在Python中通过HTTP从客户端到服务器流式传输未知大小的数据

Wou*_*ter 4 python upload http

不幸的是,我之前的问题因为是一个问题的"精确副本"而被关闭,而它绝对不是,特此再次.

它不是Python的重复:HTTP发布带有流的大文件

那个处理流式传输大文件; 我想将一个文件的任意块一个接一个地发送到同一个http连接.所以我有一个20 MB的文件,我想要做的是打开HTTP连接,然后发送1 MB,再发送1 MB等,直到它完成.使用相同的连接,服务器看到该连接上出现一个20 MB的块.

我也打算做一个Mmapping文件,但是当从stdin读取数据时这不起作用.主要针对第二种情况,我正在寻找这种逐个数据馈送.

老实说,我想知道它是否可以完成 - 如果没有,我想知道,那么可以关闭这个问题.但如果可以做到,怎么办呢?

Vas*_*nov 5

从客户的角度来看,这很容易.您可以使用httplib的低级别的界面- ,putrequest,putheader,endheaderssend-to发送任何你想要的服务器在任何大小的块.

但是您还需要指出文件的结束位置.

如果你事先知道文件的总大小,你可以简单地包含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()
Run Code Online (Sandbox Code Playgroud)

如果您事先不知道总大小,理论答案就是分块传输编码.问题是,虽然它被广泛用于响应,但它似乎不太受欢迎(尽管定义得很好).库存HTTP服务器可能无法开箱即用.但是,如果服务器也在您的控制之下,您可以尝试手动解析请求正文中的块并将它们重新组装到原始文件中.

另一种选择是Content-Length通过同一连接将每个块作为单独的请求(with )发送.但是您仍然需要在服务器上实现自定义逻辑.而且,您需要在请求之间保持状态.

添加2012-12-27.一个nginx模块可以将分块请求转换为常规请求.只要您不需要真正的流媒体(在客户端完成发送之前开始处理请求),可能会有所帮助.