用于分块响应的uwsgi / nginx配置

时间:2018-01-02 22:50:45

标签: python http nginx uwsgi chunked-encoding

我有两个端点,如下所示:

  

获取/ api / v1 / foo

     

在/ api / v1 / foo上发布

我需要POST实现使用HTTP / 1.1 chuked-tranfer编码发送回chunked响应,但是GET端点应该发送普通JSON

我的设置为nginx -> uwsgi -> flask

我看到我的一些块当前被截断为十六进制大小1000,其字节为4K,与我发送的烧瓶层不同。可能是因为我错过了一些nginx或uwsgi配置。

uwsgi配置(uwsgi.ini):

[uwsgi]
route = ^/api/v1/foo$ goto:dochunked
route-run = last:

route-label = dochunked
route-if = equal:$\{REQUEST_METHOD\};POST goto:dopostchunked
route-run = last:

route-label = dopostchunked
route-run = chunked:

nginx配置:

location / {
    uwsgi_pass unix:var/uwsgi.sock;
    uwsgi_read_timeout 600; 
    include uwsgi_params;   
}

location /api/v1/foo {   
    uwsgi_pass unix:var/uwsgi.sock;
    uwsgi_read_timeout 600; 
    include uwsgi_params;   

    if ($request_method = "POST" ) {
        set $chunked_transfer_encoding on;
        add_header X-Accel-Buffering no;
    }
}

卷曲响应标题

HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Wed, 03 Jan 2018 00:06:50 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
X-Frame-Options: deny
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Accel-Buffering: no

1 个答案:

答案 0 :(得分:1)

Chunking约为Transfer-Encoding,普通JSON为Content-Type,这两件事情无关。

传输编码的东西就是两个HTTP 1.1端点(服务器和客户端)使用的通信方法。就像gzip压缩一样。使用分块传输可以避免使用Content-Length标头,并允许响应以多个发送,当然。但另一方面,一旦收到响应,就会添加块,而你看不到通过Content-Length + big-body-in-one-chunk或body发送的响应之间的任何差异-sent-输入多块。

我说应该,因为您可能会遇到HTTP / 1.1错误的问题。在为应用程序语言启动诸如 response-receveid event 之类的事情之前,不等到消息结束(最后一个块标记)的库。

通常使用或不使用块是HTTP服务器的责任,并且由于块支持是HTTP / 1.1的请求的功能,因此很少有其他内容。使用响应主体的大小和http服务器使用的缓冲区的大小,您可能会看到组块的方式存在差异。如果链中有多个actor(比如这里的flask和Nginx),每个actor都可以决定重新组织块,合并其中一些(缓冲),或者不合并。

但正如我所说,你不应该关心它。除非你的应用程序的客户端是分块编码的错误,否则这意味着你的HTTP通信方面并不了解HTTP / 1.1。

最后,如果你真的需要避免块,但你不应该,我看到3个选项:

  • 您可以强制执行 HTTP / 1.0响应。没有HTTP / 1.0的块。但那是一个非常古老的协议版本。要做到这一点,您必须在请求方中要求HTTP / 1.0,您将从Nginx获得HTTP / 1.1响应,但没有HTTP / 1.1的高级功能(喜欢chunks)。
  • 您可以使用nginx chunked_transfer_encoding设置。我们默认情况下可以看到 on ,因此通常您可以使用它将其设置为特定位置的 off 。您当前使用它的方式什么都不做。此选项专门针对糟糕的HTTp客户端,如上所述:
      

    当使用软件无法支持分块时,它可能会派上用场   尽管符合标准要求,但编码。

  • 您也可以尝试使用proxy_buffering off,但这可能有用,我不确定。