それ mod_magnet で(出来なかった)

lighttpd-1.4.15 + FastCGI な環境で、HTTP リクエストヘッダ中の任意のレコードを参照して、その内容によって環境変数を設定しておきたい、という状況。
http://blog.tmty.jp/archives/54761462.html

mod_magnet は初めて使うわけですが。出来るんじゃないかなあ、と思ってやってみたけど出来なかった、という話。

まず、mod_magnet というのは Lua という言語を lighttpd に組み込んでリクエストハンドリングを出来るようにしたモジュールです。1.4.12 以降には標準で付いてるみたいです。
ドキュメントはこちら Docs ModMagnet - Lighttpd - lighty labs

lighttpd.conf

$HTTP["url"] =~ "printenv\.cgi$" {
  magnet.attract-physical-path-to = (server.document-root + "/setenv.lua")
}

setenv.lua

if ( lighty.request["X-Hoge"] == 'hoge' ) then
   -- ここで環境変数を設定すれば……
end
return lighty.RESTART_REQUEST

で、この if の中が書けない。

  • lighty.env は、あらかじめ決まった key しか値を設定できない
    • couldn't store 'Hoge' in lighty.env[] とか言われる
  • lighty.request は書き換えてもその後のリクエスト (CGI とか FCGI とか) に反映されない
    • ソースを眺めてみたけど、確かに request を書き戻している箇所はない
  • Lua には os.getenv() はあるけど os.setenv() はない?
    • もっとも、ここで直に環境変数を書き換えると変なことが起きそうだが

仕方ないので query にパラメータを追加してお茶を濁してみた。

if ( lighty.request["X-Hoge"] == 'hoge' ) then
   if ( lighty.env["uri.query"] == nil ) then
      lighty.env["uri.query"] = 'hoge=1'
   else
      lighty.env["uri.query"] = lighty.env["uri.query"] .. '&hoge=1'
   end
end
return lighty.RESTART_REQUEST

こうすると QUERY_STRING が書き換わった状態で CGI に渡されます。

上記の例を静的ファイルに適用した状態で ApacheBench を取ってみたらこんな感じ。

                    |  mod_magnet適用 |      非適用
--------------------+-----------------+-----------------
Requests per second | 10588.9 [#/sec] |  12440.2 [#/sec]

スクリプト動いてるのに速い!

結構面白そうです。