WindowsでApache使ってサーバ立てるのはオススメできないという話。
なんでもShift_JIS
仕様なのかバグなのか分かりませんが、Win32なApacheではPATH_INFO等がShift_JISに強制変換されるみたいです。
WindowsXP + Apache1.3.34 で確認しました。というかまあ僕の開発環境なんですが、他の環境でもそうなるかと思います。
Apache PATH_INFO 文字化けなんかで検索すると同じようなエントリが出てきます。
具体的にはどういうことかと言うと、CGIのPATH_INFOに日本語(マルチバイト?)な文字列を、
URIエスケープして渡すと、なぜかShift_JISに変換されます。
なので場合によっては文字化けしてPATH_INFOが使い物にならなくなります。
ちなみにこれはmod_rewriteを使ったURI書き換えでも起こります。
僕が遭遇したのはmod_rewriteで化けたほうが先で、PATH_INFOがおかしくなるのに気づいたのはWiki書き始めた時です。
まあ、遭遇した順番はどうでもいいですが、このままだとPATH_INFOが使えないので解決策を考えてみます。
環境変数 REQUEST_URI , SCRIPT_NAME を使う
REQUEST_URIとSCRIPT_NAMEを使えば意外と簡単にできます。
というわけで例。コードはPerlです。
my ($request_uri,$script_name) =
( $ENV{'REQUEST_URI'} , $ENV{'SCRIPT_NAME'});
my $path_info = $request_uri;
$path_info =~ s!^$script_name!!;
$path_info =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
こんな感じです。これでばっちり……と言いたい所ですが問題があったりします。 このコードそのまま使うとmod_rewriteなんかでURI書き換えた時動かねぇという事態に陥ります。
簡単なURIの書き換え、例えばCGIファイル名を隠すというリライトなら
my ($request_uri,$script_name,$script_filename) =
( $ENV{'REQUEST_URI'} , $ENV{'SCRIPT_NAME'} , $ENV{'SCRIPT_FILENAME'});
my @tmp_filename = split m{/},$script_filename;
my $filename = pop @tmp_filename;
my $path_info = $request_uri;
if ($path_info !~ m/$filename$/){
$script_name =~ s!/$filename$!!;
}
$path_info =~ s!^$script_name!!;
$path_info =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
こんな感じのコードで対応できると思います。ただこれ以外のリライトになると、 どう対応していいのか分かりません。解決策ねぇって言う状態です。 Win32でApache使うのやめるぐらいしか選択肢がないように思います。
まとめ
この問題を回避する選択肢としては、
PATH_INFOに日本語突っ込むのをやめる- WindowsでApache使うのやめる
- Windowsを窓から投げ捨てろ
ぐらいでしょうか。1か2が妥当でしょう。3はネタなので気にしない。 いや本当に投げ捨ててもいいと思いますが。問題ないのならば。
2に関してはlighttpdという最近はやり?のやつがあるので、 そっちを試してみるのもいいかもしれません。試したこと無いので問題起こるかどうか知りませんが。
おまけ
自作Wikiの公開のためのサイトですが全然できてません。 記法作るのに時間がかかってるよ。今月中には公開したい。