どさにっき 3D 〜2011年4月中旬〜

by やまや
<< = >>

2011年4月13日(水)

mod_lua であそぼう

_ 絶賛開発中の apache 2.3 (正式版では 2.4) では mod_lua なんてモジュールが含まれてるですよ。ということで遊んでみる。コンパイルの方法とかそういうのは略。

_ キホンの hello world。デフォでは handle() という関数が呼ばれる。

-- httpd.conf
AddHandler lua-script .lua

-- hello.lua
function handle(r)
    r.content_type = "text/plain"
    r:write "hello, world\n"
end
で、http://localhost/hello.lua にアクセスすると、hello world が表示される。注意すべきは、通常の CGI などとは異なり標準出力を使わないということ。このスクリプトにおける r は apache の request_rec 構造体を lua の userdata 型にマッピングしたもの。apache と lua のやりとりはすべてこれを通じておこなうことになる。

_ で、lua のスクリプトにはクライアントの IP アドレスなどは渡されない。これ重要。ホンモノの request_rec 構造体と同じであれば r.connection を参照すればいろいろ入ってるはずだけど、実際には nil が見えるだけ。CGI なんかだと $REMOTE_ADDR などの環境変数にエクスポートされているものを参照できるけど、それもない。よって、そういう情報に基づいて挙動を変えるような処理は書けない。使えねー。

_ mod_lua では特定の URL にアクセスされたときにスクリプトを発動する(ハンドラ)だけではなく、apache の処理中に呼ばれるコールバック関数(フック)も書ける。つーか、こっちが主。他の mod_xxx でやってるような処理のほとんどを lua で再実装できるということ。

_ mod_rewrite でやってるような URL の書き換えをおこなう例。

-- httpd.conf
LuaHookTranslateName /path/to/rewrite.lua rewrite_hook

-- rewrite.lua
rewrite_url = { ["/foo"] = "/bar", ["/hoge/fuga"] = "/piyo" }
redirect_url = { ["/aaa"] = "http://localhost/" }

function rewrite_hook(r)
    for k, v in pairs(rewrite_url) do
        if r.uri == k then
            r.uri = v
            return apache2.DECLINED
        end
    end
    for k, v in pairs(redirect_url) do
        if r.uri == k then
            r.headers_out["Location"] = v
            return apache2.HTTP_MOVED_TEMPORARILY
        end
    end
    return apache2.DECLINED
end
この例では完全一致した場合しか書き換えはされないけど、パターンマッチさせるように書くことももちろんできる。

_ 1/2 の確率でアクセス拒否なんてアホな制限をおこなう例。

-- httpd.conf
<LuaHookAccessChecker deny_random>
function deny_random(r)
    if math.random() < 0.5 then
        r:debug "access granted"
        return apache2.OK
    else
        r:debug "access denied"
        return 403
    end
end
</LuaHookAccessChecker>
こんなふうに httpd.conf の中に lua スクリプトを生で書くこともできちゃうですよ。

_ かなり手抜きな embedded lua。 cgiluaに含まれる lp.lua が必要。

-- httpd.conf
LuaMapHandler \.lp$ /path/to/lp_handler.lua lp_handler

-- lp_handler.lua
require "lp"

function lp_handler(r)
    local f
    puts = function(s)
        r:write(s)
    end
    lp.setoutfunc "puts"

    if r.uri:sub(1,2) == "/~" then
        f = r.uri:gsub("/~([^/]+)/(.*)", "/home/%1/public_html/%2")
    else
        f = r.document_root .. r.uri
    end
    r:debug("lp include file: " .. f)
    r.content_type = "text/html"
    lp.include(f)
end
↑こんな設定がある状態で、
<html>
<body>
<?lua
  now = os.date()
  puts "hello, world"
?>
<br>
date: <%= now %>
</body>
</html>
↑こんな感じの lua スクリプトを埋め込んだ HTML を hoge.lp という名前で置いておくと、アクセス時にスクリプト部分がその実行結果で置換される。いちおう念のため書いておくと、べつに mod_lua じゃなきゃできないわけではなく cgilua でふつーにできる。

_ 実は2年ぐらい前にも mod_lua をちょいとさわってみたことがあったりする。が、そのときからできることはあんまり変わってない印象。request_rec だけじゃなくて server_rec とか conn_rec とかもいじれるようになってるかと期待したんだけど、そうなってなくてがっかり。とはいえ、以前はかなり不安定だったのがまともに動くようになってるのでだいぶ進化してるとはいえる。スクリプトをキャッシュさせない設定にしてあるのにキャッシュしてしまって、コードの修正がちっとも反映されないとか以前はふつーにあったので。

