为什么IIS不支持分块传输编码?

7
我正在向一个IIS web服务器建立HTTP连接,并使用Transfer-Encoding: chunked编码发送POST请求数据。然而,当我这样做时,IIS会简单地关闭连接,没有错误消息或状态码。根据HTTP 1.1规范,所有HTTP/1.1应用程序都必须能够接收和解码“chunked”传输编码,因此我不明白为什么它既不能处理该编码,也不发送状态码。如果我将请求更改为发送Content-Length而不是Transfer-Encoding,则查询成功,但这并不总是可能的。
当我尝试在Apache上执行相同的操作时,我会得到一个“411 Length required”状态和一条消息,指出“chunked Transfer-Encoding forbidden”。
为什么这些服务器不支持这种编码?
5个回答

8

请看您的客户端。

无论是IIS还是Apache,都支持使用分块传输编码进行POST请求。您可以使用curl实用程序进行验证:

curl <upload-url> --form "upfile=@<local_file>" --header "Transfer-Encoding: chunked"

使用Wireshark验证传输是否分块


4
我的理解是分块编码只能在HTTP响应中使用。分块请求体具有与1.0服务器不兼容的属性,在任何情况下,用户代理也无法知道服务器是否为1.0服务器,直到它已经发送了请求。
但我同意文档不够清晰。

3
客户端可以通过发送 HEAD 请求(等其他请求)来向服务器询问。在阅读 RFC 2616 第 3.6 节时,我们可以得知当服务器收到一个无法理解的传输编码头部时,必须发送 501 响应。第 3.6.1 节说明所有的 HTTP 1.1 应用程序都必须能够接收和解码分块传输编码。因此对我来说很明显 - 客户端到服务器的通信可以是分块的。文件上传是一个常见的场景。 - Cheeso
1
原帖作者没有提到他们使用的IIS版本,但是IIS 7肯定支持传入的分块数据——我有一个C++应用程序将请求作为分块数据发送到IIS 7,没有任何问题。 - Stephen Edmonds
1
我认为你是错误的。服务器和客户端应该支持分块传输编码(不过这并不意味着它们一定支持)。你的理由是不正确的,因为任何支持http1.1的客户端也应该知道如何与http1.0服务器通信。请参见:http://www.jmarshall.com/easy/http/#http1.1s3 和:http://www.atnan.com/2008/8/8/transfer-encoding-chunked-chunky-http 和:http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6(第3.6.1节也是如此)。 - Aaron H.
我认为向HTTP 1.0服务器发送分块请求的客户端是有问题的;如果客户端在向服务器发送任何内容之前就能知道服务器支持HTTP 1.1(通过魔法?),那么它可以发送一个分块请求。有些客户端查看以前请求的响应来决定服务器是否支持1.1,我想在大多数情况下这是有效的(尽管行为仍然可疑)。 - MarkR
1
下降投票,HTTP 1.1标准规定,分块传输编码应支持请求和响应。 - unixman83

3

这是相互的。试着上传一个2MB以上的图像到 Photobucket 并记录一下。他们的上传器将分块上传到他们的 Apache 服务器上。


-1

这个命令真是救了我一命!

C:\Windows\System32\Inetsrv\Appcmd.exe set config -section:httpCompression
-[name='gzip'].staticCompressionLevel:9 -[name='gzip'].dynamicCompressionLevel:4

真是救了我的一天... 希望能帮到像我一样的人!


我不明白启用压缩与处理分块请求有什么关系。已点踩。 - Mike Dimmick

-1

我唯一的猜测是,由于安全问题的考虑,他们没有实现它。在一个天真的解决方案中,通过启动多个永远不会结束的分块传输,很容易设置DOS攻击。而一个可以应对DOS攻击的复杂解决方案可能不值得付出这样的努力。

当然,我不能代表Apache或IIS发言,您可以直接联系Apache团队:http://httpd.apache.org/bug_report.html

我同意MarkR的观点,我一直认为分块编码只能用作响应,但文档确实让它听起来可以用于请求或响应。


2
客户端可以使用分块编码。这是由RFC2616允许的。例如,在文件上传场景中非常有用。 - Cheeso
1
你可以轻松地设置类似的DOS攻击,而无需分块编码。声明一个长度为1的内容,但从未发送正文。完成。我认为与分块不同之处在于它不需要内容长度头,因此您可以流式传输未知长度的数据,并通过关闭连接终止。IIS通过最大请求长度和请求超时来保护免受这些问题的影响。 - MarkPflug

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接