2012-11-14 40 views
4

我使用urllib2做一個使用Python 2.7.3的http post請求。我的請求正在返回HTTPError異常(HTTP錯誤502:代理錯誤)。奇怪的重定向位置導致與urllib2的代理錯誤

看着與查爾斯消息流量,我看到下面正在發生的事情:

  1. 我使用的urllib2
  2. 的發送HTTP請求(POST /index.asp?action=login HTTP/1.1)遠程服務器回覆狀態303和位置標頭../index.asp?action=news
  3. urllib2重試發送獲取請求:(GET /../index.asp?action=news HTTP/1.1)
  4. 遠程服務器回覆狀態502(代理錯誤)

的502答覆包括本會在響應正文:「DNS查找失敗的:10.0.0.30:80index.asp」(注意格式不正確的URL)

所以我認爲這意味着,關於代理服務器遠程服務器的網絡會在請求中看到「/../index.asp」URL,並將其誤解,並將請求發送給錯誤的URL。

當我用我的瀏覽器(Chrome)發出同樣的請求時,重試會發送到GET /index.asp?action=news。因此,Chrome取消了URL中的前導「/ ..」,並且遠程服務器回覆了有效的響應。

這是一個urllib2錯誤嗎?有什麼我可以做的,所以重試忽略URL中的「/ ..」?或者有其他方法可以解決這個問題嗎?認爲它可能是一個urllib2錯誤,我用請求換出了urllib2,但請求產生了相同的結果。當然,這可能是因爲請求建立在urllib2上。

感謝您的任何幫助。

+0

當您在Chrome中嘗試時,位置標頭是'../ index.asp?action = news'以及? –

+0

我認爲這是一個無效的位置,在這種情況下,它確實是服務器配置中的一個錯誤。如果是這樣的話,那麼Chrome和許多其他瀏覽器都可以解決這個問題,這並不意味着'urllib2'不是這樣做的錯誤。 – abarnert

回答

2

與302一起發送的位置在多個方面都是錯誤的。首先,如果您閱讀RFC2616(HTTP/1.1標題字段定義)14.30位置,則位置必須是絕對URI,而不是相對的。 10.3.3節明確指出這是相關的定義。其次,即使允許使用相對URI,RFC 1808,相對統一資源定位符,4.解析相對URL,第6步,僅在<segment>/../模式中指定..的特殊處理。這意味着相對URL不應以..開頭。因此,即使基本網址是http://example.com/foo/bar/而相對URL是../baz/,解析後的網址也不是http://example.com/foo/baz/,而是http://example.com/foo/bar/../baz。 (當然,大多數服務器都會以相同的方式處理這些內容,但這取決於每臺服務器。)

最後,即使您在解析..之前合併了相對和基本URL,其路徑始於..的絕對URI是無效。

所以,這個錯誤是在服務器的配置。

現在,很多用戶代理都會解決這個問題。特別是,他們將/../foo變成/foo,以阻止用戶(或者在他們不知情的情況下代表他們運行任意JS)試圖「逃離webroot」攻擊。

但是,這並不意味着urllib2應該這樣做,或者它不是這樣做的越野車。當然,urllib2應該提前檢測到錯誤,以便它可以告訴你「無效路徑」或其他東西,而不是一起運行一個非法的絕對URI,這會使服務器混淆發送回無意義的錯誤。但它權利失敗。

說服務器配置是錯誤的,但除非你是負責服務器的人,否則你可能會面臨一場艱苦的鬥爭,試圖說服他們他們的網站已經損壞並且需要當它與他們關心的每個網頁瀏覽器一起工作時,它們將被修復。這意味着您可能需要編寫自己的解決方案來處理他們的網站。

的方式來做到這一點與urllib2是與redirect_request方法的實現,這種情況識別並返回一個不同Request比默認的代碼會(尤其是http://example.com/index.asp?action=news代替http://example.com/../index.asp?action=news)提供自己的HTTPRedirectHandler

+0

哇。一個很好的解釋 - 徹底和清晰。我會研究HTTPRedirectHandler。 – david193

+0

abamert,謝謝你的幫助。我實現了一個HTTPRedirectHandler,它給了我所需要的。 – david193

+0

@ david193:很高興幫助。同時,對於運行遠程服務器的人提出一個錯誤,因爲你不應該首先處理這個問題。 – abarnert