从客户的角度来看,这很容易。您可以使用httplib
的低级接口—<a href="http://docs.python.org/library/httplib.html#httplib.HTTPConnection.putrequest" rel="nofollow"> putrequest
、putheader
、endheaders
和send
— 发送无论您想以任何大小的块向服务器发送任何内容。
但是您还需要指出文件的结束位置。
如果您事先知道文件的总大小,您可以简单地包含Content-Length
标头,并且服务器将在那么多字节后停止读取您的请求正文。代码可能看起来像这样。
import httplib
import os.path
total_size = os.path.getsize('/path/to/file')
infile = open('/path/to/file')
conn = httplib.HTTPConnection('example.org')
conn.connect()
conn.putrequest('POST', '/upload/')
conn.putheader('Content-Type', 'application/octet-stream')
conn.putheader('Content-Length', str(total_size))
conn.endheaders()
while True:
chunk = infile.read(1024)
if not chunk:
break
conn.send(chunk)
resp = conn.getresponse()
如果事先不知道总大小,理论上的答案是分块传输编码。问题是,虽然它被广泛用于响应,但对于请求来说似乎不太受欢迎(尽管定义一样)。普通的 HTTP 服务器可能无法开箱即用地处理它。但是,如果服务器也在您的控制之下,您可以尝试手动解析请求正文中的块并将它们重新组装到原始文件中。
Content-Length
另一种选择是通过同一连接将每个块作为单独的请求(带有)发送。但是您仍然需要在服务器上实现自定义逻辑。此外,您需要在请求之间保持状态。
Added 2012-12-27. There’s an nginx module that converts chunked requests into regular ones. May be helpful so long as you don’t need true streaming (start handling the request before the client is done sending it).