繁体   English   中英

Iterable对象和Django StreamingHttpResponse

[英]Iterable object and Django StreamingHttpResponse

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

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

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

首先,一些条件必须是真的:

  • 客户端必须说HTTP/1.1或更高版本
  • 请求方法不是HEAD
  • 响应不包括Content-Length标头
  • 响应状态不是204304

如果这些条件成立,则Gunicorn将向响应添加Transfer-Encoding: chunked标头,向客户端发信号通知响应将以块的形式流式传输。

实际上,即使你使用了HttpResponse,如果这些条件成立,Gunicorn也将使用Transfer-Encoding: chunked响应Transfer-Encoding: chunked

要真正流式传输响应,即将其发送到客户端,条件必须为true,并且您的响应需要是具有多个项目的可迭代响应。

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

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

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

干杯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM