追記@2009-10-20: もっとちゃんとした reproxy モジュールを書きました。こちらの新しい記事を参照ください。
突然ですが、perlbal というロードバランサーをご存じでしょうか。この perlbal には reproxy という機能があります。 これは、このロードバランサー下のWebサーバーが
X-Reproxy-Url: http://example.com/
などというヘッダを返すと、perlbal がその URL の内容を取得し、コンテンツボディをその URL の内容に置き換えてくれるという物です。
MogileFS や Amazon S3 との相性のいい機能ですね。
これを lighttpd でもやりたくなったのでがんばってみました。
既存の mod_fastcgi
に reproxy 機能を組み込んだモジュールです。パッチにしてもよかったのですが、別モジュールのほうが使い勝手がいい気がしたので別名で作ってみました。
reproxy 機能以外は基本的に mod_fastcgi
として動作するため、このモジュールを使用する場合は mod_fastcgi
をロードしないようお気をつけください。
使い方は mod_fastcgi
と全く同じですが、あたらしく allow-x-reproxy
というオプションが追加されており、これを "enable"
にすることで reproxy 機能が有効になります。
実際に使える最小の lighttpd.conf
は
server.modules = (
"mod_fastcgi_reproxy",
)
server.document-root = "/home/typester/dev/lighttpd/lighttpd-1.4.21"
server.port = 80
fastcgi.server = (
"" => (
( "bin-path" => "/home/typester/dev/lighttpd/lighttpd-1.4.21/test.fcgi",
"socket" => "/tmp/fcgi.socket",
"max-procs" => 1,
"check-local" => "disable",
"allow-x-reproxy" => "enable",
),
),
)
このような感じになります。
test.fcgi
は
#!/usr/bin/env perl
use strict;
use warnings;
use CGI::Fast;
while (my $q = CGI::Fast->new) {
print "X-LIGHTTPD-reproxy-host: example.com\n";
print "X-LIGHTTPD-reproxy-path: /path/to/file.jpg\n";
print "\n";
print "Hello fcgi";
}
こんな感じとなってます。
この fcgi では "Hello fcgi"
というコンテンツを返していますが、mod_fastcgi_reproxy
によりコンテンツが置き換えられ、実際には http://example.com/path/to/file.jpg
のデータが返ります。
lighttpdには以前ご紹介した X-Sendfile
という仕組み がありますが、こちらと組み合わせると、
- S3 のデータをローカルでキャッシュしている場合には X-Sendfile でローカルのファイルを出力
- キャッシュがない場合には X-Reproxy で S3 のファイルを出力
というようなことが簡単にできるようになります。
実はこの機能は、lighttpd 1.5 では実装済み (X-Rewrite-* という名前) だったりするのですが、1.5はまったくもってリリースされないので待ちきれずにハックしてしまいました。後悔はしていません。
現在の問題としては
- fcgi で出力されたヘッダと reproxy 先で返されるヘッダのマージ処理がおかしい
- 自分自身に reproxy されると無限ループ><
などがあります。
皆様のバグレポートをお待ちしております。
ではまた!
カヤックでは apache モジュールや lighttpd モジュール、また perlbal プラグインなどをがんがん書くことが出来る技術者を募集しています!