CGIじゃないけど.cgiで動かす

実装はPHPなんだけどPHPだと知られたくないらしく、/cgi-bin/foo/bar.cgiと/cgi-bin/foo/baz.phpで動かしたいとの要求があった。
とりあえず一行目にshebang*1を追加してアクセスしてみたらInternal Server Errorで撃沈。
ApacheのエラーログにPHPが何やらぐだぐだと書き込んでるんだけどよくわからん。


で、CGIだとパフォーマンスも悪いし普通にモジュールで動かせばいいんじゃないの? と思ったのだが、ScriptAliasの管理下だとハンドラが強制的にcgi-scriptで固定されるらしくPHPで処理してもらえない。
RemoveHandlerとかForceTypeを駆使してもダメだった。


ちなみに/cgi-bin/をScriptAliasにしないという案は残念ながら採用できなかった。
なぜなら既にPerl製のCGIプログラムが稼動しているから。


結局、あれこれ試行錯誤して辿り着いた解決案は次の通りとなった。

# /cgi-bin/foo/ 以外の /cgi-bin/ を CGI 扱い
#ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
ScriptAliasMatch ^/cgi-bin/(?!foo/)(.*) "/var/www/cgi-bin/$1"

# /cgi-bin/foo/ は普通に PHP が動く設定にする
Alias /cgi-bin/foo/ "/var/www/cgi-bin/foo/"
<Directory "/var/www/cgi-bin/foo">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all

    # PHP(.cgiも)
    AddType application/x-httpd-php .php .cgi
</Directory>

この設定で以下の動作が実現可能。

/cgi-bin/foo.cgi     ……従来通りCGIとして動作
/cgi-bin/foo/bar.php ……PHPモジュールとして動作
/cgi-bin/foo/baz.cgi ……PHPモジュールとして動作

要するに正規表現でもって/cgi-bin/foo/はScriptAliasの管理外にしているだけ。
ApacheはPCREだからよかったものの、look-aheadがなかったらダメだったかもしれない。


しかし今ブログにまとめていて思ったが、rewriteとかproxyとかでもよかったんだろうか。
つか、実装を知られたくないとか言うぐらいなら、実装依存URIは撤廃して/foo/barとかにした方がいいんじゃないのか。

*1:#!/usr/bin/〜ってやつ