2014-10-29 71 views
0

我遇到了在Passenger/Apache下運行的Rails應用程序的問題,其中Googlebot試圖訪問查詢字符串參數已被雙重編碼的URL。 (我不知道Googlebot從哪裏獲取這些網址 - 它們不在我應用的任何位置)。Apache:如何對雙重編碼的傳入URL進行雙重解碼

這會導致我的日誌中出現很多額外的錯誤,這使得診斷非常困難「真正」問題,因爲它們被Googlebot嘗試訪問的網址所導致的錯誤所掩蓋。

下面是從我的Apache訪問日誌的示例:

66.249.67.103 - - [27月/ 10月/ 2014:07:44:32 -0400]?「GET /目錄F%255Bfacet_field_1%255D% 255B%255D = foo & f%255Bfacet_field_2%255D%255B%255D = bar & sort = title_info_primary_ssort + asc%252C + date_start_dtsi + asc HTTP/1.1「200 5266」 - 「」Mozilla/5.0(compatible; Googlebot/2.1; + http://www.google.com/bot.html)「

注意雙重編碼(」%255B「,」%255D「 ),它是已編碼字符(「%5B」,「%5D」)的編碼版本。因此,而不是我的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的URL進行雙重解碼的方法。似乎應該可以使用mod_rewrite來做到這一點,但我沒有太多的運氣,因爲mod_rewrite似乎不太適合修改URL的查詢字符串部分。這也是有問題的,因爲我無法預測參數的確切順序,也無法預測可能在URL中傳遞的參數的確切組合。

如何告訴Apache在將請求傳遞給我的應用程序之前對URL進行雙重解碼(基於用戶代理)? (服務器版本:Apache/2.4.7(Ubuntu))。阻止Googlebot不是一個可以接受的選項。

回答

0

有辦法做到這一點,但它需要修改服務器的.conf文件。您需要添加到服務器配置以下指令:

RewriteMap unescape int:unescape 

後,您可以使用重寫規則爲這樣的事情:

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] 
+0

(它可以在元素,不只是在參數的名稱值的雙引號的符號存在的情況下被觸發)這效果很好 - 謝謝!FWIW,我最終決定返回400錯誤的請求響應這些Googlebot的請求,而不是將其重定向彷彿參數已被正確編碼: 「的RewriteCond%{HTTP_USER_AGENT} Googlebot的 的RewriteCond%{QUERY_STRING}%25 [25] [ BC] RewriteRule。 - [R = 400,L]' – 2014-10-31 19:49:29