我想用django连接到内部http服务,我需要缓冲输出这些服务的http响应,因为有些内容非常大。
我正在使用python 3.6,django 2.0,http.client
以及以下代码:
class HTTPStreamIterAndClose():
def __init__(self, conn, res, buffsize):
self.conn = conn
self.res = res
self.buffsize = buffsize
self.length = 1
bytes_length = int(res.getheader('Content-Length'))
if buffsize < bytes_length:
self.length = math.ceil(bytes_length/buffsize)
def __iter__(self):
return self
def __next__(self):
buff = self.res.read(self.buffsize)
if buff is b'':
self.res.close()
self.conn.close()
raise StopIteration
else:
return buff
def __len__(self):
return self.length
def passthru_http_service(request, server, timeout, path):
serv = HTTPService(server, timeout)
res = serv.request(path)
response = StreamingHttpResponse(
HTTPStreamIterAndClose(serv.connection, res, 200),
content_type='application/json'
)
response['Content-Length'] = res.getheader('Content-Length')
return response
响应是空的,我用:
测试迭代器b''.join(HTTPStreamIterAndClose(serv.connection, res, 200)
一切正常,我不知道为什么不工作。
答案 0 :(得分:4)
https://andrewbrookins.com/django/how-does-djangos-streaminghttpresponse-work-exactly/
首先,某些条件必须为真:
- 客户必须说
HTTP/1.1
或更新- 请求方法不是
HEAD
- 响应不包含
Content-Length
标题- 回复状态不是
204
或304
如果这些条件属实,那么Gunicorn将为该标题添加
Transfer-Encoding: chunked
标题 响应,向客户端发出响应将流入的信号 块。事实上,Gunicorn即使有
Transfer-Encoding: chunked
也会回复 如果这些条件成立,你使用了HttpResponse!真正流式传输响应,即将响应发送到客户端 件,条件必须是真实的,你的反应必须是一个 可以使用多个项目进行迭代。
基本上,您需要决定:流媒体或Content-Length
。
如果您想要可恢复的下载,请使用Range
。
答案 1 :(得分:0)
最后,问题在于http请求在一段ms之后断开连接,这就是为什么当我在连接之后和创建对象之前进行迭代时找到而不是在我在响应之后使用时,但是当我开始迭代时启动连接时,所有工作都完美无缺= /。
干杯。