なんかここの所 Wiki ネタばっかりなので、役に立ちそうで立つのか分からないネタ。
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 使うのやめるぐらいしか選択肢がないように思います。
まとめ
この問題を回避する選択肢としては、
ぐらいでしょうか。1 か 2 が妥当でしょう。3 はネタなので気にしない。いや本当に投げ捨ててもいいと思いますが。問題ないのならば。
2 に関しては lighttpd という最近はやり?のやつがあるので、そっちを試してみるのもいいかもしれません。試したこと無いので問題起こるかどうか知りませんが。
おまけ
自作 Wiki の公開のためのサイトですが全然できてません。記法作るのに時間がかかってるよ。今月中には公開したい。