毎秒1000リクエスト を捌く超高速CMS「adiary」
2006/04/21(金)multipart/form-data
日記への画像添付に向けて、multipart/form-data の解析ルーチンでも作ろうかと思って調べ始めてみると……
- とりあえずネットで仕様書を検索。RFC1876, RFC2388だということは分かるが……見ても分かりにくいぞ、これは。
- 仕方ないので perl で書かれたサンプル(アップローダ)でも探してみると、CGI.pm を使用したものばかり見つかる。
- しょうがないので、ENCTYPE="multipart/form-data" なフォームで POST してデータを全部ファイルにはき出してみる。実に分かりやすい。
- 結局 boundary を認識しつつ読み出す必要があるので、perl 的にデリミタを書き換えてと思ったものの、例えば 100MB とか大きなファイルを受け取るとき、それだけメモリを食うこととなる。 → 常識的にはNG
- なんかいい方法ないかなぁーと再びネット内のcgiスクリプトを検索。…………見るんじゃなかった(笑)
どうしてネットに転がってる cgi (with perl) スクリプトってのは、有名どころ含め、汚いのばかりかなぁ(苦笑)*1
multipart/form-dataの例
というわけで例をアップしておきます。参考にどうぞ。アップロードしたファイルは、C++のソースです。
2006/04/15(土)mod_perl で chdir
mod_perl2 (on Apache 2.x)で無理矢理MT(Movable Type)を動かそうとしたり、古いスクリプトをmod_perl2で動かそうとする人たちがいまして。そういうページの中で、mod_perl2はカレントディレクトリをスクリプトのdirに変更しないというのが日本ではなぜか迷信のごとく広まっています。……いやある意味では正しいのですけど。例えばこちらのページでは
PerlFixupHandler "sub { \ chdir('/project/sfo/www/www.sfo.jp/lib/mt'); \ return OK; \ }" PerlResponseHandler ModPerl::Registry
とやって明示的に chdir しています(別にやり玉に挙げているわけではなくて、どこのサイトを見てもおよそこんな感じです)。そもそもなぜ、ModPerl::Registry がスクリプトの場所にカレントディレクトリを変更しないかといえば、worker モデルの場合(Apacheがスレッド動作モデル)の場合、chdir しても途中でカレントディレクトリが変わる可能性がある=あまり意味がないからです。だから chdir を明示的に発行するときは、Apache が prefork(従来のプロセスをforkして並列動作する方式)で動いてることを期待しています。
ここからが本題。mod_perl2のマニュアルによるとmod_perl2にはPrefork専用のハンドラーがあり、
PerlResponseHandler ModPerl::RegistryPrefork PerlResponseHandler ModPerl::PerlRunPrefork
と(どちらか一つを)書けば chdir してくれるそうです。まあ英語のマニュアルだから自分もcgi開発でもなければ読まなかったのですが、日本での普及率をGoogle先生に聞いてみるとこんな結果になります(汗)
というわけで、以降普及することを期待して終わり(笑)