我使用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;
脚本发送传输编码:分块和内容长度:251:
HTTP/1.0 307 Temporary Redirect Content-length: 251 Pragma: no-cache Location: /... Cache-control: no-cache Transfer-encoding: chunked
我需要两个,但nginx自动删除内容长度:
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。
不幸的是,我不能评论cnst的post – 所以我会在这里回答。
默认情况下, nginx_http_proxy
模块与HTTP / 1.0中的上游进行通信。 这可以通过指令proxy_http_version 1.1
进行修改。
这也可能是脚本返回HTTP / 1.0答案的原因,尽pipe此版本中不包含分块编码和状态码307
。
你不应该使用redirect编码,因为这没有什么意义。
此外 ,似乎nginx 并没有将上游的数据块逐个传递给客户端,而是缓冲了上游的响应 。 Content-Length
标题字段被忽略,因为它违背了定义。 我不得不看看模块的源代码 ,因为所有这些似乎都是无证的。
您可能需要尝试nginx_tcp_proxy_module
将分块的内容作为原始TCP数据进行代理: Github上的模块
UPDATE (10.04.14)
nginx_http_proxy
模块支持X-Accel-*
头 ,其中一个( X-Accel-Buffering: yes|no
)控制是否caching响应。
将这个头( X-Accel-Buffering: no
)添加到后端的响应将导致nginx直接将块传递给客户端。
这个头允许在每个请求的基础上控制缓冲。
该模块还有一个configuration指令 proxy_buffering
来启用或禁用响应缓冲(不缓冲意味着发送块将工作)。
代理缓冲(基于头和指令) 在这里被logging。
正如Lukas所指出的那样,如果有一个Transfer-Encoding
集,HTTP 1.1将禁止Content-Length
。
引用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 (ie, 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.
您还没有具体阐述为什么您的脚本首先需要分块编码,尤其是redirect响应。
我在这里看到很多问题。
Transfer-Encoding: chunked
是一个HTTP/1.1
function(你的脚本似乎是用HTTP/1.0
头来回复)
HTTP/1.0
没有307
chunked
的全部目的是你不知道你的Content-Length
会是什么,所以chunked
用来代替在Content-Length
内提供Content-Length
,而在响应的主体内部提供长度,混合与实际内容; 脚本生成两个标头是没有意义的
我个人不熟悉chunked
,但根据http://en.wikipedia.org/wiki/Chunked_transfer_encoding和http://tools.ietf.org/html/rfc2616#section-3.6.1的基本信息,我会猜测你的脚本对分块编码的整个处理可能是完全错误的。
如果上述内容仍然没有涉及到,并且在所有的情况下,也不清楚为什么应该给“ 307
或“ 302
http状态码的回复提供一个“奇怪的”编码。 最近在nginx邮件列表中有类似的讨论,大概有410 Gone
和其他的错误页面总是排除在gzip
压缩之外,我认为这里的情绪同样适用。 ( http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html )
我有相同的问题通过HTML5video标签streammp4文件。
Safari和Firefox运行正常,而Chrome在某些时候触发了ERR_CONTENT_LENGTH_MISMATCH(但它允许我在发生故障前扫描video的几分钟)。
在closures对mp4文件的caching控制后,问题没有再现。