我有一段 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 规范 中进行了搜索,但没有找到任何提示.我没有使用任何传输编码或传输编码.
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
的来源好像有一个headers列表是限制的,调用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).
可以通过在 JVM 启动时将系统属性 sun.net.http.allowRestrictedHeaders
设置为 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 代码中给出的值不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!