3

一开始我以为http流其实就是实现了http chunk。

所以我做了一个测试来学习。

这是一个django视图

def test_stream(request):

    return StreamingHttpResponse(func)

func return iterable 这是使用 curl 访问视图的输出

curl -vv -raw http://172.25.44.238:8004/api/v1/admin/restart_all_agent?cluster_id='dd5aef9cbe7311e99585f000ac192cee' -i
Warning: Invalid character is found in given range. A specified range MUST 
Warning: have only digits in 'start'-'stop'. The server's response to this 
Warning: request is uncertain.
* About to connect() to 172.25.44.238 port 8004 (#0)
*   Trying 172.25.44.238...
* Connected to 172.25.44.238 (172.25.44.238) port 8004 (#0)
> GET /api/v1/admin/restart_all_agent?cluster_id=dd5aef9cbe7311e99585f000ac192cee HTTP/1.1
> Range: bytes=aw
> User-Agent: curl/7.29.0
> Host: 172.25.44.238:8004
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
* no chunk, no close, no size. Assume close to signal end

< 

some http response body.

* Closing connection 0

从输出中您可以看到没有分块标题。似乎Http流与块无关。

所以这是问题

  • http流是由http chunk实现的吗?
  • 如何在 django 中返回分块响应?
4

1 回答 1

2

不,流媒体与分块没有任何关系。你可以有一个有或没有另一个。

流式响应的优点是您不需要一次将整个响应作为字符串加载到内存中。

这篇博客文章很好地解释了用例是什么:https ://andrewbrookins.com/django/how-does-djangos-streaminghttpresponse-work-exactly/

它还涵盖了返回分块响应所需的内容,我将对此进行总结:

  • 使用StreamingHttpResponse类,但提供一个可迭代的(列表、生成器...)作为第一个参数而不是字符串。
  • 不要设置标题Content-Length
  • 您需要使用一个网络服务器来为您分块响应。Django 本身不会这样做,并且不会发生(manage.py runserver例如,但会发生)uvicorngunicorn
from django.urls import path
from django.http import StreamingHttpResponse

def generator():
    for i in range(0, 100):
        yield str(i) * 1024 * 1024

def chunked_view(request):
    return StreamingHttpResponse(generator(), content_type='text/plain')

urlpatterns = [path('chunked', chunked_view)]

使用uvicorn myapp.asgi:application.

curl -v http://127.0.0.1:8000/chunked > /dev/null显示transfer-encoding: chunked在响应标头中。

于 2019-12-19T11:20:08.263 回答