2011-10-05 108 views
2

如果http響應不包含Content-Length頭文件,我該如何正確使用python下載文件?如果沒有提供Content-Length,用python正確下載文件

即時通訊問題與appengine的send_blob()函數由於某種原因不會在較大(20mb +)blob添加內容長度標頭。

現在我使用urllib.urlretrieve(),但有時它不下載整個文件。 我現在正在做的是在下載文件之前發送內容長度,以便在繼續之前檢查文件是否具有合適的大小。

我不知道是否有更好的方法來做到這一點。

這些文件之一的標題:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Content-Type: application/octet-stream 
Expires: Fri, 01 Jan 1990 00:00:00 GMT 
Date: Fri, 30 Sep 2011 19:41:34 GMT 
Server: Google Frontend 
Transfer-Encoding: Identity 
Connection: close 

我只是試圖使用wget下載一個文件,wget --server-response --continue和標題有:

HTTP/1.1 200 OK 
    Cache-Control: no-cache 
    Content-Type: application/octet-stream 
    Expires: Fri, 01 Jan 1990 00:00:00 GMT 
    Date: Wed, 05 Oct 2011 14:08:13 GMT 
    Server: Google Frontend 
    Transfer-Encoding: chunked 
Length: unspecified [application/octet-stream] 
+0

確實關閉HTTP連接(從服務器端)工作? (不確定是否會產生明確定義的行爲,但這是我最好的猜測) – ninjagecko

+0

當它不發送Content-Length時,它是否使用Transfer-Encoding:chunked? –

+0

@ninjagecko:實際上並不知道在使用send_blob()函數時是否可以手動關閉連接。 – aschmid00

回答

0

App Engine使用chunked encoding發送響應,該響應允許客戶端確定響應何時完成。儘管如此,urllib應該爲你處理這個問題;由於某種原因,您的連接可能過早終止,並且urllib沒有向您傳達該連接(或者您在捕獲並忽略該異常)。

1

如果服務器沒有給出指示請求數據的長度,向您發送一些數據,然後關閉連接,然後HTTP客戶端必須假定所有數據都已成功傳輸。

只有使用附加的,非HTTP信息,例如有效載荷格式內的校驗和或其他的糾錯,可在應用確定已發生了錯誤,並使用HTTP Range header(即Range: bytes=NNNN-)在隨後的客戶端請求恢復轉移。

如果服務器不支持Range標頭,如果服務器隨時發送響應標頭Accept-Ranges: none,您可能會得出結論,那麼據我所知,除了定期重試以外,沒有辦法針對破損的服務器實施請求希望它最終能夠提供通過錯誤檢測的響應。

腳註:當服務blob內容時,Content-Length標題丟失並不令我吃驚。許多數據庫API不允許在沒有實際檢索整個事物的情況下測試blob的長度。我懷疑這是因爲在SQL引擎本身缺乏對此測試的支持。

+0

只有在不使用分塊編碼的情況下。 –

相關問題