如果http响应不包含Content-Length标头,如何使用python正确下载文件?
我的appengine的send_blob()函数存在这个问题,由于某种原因,它不会在较大的(20mb +)blob上添加Content-Length头。
现在我正在使用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 :(得分:1)
如果服务器未指示所请求数据的长度,向您发送一些数据然后关闭连接,则 HTTP客户端必须假定所有数据都已成功传输。< / p>
只有在有效负载格式中使用其他非HTTP信息(例如校验和或其他纠错),应用程序才能确定发生了错误,并使用HTTP Range header (即Range: bytes=NNNN-
)在随后的客户请求中恢复转移。
如果服务器不支持Range
标头,如果服务器随时发送响应标头Accept-Ranges: none
,您可以得出结论,那么据我所知,您无法对损坏的服务器进行追索实现,除了定期重试请求,希望它最终提供通过错误检测的响应。
脚注:在提供blob内容时,Content-Length
标题丢失并不令我感到意外。许多数据库API不允许测试blob的长度而不实际检索整个事物。我怀疑这样做的原因是缺乏对SQL引擎本身测试的支持。
答案 1 :(得分:0)
App Engine使用chunked encoding发送响应,允许客户端确定响应何时完成。 urllib应该为你处理这个问题;由于某种原因,你的连接似乎很可能会提前终止,而urllib也没有与你沟通(或者你正在捕捉并忽略异常)。