Iterable对象和Django StreamingHttpResponse

时间:2017-12-28 22:12:54

标签: python django python-3.x django-2.0

我想用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)

一切正常,我不知道为什么不工作。

2 个答案:

答案 0 :(得分:4)

https://andrewbrookins.com/django/how-does-djangos-streaminghttpresponse-work-exactly/

  

首先,某些条件必须为真:

     
      
  • 客户必须说HTTP/1.1或更新
  •   
  • 请求方法不是HEAD
  •   
  • 响应不包含Content-Length标题
  •   
  • 回复状态不是204304
  •   
     

如果这些条件属实,那么Gunicorn将为该标题添加Transfer-Encoding: chunked标题   响应,向客户端发出响应将流入的信号   块。

     

事实上,Gunicorn即使有Transfer-Encoding: chunked也会回复   如果这些条件成立,你使用了HttpResponse!

     

真正流式传输响应,即将响应发送到客户端   件,条件必须是真实的,你的反应必须是一个   可以使用多个项目进行迭代。

基本上,您需要决定:流媒体或Content-Length

如果您想要可恢复的下载,请使用Range

答案 1 :(得分:0)

最后,问题在于http请求在一段ms之后断开连接,这就是为什么当我在连接之后和创建对象之前进行迭代时找到而不是在我在响应之后使用时,但是当我开始迭代时启动连接时,所有工作都完美无缺= /。

干杯。