如何告诉HTTP服务器不要发送分块编码。

11

我正在写一个HTTP客户端,用于在返回HTTP响应的URL上执行HTTP POST请求。

然而,对于错误消息代码400和500,它会发送非分块的HTTP响应,而对于成功消息201,则会发送分块响应。

在请求中,我设置了内容长度,所以我不确定为什么它仍然向我们发送分块传输编码。是否还有其他头可以在请求中设置,告诉HTTP服务器不要发送分块编码?

        headerList.append("POST /v2/charges HTTP/1.1")
        headerList.append("Content-Type: application/json")
        headerList.append("host: xxxxxxxxx")
        headerList.append("request-id: ABCD001123")
        headerList.append("Content-length: %d" %len(Msg))
        hostReqHeader = "\r\n".join(headerList)
        reqData = hostReqHeader + '\r\n\r\n' + qbPosMsg

我正在使用套接字来发送这些HTTP消息,而不是使用httplib或requests库。


坏消息:RFC7230,¶4.1,"接收方必须能够解析和解码分块传输编码。" 因此,没有一般标准的方法可以防止分块编码。我想可能有一种特定于您的服务器且超出标准范围的方法。您使用的是哪个服务器? - Robᵩ
请参考第4.3节,"客户端不得在TE中发送分块传输编码名称;分块对于HTTP/1.1接收者始终是可接受的。" - Robᵩ
2个回答

10

Chunked是HTTP/1.1的必需特性。如果您不需要其他1.1特定的功能,请在请求中指定HTTP/1.0:

    headerList.append("POST /v2/charges HTTP/1.0")

6
您在请求中指定的Content-Length标头仅适用于请求,而不是服务器的响应。
当客户端将HTTP/1.1作为协议指定时,HTTP/1.1服务器在响应中才会使用分块传输。如果您想完全禁用分块传输,则可以在请求中指定HTTP/1.0作为协议。
或者,使用支持分块传输的HTTP客户端库 - 任何支持HTTP/1.1的库都可以,因为在任何HTTP/1.1对话中,服务器可以自由选择是否为任何请求使用分块传输。
HTTP/1.1(以及HTTP/2)服务器仍然支持HTTP/1.0,并且HTTP 1.0仍然非常有用,因为可以编写只需几行代码的简单客户端,仍然可以查询现代Web服务器(尽管需要进行TLS封装以支持HTTPS)。所以在这种情况下使用HTTP 1.0是相当合适的。我认为这就是HTTP的美妙之处,基本协议非常简单。HTTP 1.1和HTTP 2.0会逐步增加更多复杂性,以便能够编写支持它们的客户端,但所有这些复杂性都是可选的 - 仍然可以使用HTTP 1.0。

1
分块传输编码永远不会用于HTTP请求,只用于响应,并且仅当客户端指定HTTP/1.1协议时才使用。我认为这不正确。RFC是针对消息主体的分块编码,并没有特别提到它仅适用于响应。https://datatracker.ietf.org/doc/html/rfc2616#section-3.6.1 - Niall Connaughton
1
此外,根据RFC的规定:“所有HTTP/1.1应用程序都必须能够接收和解码“分块”传输编码”。因此,如果您的应用程序不支持分块编码,则根据定义,您正在实现HTTP 1.0而不是1.1。这没问题 - 只需告诉服务器您使用的是1.0版本即可。 - Niall Connaughton
或者使用版本HTTP 2。 - Obay Abd-Algader
1
我从未考虑过在请求中使用分块,但看起来你是对的。我想你需要确信服务器或代理启用了HTTP/1.1,这可以通过带外确定或基于先前在同一连接中收到的服务器响应进行确定。如今,在这方面,HTTP/1.1已经成为被遗忘的中间儿子,因为它的保持活动和分块传输在HTTP/2中被放弃以获得更好的多路复用,并且在HTTP/1.0中不受支持。 - thomasrutter

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