Apache:如何对双编码的传入URL进行双重解码

时间:2014-10-29 16:26:16

标签: apache mod-rewrite url-rewriting apache2 urldecode

我在使用Passenger / Apache运行的Rails应用程序时遇到问题,Googlebot正在尝试访问查询字符串参数已经过双重编码的URL。 (我不知道Googlebot从哪里获取这些网址 - 他们不在我应用的任何地方的任何链接中。)

这导致我的日志中出现了很多额外错误,因此很难诊断出真正的"因为Googlebot试图访问的网址导致错误导致问题被隐藏起来。

以下是我的Apache访问日志中的一个示例:

  

66.249.67.103 - - [27 / Oct / 2014:07:44:32 -0400]" GET / catalog?f%255Bfacet_field_1%255D%255B%255D = foo& f%255Bfacet_field_2%255D%255B %255D =栏&安培;排序= title_info_primary_ssort + ASC%252C + date_start_dtsi + ASC   HTTP / 1.1" 200 5266" - " " Mozilla / 5.0(兼容; Googlebot / 2.1;   + http://www.google.com/bot.html)"

请注意双重编码("%255B","%255D"),这是已编码字符的编码版本("%5B", "%5D&#34)。因此,而不是我的Rails应用程序接收这些参数:

{
  "f[facet_field_1][]" => "foo",
  "f[facet_field_2][]" => "bar",
  "sort" => "title_info_primary_ssort asc, date_start_dtsi asc"
}

......收到这些:

{
  "f%5Bfacet_field_1%5D%5B%5D" => "foo",
  "f%5Bfacet_field_2%5D%5B%5D" => "bar",
  "sort"=>"title_info_primary_ssort asc%2C date_start_dtsi asc"
}

......它无法解释,导致错误日志中有大量条目。 URL被解码一次(非常确定Apache默认执行此操作),但仍然会在Rails无法处理的参数哈希中留下URL编码的字符。

我需要的是一种双重解码用户代理是Googlebot的网址的方法。似乎应该能够使用mod_rewrite来做到这一点,但我没有太多运气,因为mod_rewrite似乎不适合修改URL的查询字符串部分。它也存在问题,因为我无法预测参数的确切顺序,也无法预测URL中可能传递的参数的确切组合。

如何在将请求传递给我的应用程序之前告诉Apache对URL进行双重解码(基于用户代理)? (服务器版本:Apache / 2.4.7(Ubuntu))。阻止Googlebot是不可接受的选择。

1 个答案:

答案 0 :(得分:0)

有办法实现,但需要修改服务器的.conf文件。您需要在服务器配置中添加以下指令:

RewriteMap unescape int:unescape

之后你可以像这样使用RewriteRule:

RewriteEngine On
RewriteCond %{IS_SUBREQ} false
RewriteRule ^(.*)$ $1?${unescape:%{QUERY_STRING}} [L]

并且,正如我认为的那样,不应该针对每个请求进行,而只针对那些需要解码的请求,因此需要额外的RewriteCond。例如,您可以检查是否存在%255B%255D等等。

因此,最后一组规则将是(如果元素的值中存在双引号,而不仅仅是参数的名称,则可以触发)

RewriteEngine On
RewriteCond %{IS_SUBREQ} false
RewriteCond %{QUERY_STRING} %255(B|D)
RewriteRule ^(.*)$ $1?${unescape:%{QUERY_STRING}} [L]