Apache mod_rewrite在redirect时对查询string进行双重编码

在传递查询string时,我们遇到了一个奇怪的问题(可能是一个bug),Apache mod_rewrite的行为。

为了重现,我们使用默认的Apacheconfiguration设置了一个干净的Ubuntu(oneiric)安装。 我们启用了mod_rewrite,在默认的站点configuration中,我们添加了以下内容:

RewriteEngine on RewriteRule ^/(.*)$ /r/$1 [R] 

为了testing,我们使用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 

正如你所看到的,查询string是双重转义的,这是错误的。 有谁知道我们如何解决这个问题? 我们已经尝试了几件事情:

  • 添加[NE]。 这给了我们正确的查询string,但是path没有转义,这导致了新的问题。
  • 添加[NE,B]。 这似乎工作,但是导致path的ab部分之间的/将被转义。
  • 手动翻阅查询string。

     RewriteCond %{QUERY_STRING} .* RewriteMap unescape int:unescape RewriteRule ^(.*)$ $1?${unescape:%{QUERY_STRING}} 

    但是,这意味着我们无法区分查询string中的&和转义的&

更新:

这个错误报告描述了同样的问题。 第一条评论链接到一个明显解决问题的提交,但是正如Pieter在下面所说的那样,似乎并没有真正修复这个问题。

    这似乎是Apache中的一个错误。 这个错误报告有点乱,但完全描述你的问题:

    https://issues.apache.org/bugzilla/show_bug.cgi?id=34602

    看起来他们知道这个问题。 虽然错误声称他们已经修复,但我已经用Apache 2.3.15testing过了,问题似乎仍然存在。 另外请注意,Apache 2.3是一个testing版本,所以即使它修复了它也是没有用的,直到Apache 2.4不存在为止。