2021/02/11(木)実はCGIってCLIアプリなのでは?と思ったので試してみた
投稿日:
ふとした気づき
今時CGIなんて言わない?知らない?そんなこたぁいいんですよ。
ふと思ったんですよ、CGIとCLIアプリって本質的に同じものなんじゃないかなって。
だってPHPってこんなふうに書いてブラウザでアクセスしたらいろはにほへとって出るじゃないですか?
そしてこれをphp index.phpみたいにして叩いてもいろはにほへとって出ますよね?
<?php
echo 'いろはにほへと';
そう、気付いてしまったのです。
実はCGIって本質的にはCLIアプリなのではないかと…。
むしろ何が違うんでしょう?
仕組みを調べてみることに
気になったのでどういう仕組で動いてるのか軽く調べるために、敢えてC言語でCGIを作ってみることに。
今までC言語でCGIとか狂人のやることって印象があったのですが、意外とやってみると大したことはないというか、まぁ大したものを作ってないから当たり前なんですが…。
これが何をしているかというと、環境変数を取ってきて標準出力に吐いてるだけなので、どっからどう見てもCLIアプリです。
#include <stdio.h>
// getenv
#include <stdlib.h>
// strcmp
#include <string.h>
/*
get path for after hostname
*/
char* getPath(void) {
char *path = getenv("REQUEST_URI");
return path;
}
int main(void) {
// put http header
printf("Content-type: text/plain\n\n");
char *path = getPath();
// show current path
printf("Current path: %s\n", path);
// routing, required .htaccess to serve on apache
if (strcmp(path, "/foo") == 0) {
printf("hoge");
} else if (strcmp(path, "/bar") == 0) {
printf("piyo");
} else {
printf("fuga");
}
return 0;
}
実際に動かしてみたところ
CGIとして
CLI として
辿り着いた結論
恐らくこれは動作環境が重要なのであって、多分CGIとCLIアプリの作りとしては大きな違いはないのではないか?というのが辿り着いた結論です。
いやまぁ引数をargvから取るか環境変数から取るかは結構違う気もしますが、基本的に表示したいものを標準出力に吐く点は同じですし、別にCGIでTCPソケットを触るわけでもないので、同じようなものでは?と思った次第。
これは多分、 HTTPサーバーを通すことで標準出力がHTTPレスポンスに出力され、 Xサーバーを通すなら画面に、プリンタサーバーを通せば紙にといった具合に、どこのサーバーを通して標準出力をするかで出てくるところが変わるのでは?と感じました。(細かいことを言うともっと複雑らしい)
多分ApacheとかのHTTPサーバーはTCPソケットをいい感じにやってくれて、 HTTPヘッダを環境変数に入れてCGIスクリプトを起動といったところをしてくれているのではないかと思ったので、暇な時にTCP通信から始めるHTTPサーバーの実装でもやってみたいところですね…。
おまけ
取り敢えずPHPのCGIをCLIとして動かせるやつです。
<?php
echo $_SERVER['REQUEST_URI'];
2019/12/25(水)GitHubにGPGで署名コミットする
投稿日:
確認環境
Windows
あらかじめgpgのパスをPATHに通しておくと良い
参考値:C:\Program Files (x86)\GnuPG\bin
| Env | Ver |
|---|---|
| Windows 10 Pro | Build 19042.804 |
| git | 2.30.0.windows.1 |
| VSCode | 1.53.2 |
| Kleopatra | Gpg4win-3.1.15 |
Ubuntu
Windows側からVSCodeのRemote - SSHで接続
| Env | Ver |
|---|---|
| Ubuntu Desktop | 20.04.2 |
| git | 2.25.1 |
| gpg | 2.2.19 |
手順
Windows
- Kleopatoraを起動
- ファイル> New Pair Key
- 個人用のOpenPGP鍵ペアを生成
- 期限なし、パスフレーズは適当に
- Exportから
-----BEGIN PGP PUBLIC KEY BLOCK-----の中身を全部GitHubのGPG keys/ Add newに貼り付ける - 追加後にでてきた
Key IDをgit config --global user.signingkey KeyIDとしてcmdに流す - 以下を流す(
gpg.programはなくても動くが、あったほうが問題が起きない)git config --global commit.gpgsign true git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe" - 管理者権限で
cmdを起動し次のシンボリックリンクを作成mklink /D %USERPROFILE%.gnupg %AppData%\GnuPG
- VSCodeで適当なリポジトリを作成
- なんか適当にコミットする
- GitHubに投げる
- GitHubのコミット履歴にverified signatureがついてたら成功
Ubuntu
- Windows側のKleopatoraから公開鍵と秘密鍵をエクスポートして持ってくる
gpg --import FooBarpublic.ascで公開鍵をインポートgpg -kでインポートされていることを確認し、下記XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX相当の部分をコピペpub rsa3072 2021-01-17 [SC] XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX uid [ 不明 ] Foo Bar <foobar@example.com> sub rsa3072 2021-01-17 [E]gpg --edit-key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXtrust5を選ぶquitgpg -kで信用度が[ 究極 ]になっていることを確認gpg --import FooBarSECRET.ascで秘密鍵をインポート- SSHで繋いでいる時でタイムアウトする場合、GUIプロンプトからの入力になっている可能性があるので、どうにかして入力
- XRDP経由なら
pkill gnome-sessionを叩くと入れる
- Windowsの時と同様に次のコマンドを流す
git config --global user.signingkey KeyIDgit config --global commit.gpgsign true
- VSCodeで適当なリポジトリを作成
- 何か適当にコミットする
- コミットがコケたらXRDPから入力する
- GitHubに投げる
- GitHubのコミット履歴にverified signatureがついてたら成功
Ubuntu側でGPGキーを作る場合
以下のコマンドを叩くとウィザードが出るのでそれに沿ってやればよい。
gpg --full-generate-key
CLIからやる場合でパスフレーズを何度も打ちたくないケース
以下の手順が参考になる
トラブルシュート
Key IDを確認したい
以下のコマンドで確認可能
gpg --list-signatures
GPGキーを消したい
Inappropriate ioctl for deviceとか出る
.zshrcにexport GPG_TTY=$(tty)を追記すると解消する。
GPGキーのパスフレーズを記憶させたい
毎回聞かれるのが鬱陶しい場合に記憶させる場合の手順。
Windows
%USERPROFILE%/AppData/Roaming/gnupgのシンボリックリンクを%USERPROFILE%/.gnupgに作成gpg-agent.confに以下を追記するdefault-cache-ttl 34560000 max-cache-ttl 34560000
Ubuntu
cat <<'EOF' | tee ~/.gnupg/gpg-agent.conf
###+++--- GPGConf ---+++###
default-cache-ttl 34560000
max-cache-ttl 34560000
EOF