为什么Content-Length HTTP头字段使用的值不是Java代码中给出的值? [英] Why does Content-Length HTTP header field use a value other than the one given in Java code?
问题描述
我有一段Java代码将字节数组传输到HTTP服务器:
I have a piece of Java code to transfer a byte array to HTTP server:
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="
+ myBoundary);
connection.setRequestProperty("Content-Length", 1024);
我使用此代码传输大小大于1024的字节数组。它运行良好。但实际的HTTP消息(由 Wireshark 捕获)显示Content-Length的值是实际大小而不是1024.为什么?
I used this code to transfer a byte array whose size is greater than 1024. It worked well. But the actual HTTP message (captured by Wireshark) shows that the value of Content-Length is the actual size instead of 1024. Why?
我搜索了 HTTP规范但没有发现任何暗示。我没有使用任何Transfer-Encoding或Transfer-coding。
I searched in HTTP spec but found no hint. I did not use any Transfer-Encoding or Transfer-coding.
推荐答案
我猜是 HttpURLConnection
将简单地覆盖带有正确值的 Content-Length
标头,因为它知道说谎它是否是好的; - )
I'd guess that the HttpURLConnection
will simply override the Content-Length
header with the correct value, since it knows that lying about it is no good ;-)
确实:在 sun.net.www.protocol.HttpURLConnection
如果合适,设置 Content-Length
。在设置了用户指定的标题之后会发生这种情况,因此该值将被覆盖。
And indeed: at the lines 535-550 of sun.net.www.protocol.HttpURLConnection
the Content-Length
is set if appropriate. This happens after the user-specified headers are set, so that value will be overwritten.
这是正确的:如果数量是您转移的数据与声明的金额不符,那么您只会混淆另一端。
And it's right about that: if the amount of data you transfer does not match the claimed amount, then you'll only confuse the other end.
检查 sun.net.www的来源.protocol.http.HttpURLConnection
似乎有一个受限制的标题列表,在调用 setRequestProperty
时将被忽略。 Content-Length
就在该列表中。不幸的是,这似乎没有记录(至少我找不到任何关于此的文档,只有这里讨论相关问题)。
Checking the source of sun.net.www.protocol.http.HttpURLConnection
it seems that there is a list of headers that are restricted and will silently be ignored when calling setRequestProperty
. Content-Length
is among that list. Unfortunately this seems to be undocumented (at least I couldn't find any documentation on this, only a discussion of a related problem here).
搜索引入此功能的ChangeSet 似乎这一变化是作为对安全漏洞的反应而引入的 CVE-2010- 3541 和 CVE-2010-3573 (关于此主题的Redhat错误)。
Googling for the Bug IDs (?) mentioned in the ChangeSet that introduced this "functionality" it seems that this change was introduces as a reaction to the security vulnerabilities CVE-2010-3541 and CVE-2010-3573 (Redhat bug on this topic).
可以通过设置系统属性 sun.net.http.allowRestrictedHeaders
t来手动禁用限制在JVM启动时 true
。
The restriction can manually be disabled by setting the System property sun.net.http.allowRestrictedHeaders
to true
on JVM startup.
这篇关于为什么Content-Length HTTP头字段使用的值不是Java代码中给出的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!