そもそも、デコードされているっていうのは、あんまり意識してなかったですが...
今回、PATH_INFO中に%2Fを使う必要があって、ぶつかりました。
URL内に%2Fを含むためには、AllowEncodedSlashes on が必要です。で、ドキュメントにはこう書かれてます。
符号化されたスラッシュを許可することは、復号をすることを 意味しません。%2F や (関係するシステムでの) %5C は、他の部分が復号された URL の中でもそのままの形式で 残されます。
http://httpd.apache.org/docs/2.2/ja/mod/core.html#allowencodedslashes
のですが、PATH_INFOで受け取った値はデコードされてしまっています。
僕の使っているバージョンは、Apache/2.2.9 (Debian)ですが、結構前からのようです。
https://issues.apache.org/bugzilla/show_bug.cgi?id=43192
実際起きることは、ルートパスがプログラムで下記のようなURLの場合、
http://example.com/hoge%2Fhoge/fuga
PATH_INFOは、下記のようになる。
/hoge/hoge/fuga
"/hoge%2Fhoge/fuga"でもらいたいんだけど、取れない。
求めているものをもらうためには、下記のような処理が必要になります。
my $request_uri = $ENV{REQUEST_URI}; $request_uri =~ s{\?.+$}{}; my @args = map {$_ = CGI::unescape($_); s{/}{%2F}g; $_} split('/', $request_uri, -1); $ENV{PATH_INFO} = join("/", @args) || '/';
PATH_INFO中に%2F以外でエンコードされたものがないなら、unescapeする必要はないですが。
後は、プログラムがルートパスでなければ、その分を削除したりしないといけませんね。
REQUEST_URIとPATH_INFOでググるといろいろ出てきました。
http://www.google.co.jp/search?sourceid=chrome&ie=UTF-8&q=REQUEST_URI+PATH_INFO
(今のバージョンでもそうなのかは知らないけど)Windowsでは、PATH_INFOがsjisにされているらしい。へー。