Nginx删除分块内容的Content-Length标头


10

我使用nginx 1.2.3代理脚本:

proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;

脚本同时发送Transfer-encoding: chunkedContent-Length: 251

HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked

我都需要,但是nginx会自动删除Content-Length

HTTP/1.1 302 Found
Server: nginx/1.2.3
Content-Type: application/json; charset=utf-8
Content-Length: 58
Connection: keep-alive
Location: /...

结果,客户端不等待发送块。这曾经与早期版本的nginx一起使用。


Nginx代理的标头是什么样的?
h缩

它曾经使用过哪个版本?
cnst

它曾经与nginx 0.9.8一起使用
Julien

您违反了HTTP协议。它可以与nginx 0.9.8一起使用,因为直到1.1.4版本,它才完全不支持分块编码。
VBart 2013年

Answers:


11

不幸的是,我无法评论cnst的帖子-所以我将在这里回答。

nginx_http_proxy默认情况下,该模块与HTTP / 1.0中的上游对话。可以使用指令更改它proxy_http_version 1.1

尽管307此版本中不存在分块编码和状态码,但这也可能是脚本返回HTTP / 1.0答案的原因。

您也不应该将分块编码与重定向一起使用,因为这实际上没有意义。

另外,似乎nginx 不会将上游的块大块地传递给客户端,而是缓冲上游的响应。该Content-Length头字段被忽略,因为它是对的定义。我必须查看模块的源代码,因为所有这些似乎都没有记录。

您可能想尝试使用nginx_tcp_proxy_module代理将分块的内容作为原始TCP数据进行代理:Github上的模块


UPDATE(14年4月10日)
nginx_http_proxy模块具有用于支撑X-Accel-* ,其中的一个(X-Accel-Buffering: yes|no)控制是否将响应应该被缓冲或没有。

将此标头(X-Accel-Buffering: no)添加到后端的响应中,将导致nginx直接将块传递给客户端。

此标头允许根据每个请求控制缓冲。

该模块还具有用于启用或禁用响应缓冲的配置指令 proxy_buffering(不缓冲意味着发送块将起作用)。

此处记录代理缓冲(基于标头和指令)。


他甚至不应该那样做nginx_tcp_proxy_module。它仅可用于某些浏览器,因为它们具有很高的容错能力。
VBart 2013年

因为所有这些似乎都没有记载错误。它记录在RFC 2616中。请参见13.5.1
VBart 2013年

@VBart当然有标准-但是关于nginx特别实现它们的程度的信息很少。TCP代理模块是建议的解决方法
卢卡斯

9

正如Lukas所暗示的那样,HTTP 1.1禁止Content-Length使用它Transfer-Encoding

引用http://www.ietf.org/rfc/rfc2616.txt

   3.If a Content-Length header field (section 14.13) is present, its
     decimal value in OCTETs represents both the entity-length and the
     transfer-length. The Content-Length header field MUST NOT be sent
     if these two lengths are different (i.e., if a Transfer-Encoding
     header field is present). If a message is received with both a
     Transfer-Encoding header field and a Content-Length header field,
     the latter MUST be ignored.

此外,Nginx符合HTTP 1.1的正确行为对于防止HTTP请求走私攻击大有帮助。
AMN

3

您尚未具体说明为什么脚本首先需要分块编码,尤其是在重定向响应中。

我在这里看到很多问题。

  • Transfer-Encoding: chunked是一项HTTP/1.1功能(而且您的脚本似乎在回复HTTP/1.0标头)

  • 有没有307HTTP/1.0

  • 的全部目的chunked是您不知道要怎么做Content-Length,因此chunked被用来代替中的长度Content-Length,而在响应正文中提供的长度与实际内容混合在一起;脚本预先生成两个标头是没有意义的

我个人并不熟悉chunked,但是根据http://en.wikipedia.org/wiki/Chunked_transfer_encodinghttp://tools.ietf.org/html/rfc2616#section-3.6.1的基本信息,我猜想您的脚本对分块编码的整个处理可能是完全错误的。

如果以上内容仍未涵盖该内容,或者实际上还没有涵盖该内容,则还不清楚为什么应使用“奇怪”编码为带有a 307302http状态代码的回复提供信息。最近,nginx邮件列表中也有类似的讨论,关于410 Gone其他错误页面始终不包含在gzip压缩范围内,我认为这种观点在这里同样适用。(http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html


我用它来让用户等待:我每秒钟发送一次块,以便用户等待X秒的重定向而不会超时
Julien 2013年

我建议您先将HTTP / 1.0修复为HTTP / 1.1(这确实有所作为),并确保分块的编码不正确。较新版本的nginx可能会丢弃您依赖的某些标头,因为它们是错误的。
cnst 2013年

1

我有同样的问题通过html5 video标签流mp4文件。

Safari和Firefox表现正常,而Chrome在某个时候触发了ERR_CONTENT_LENGTH_MISMATCH(但它使我可以观看视频几分钟,然后再失败)。

我关闭了mp4文件的缓存控制后,该问题不再出现。


0

分享我发布给SO的答案,以防它有用:https : //stackoverflow.com/questions/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509

由于未提供数据块,我在mp4播放时遇到了类似的问题,并按照下面列出的Apple指南确认了该问题。我确认我正在下载整个文件,并且在下面的修复程序之后,仅下载了第一块。

curl --range 0-99 http://example.com/test.mov -o /dev/null

我通过更改nginx.conf中的gzip压缩设置以删除.mp4文件的gzip压缩来解决了Safari .mp4播放的问题。

这是nginx中的块供参考。(注意:根据您应用的配置方式,您可能需要将位置行更改为location ~ \.mp4$ {

location ~ ^/(assets|system|videos)/  {
   expires max;
   add_header Cache-Control public;
   add_header ETag "";
   gzip on;
   gzip_http_version 1.1;
   gzip_vary on;
   gzip_comp_level 6;
   gzip_proxied any;

   # Reference configuration
   #gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript video/mp4 application/mp4 image/jpeg image/png image/svg+xml application/x-font-ttf application/x-font-truetype application/font-woff application/font-woff2 application/vnd.ms-fontobject;

   # Kelton trying to fix cloudflare by removing the mp4 settings
   gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript image/jpeg image/png image/svg+xml application/application/x-font-ttf application/x-font-truetype application/font-woff application/font-woff2 application/vnd.ms-fontobject;
}

链接到Apple文档参考:https : //developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.