_ ほかのスクリプト言語(?)としては、mod_sed なんてのもある模様。


2011年4月14日(木)

mod_sed であそぼう

_ mod_lua と違って、こちらは単純なフィルタですな。

<Files hoge.html>
    SetOutputFilter Sed
    OutputSed "s;</body>;<hr>hello world</body>;"
</Files>
コンテンツに定型文を挿入したりするのに使うと便利、ってなところかな。この例だと、HTML の末尾に hello world が差し込まれる。

_ ソースを見ると燦然と輝く Sun Microsystems の文字。Solaris から持ってきた sed みたい。正規表現も mod_sed では apache が通常使う PCRE ではなく solaris のものが使われるようだ。


2011年4月17日(日)

東北花見

_ 花見してきた。自粛なんかしない。震災なんぞ知ったことかと花は変わらず咲くのだから、こちらも変わらず桜を愛でればいい。

_ 日本三大桜のひとつらしい滝桜(福島県三春町)。 4/10 頃開花との予想だったので、それに合わせて今週末に見物に行く計画を立てたわけなんだが、実際に開花したのは 4/15だよがっかりだよ。というわけで、開花翌日のきのう訪れたわけだが、うーん、やっぱり花が少ないのがもったいない。枝ぶりも見事な巨木だし、これが満開ならほんとに凄い風景になるんだろう。
滝桜
三春町にはほかにも立派な桜の木がいくつもあるようで、それらもいくつか見てまわるつもりだったんだけど、どれもやっぱり満開にはほど遠いようなのでパス。ソメイヨシノならばこのあたりでも満開の時期なんだけど、そうではなくベニシダレザクラなので花期が遅いようだ。ちなみに福島第一原発から 45km。

_ 続いて福島市内にある花見山。山いっぱいにいろんな種類の木が咲きほこってるけど、本来は園芸業者が栽培してる商品。売り物なのにタダで公開してくれてありがたいことです。桜だけでも何種類もあるし、桜以外にもいろんな花がある。このときはレンギョウの黄色の鮮やかさが目をひいていた。ただ惜しむらくは、天気が。午前中はよく晴れてたのに、ここに到着したころには雲が出てかなり強い風も吹いて、かなり残念なことに。
花見山
花見山

_ 夜は飯坂温泉の旅館へ。車中泊ではなく宿に泊まるのって、出張以外では何年ぶりだろう。少なくとも5年以内に記憶はない:-)。宿を予約してしまったがために、滝桜が満開にほど遠いとわかっていながら来ざるをえなかったという。そういうのを避けるためにもやっぱり車中泊のほうがいいよ。

_ 翌日。白石川の河畔に咲く一目千本桜(宮城県大河原町、柴田町)と、そのすぐそばの船岡城址公園。いや、もう、すばらしい。いまだ雪に覆われた蔵王の山々を背後に桜並木が延々と続く。雲ひとつない青空で言うことなし。景色だけでなく、お花見してる人たちのマナーもすばらしい。だらしなく酔っ払ってる人がまったくいないし、地元住民がふだん使うゴミ集積場に捨てられる花見客のゴミがほぼゼロ。どういうこと?
一目千本桜
一目千本桜
震災にめげず東北本線も運行を再開した。
一目千本桜

_ というわけで、震災1ヶ月後の東北にあえて突撃してきた。いずれも内陸で、地震の影響はいくらか見られるけど、津波とは無縁の地域。そして、予定されていたイベントがすべて中止になっているという共通点もある。でも、イベントなんかなくたって花は咲く。花が咲けば人は集まる。震災直後だけど、みんな楽しそうに笑ってた。

_ もうすぐ GW だけど、海沿いの被災地を野次馬しにいくのでなければ、気にせずどんどん東北に遊びに行っていいと思う。しなくていい遠慮をしてまうと、観光収入が減ってしまう。それで生計を立ててる人には大打撃だよね。どんどん出かけてどんどんお金を落としていくべき(今回珍しく宿に泊まったのもそれが理由)。電車も、高速道路も、飛行機も、完全復旧ではないにしろ、みんな再開している。ガソリンもふつーに入手できる。コンビニは一部商品が品薄で、それは東京も同じ。震災で東北全部が壊滅したわけではない。東北をひとくくりにして避けてしまうのはよくない。内陸部、日本海側は以前の生活を取り戻しつつあるんだから、こういうところに出かけていってお土産を買ってくるのも支援のひとつの形だと思う。


<< = >>
やまや