思い出したようにCGIってどんな仕組みだっけ?と学び直そうと調べたのですが、
shebangを読み込んでプログラムが実行され標準出力がクライアントに送信される簡単な仕組みだったのですね。
サーバー設定
dockerでapacheを起動します。
httpdの公式dockerイメージではCGIが有効になっていないので、httpd.confを編集しながら起動します。
$ docker run -it -p 80:80 -v $PWD:/usr/local/apache2/cgi-bin httpd sh -c 'sed -ri "/cgid_module|cgi-script/s/#(.*)/\1/" /usr/local/apache2/conf/httpd.conf && httpd-foreground'
Hello,World!
shebangには1つだけオプションが渡せるので、CGI の Hello,World! は以下のように書くことができます
#!/bin/sed 1d
Content-type: text/plain; charset=utf-8
Hello,World!
#!/usr/bin/tail -n+2
Content-type: text/plain; charset=utf-8
Hello,World!
プロキシサーバー
プロキシサーバーも2行で十分ですね。……これはプロキシサーバーなのでしょうか?
とりあえず http://localhost/cgi-bin/proxy.cgi?http://www.google.com/
のようにアクセスするとCGI経由でコンテンツを取得できます。
#!/bin/bash
curl -sSi "$1" | sed -r '1d;/^Transfer-Encoding/d'
httpdの公式dockerイメージではcurlが入っていないのでcurlをインストールする必要があります。
$ docker exec -it YOUR_CONTAINER_ID sh -c 'apt-get update && apt-get install curl -y'
改めてPerlのCGIでHello,World!
shebangが重要になるのであれば プログラム言語のCGIでは
/usr/bin/env
で始めるべきで、PerlのHello,World!は下記になるのでしょうか?
#!/usr/bin/env perl
print <<EOS
Content-type: text/plain; charset=utf-8
Hello,World!
EOS
調べてみるとやはり、#!/usr/bin/env perl
でなく #!/usr/bin/perl
だとハマることもあるみたいです。
しかしPerl, Python 及び Ruby スクリプトにおける正しいshebangの書き方 によると、
#!/usr/bin/env perl
では駄目らしく、Perlでの正しいshebangは7行くらいある下記が正しいようです。
#! /bin/sh
eval '(exit $?0)' && eval 'PERL_BADLANG=x;PATH="$PATH:.";export PERL_BADLANG\
;exec perl -x -S -- "$0" ${1+"$@"};#'if 0;eval 'setenv PERL_BADLANG x\
;setenv PATH "$PATH":.;exec perl -x -S -- "$0" $argv:q;#'.q
#!perl -w
+push@INC,'.';$0=~/(.*)/s;do(index($1,"/")<0?"./$1":$1);die$@if$@__END__+if 0
;#Don't touch/remove lines 1--7: http://www.inf.bme.hu/~pts/Magic.Perl.Header
print <<EOS
Content-type: text/plain; charset=utf-8
Hello,World!
EOS
……私にはまだPerlでCGIを書くのは早かったみたいです。
かつて学生だった頃に意味を理解せずにPerlでCGIを書いていた記憶がありますが、
標準入出力さえアレばどんなプログラムでもよかったのですね。
また、dockerを使えばワンライナーでサーバーを立ち上げられる時代になったのは嬉しいですね。
今後CGIで書くことは無いと思うので、特に意味はない気がしますが……
参考
シバン (Unix)
開眼☆シェルスクリプト CGIスクリプトを作る(1)―Webサーバへのデータは標準出力で渡す
シェルスクリプトでCGI