URLエスケープされた文字列にスラッシュが含まれている場合
URLエスケープとは簡単に言うと、wikipediaのページのURLに含まれている文字列で、「%」なんちゃらというやつである。URLエンコードと呼ばれているときもあって、実際どちらが正しいのかわからん。
で、そのURLエスケープの意図としては以下のとおり。
フォームから問い合わせ文字列を受け取ったり、クッキーを発行するとき、 HTTPプロトコルとCGIが適正に処理できるデータ形式に変更する必要があります。
http://www.kinet.or.jp/hiromin/cgi_introduction/appendix/url_encode.html
ということで、サーバへ文字列を送信する場合にはURLエスケープして送信し、受信側で復元する処理をするのが通常。perlでは、CGI.pmを通せば自動的にアンエスケープ処理をしてくれるので特に意識することはなかったりする。
だが、Apacheの設定によっては、たとえ適切にURLエスケープしていても駄目なときがある。
それがこの「スラッシュが含まれている場合」である。
例えば、はてなブックマークの「これはすごい」タグのURL。
http://b.hatena.ne.jp/t/%E3%81%93%E3%82%8C%E3%81%AF%E3%81%99%E3%81%94%E3%81%84
全く問題なく見れる。
では、これではどうか「これは/すごい」
http://b.hatena.ne.jp/t/%E3%81%93%E3%82%8C%E3%81%AF/%E3%81%99%E3%81%94%E3%81%84
エントリが存在しないが、タグ「これは/すごい」が認識されているという点では正常に見える。
では、これはどうか。「これは%2fすごい」
http://b.hatena.ne.jp/t/%E3%81%93%E3%82%8C%E3%81%AF%2f%E3%81%99%E3%81%94%E3%81%84
「Not Found」と文字化けした文字列が表示されたハズ。これ。これが問題。
この問題はApacheの仕様のようで、設定を変更することで対応できるようだ。
apacheの設定がデフォルト状態だと404エラーになります。
これを解消するにはAllowEncodedSlashesをOnにします。
http://kawama.jp/archives/2007/04/path_info2f404a.html
とあり、Apacheのドキュメントにも
AllowEncodedSlashes ディレクティブは符号化された パス分離文字 (/ は %2F、さらにシステムによっては \ に対応する %5C) が存在する URL の使用を 許可するかどうかを決定します。通常はそのような URL は 404 (Not found) エラー で拒否されます。
(↑文字化けしちゃってるけどw)
ということで、この設定を行えば問題なくURLエスケープされた文字列を受信側で受けとれるハズ。そして、Apacheのドキュメントにあるように環境変数PATH_INFOを使用して使うとめちゃ便利に使えますね。
さぁみんなPATH_INFO使ってRESTしよう!!!!
となるハズなんだけど、ちょっと古いApacheではPATH_INFOのURLエスケープされた文字列がアンエスケープされてしまって使いものにならないバグがあり、しかたなしにREQUEST_URIを使用するハメになってしまう。
最新版のApacheでは修正されているようだ。
35256 – %2F will be decoded in PATH_INFO (Documentation to AllowEncodedSlashes says no decoding will be done)
ということで、RESTしたかったら、
- AllowEncodedSlashesをOnにすること
- PATH_INFOのバグが治っているバージョンかどうか確認すること
- バグがあるならREQUEST_URIを使ってなんとかすること
という点を確認しておくべき。
とはいえ、AllowEndcodedSlashesがOffの場合、サーバ設定ファイルやVirtualHost設定が弄れる環境でないとどうしようもないけれども、、、