[英]Why does Content-Length HTTP header field use a value other than the one given in Java code?
我有一段Java代码将字节数组传输到HTTP服务器:
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.为什么?
我在HTTP规范中搜索但没有发现任何提示。 我没有使用任何Transfer-Encoding或Transfer-coding。
我猜HttpURLConnection
将简单地用正确的值覆盖Content-Length
标头,因为它知道说谎它是不好的;-)
确实如此:在sun.net.www.protocol.HttpURLConnection
第535-550行,如果合适,设置Content-Length
。 这在用户指定的标头设置后发生,因此该值将被覆盖。
这是正确的:如果您传输的数据量与声明的数量不符,那么您只会混淆另一端。
检查sun.net.www.protocol.http.HttpURLConnection
的源代码似乎有一个受限制的标头列表,在调用setRequestProperty
时将被忽略。 Content-Length
就在该列表中。 不幸的是,这似乎没有记录(至少我找不到任何关于此的文档,只讨论相关问题 )。
谷歌搜索引入此“功能”的ChangeSet中提到的错误ID(?),似乎此更改是作为对安全漏洞CVE-2010-3541和CVE-2010-3573 ( 本主题的Redhat错误 )的反应而引入的。
通过在JVM启动时将系统属性sun.net.http.allowRestrictedHeaders
设置为true
,可以手动禁用该限制。
这解决了我:
connection.setFixedLengthStreamingMode(myString.getBytes().length);
conn.setRequestProperty("Content-length", String.valueOf(myString.getBytes().length));
“connection.setFixedLengthStreamingMode(myString.getBytes()的长度。);” 在设置Content-Length标头之前。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.