ありゃ。本当にイチハラヒロコだったらしい。
あげられている書籍の 「この人ゴミを押しわけて、はやく来やがれ、王子さま。」 はかなり面白いので、興味のある人は是非。
mod_ruby の真価は ruby script が早く動くことではなく apache の挙動を ruby で制御できることだ。 ……というわけで今まで mod_rewrite でやっていた URL 書き換えを mod_ruby のハンドラでやってみることにした。
と、思い立ったのは良いんだけど オフィシャル 見てもドキュメントが全然無い。 仕方ないのでソースと mod_perl のサイトを読む。 URL Translation phase でコードを実行するには RurbyTransHandler ディレクティブに translate_uri メソッドを持つオブジェクトを 指定すれば良いみたい。
自分で調べた部分は Wiki に勝手に追加しといた。
わざわざ singleton を使わなくてもclass のオブジェクトを そのまま渡せばいいや、と言うことでこんな風に。
class SugiTDiaryRewriter BASE_URL = "/diary/" # must end with / def self.translate_uri(r) if r.uri !~ /^#{BASE_URL}/ return Apache::DECLINED elsif r.uri =~ %r[^#{BASE_URL}(\d{6,})(-\d+)?.html?$] new_uri = "#{BASE_URL}?date=#{$1}#{$2}" elsif r.unparsed_uri =~ %r[^#{BASE_URL}(?:index\.cgi)?\?(?:.*&to=)?(\d{6,})] # HNS style new_uri = "#{BASE_URL}?date=#{$1}" end if new_uri r.internal_redirect(new_uri) return Apache::DONE end return Apache::DECLINED end end
このコードを呼ぶために httpd.conf の VirtualHost 内 に以下を追加すればOK。
RubyRequire /etc/apache2/vhosts/sugi/tdiary-rewrite.rb RubyTransHandler SugiTDiaryRewriter
SugiTDiaryRewriter と言う定数はクラスそのものなので、 クラスメソッドの translate_uri が正しく呼ばれます。
うう。後で気づいたけど、英語の方にはちゃんとあった ……。ソースの doc ディレクトリに入ってるのもこれか。
とりあえず debian package にこのドキュメント入れて欲しい と言うのをBTSに出しておく。
もう一つついでにメモ。
上の話は内部リダイレクトを使っているけど、例えば Alias ディレクティブの様にファイルシステムへの マッピングを書きたい時もある。例えば以下のように。
Alias /diary /home/sugi/www/sugi/tdiary
このAliasと同じ事をするには、r.filename に代入してやればいい。 この辺は mod_perl と同じなので、 perl のドキュメント当たった方が早そうですね。
class MyAlias def self.translate_uri(r) if r.uri =~ %r[^/diary(.*)] r.filename = "/home/sugi/www/sugi/tdiary#{$1}" return Apache::OK end return Apache::DECLINED end end