【问题标题】:Iterable object and Django StreamingHttpResponse可迭代对象和 Django StreamingHttpResponse
【发布时间】:2018-06-09 10:43:09
【问题描述】:

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

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

【问题讨论】:

  • 浏览器控制台有错误吗?
  • 不,没有错误
  • “不工作”是什么意思?你得到http 500吗? 200 有空白输出?请在您的问题中提供curl -v http://localhost:8000/x/y/(或邮递员或...)输出。
  • 正如我所说,空响应,什么都没有 =(
  • 使用外部连接作为客户端,你会看到真正的“发生了什么”!根据您的问题,以这种方式连接到环回地址是不可能的(为流作业定义另一个环回)。

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


【解决方案1】:

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

【讨论】:

  • 这是否也适用于其他 WSGI 服务器?
  • IDK,我没有实验。
【解决方案2】:

最后,问题在于 http 请求在几毫秒后断开连接,这就是为什么当我在连接之后和创建对象之前进行迭代时发现而不是在响应之后使用时,但是当我开始迭代时开始连接时,一切正常=/。

干杯。

【讨论】:

    猜你喜欢
    • 2021-07-04
    • 2021-02-04
    • 2020-02-28
    • 2013-05-07
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 2020-05-25
    相关资源
    最近更新 更多