クエリ文字列を渡す際のApache mod_rewriteの動作に関する奇妙な問題(おそらくバグ?)に遭遇しました。
再現するために、デフォルトのApache構成でクリーンなUbuntu(oneiric)インストールをセットアップしました。mod_rewriteを有効にし、デフォルトのサイト構成で次を追加しました。
RewriteEngine on
RewriteRule ^/(.*)$ /r/$1 [R]
テストするには、curlを使用します。
curl -I 'http://[ubuntu-machine]/a/b%20c?a%20b'
関連する出力は次のとおりです。
HTTP/1.1 302 Found
Server: Apache/2.2.20 (Ubuntu)
Location: http://[ubuntu-machine]/r/a/b%20c?a%2520b
ご覧のとおり、クエリ文字列は二重エスケープされていますが、これは間違っています。これを修正する方法はありますか?私たちが試したいくつかのこと:
- [NE]を追加します。これにより正しいクエリ文字列が得られますが、パスはエスケープされず、新しい問題につながります。
- [NE、B]を追加します。これは機能しているように見えますが、パスのとの
/
間の部分がエスケープされます。a
b
クエリ文字列を手動でエスケープ解除します。
RewriteCond %{QUERY_STRING} .* RewriteMap unescape int:unescape RewriteRule ^(.*)$ $1?${unescape:%{QUERY_STRING}}
ただし、これは、たとえば、クエリ文字列で
&
エスケープさ&
れたan とエスケープされた文字を区別できないことを意味します。
更新:
このバグレポートでは、同じ問題について説明しています。最初のコメントは明らかに問題を修正するコミットにリンクしていますが、Pieterが以下で述べているように、実際に修正されているようには見えません。