Practice of Programming

プログラム とか Linuxとかの話題

PATH_INFO中の%2Fがデコードされる

そもそも、デコードされているっていうのは、あんまり意識してなかったですが...
今回、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にされているらしい。へー。