为什么内容长度 HTTP 标头字段使用的值不是 Java 代码中给出的值



我有一段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规范中搜索,但没有找到提示。我没有使用任何传输编码或传输编码。

我猜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 错误)的反应而引入的。

通过将 System 属性sun.net.http.allowRestrictedHeaders设置为 JVM 启动时true,可以手动禁用此限制。

这为我解决了:

connection.setFixedLengthStreamingMode(myString.getBytes().length);
conn.setRequestProperty("Content-length", String.valueOf(myString.getBytes().length));

"connection.setFixedLengthStreamingMode(myString.getBytes().length);",然后设置 Content-Length 标头。

相关内容

  • 没有找到相关文章

最新更新