6

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

4

2 回答 2

16

我猜这HttpURLConnection将简单地用正确的值覆盖Content-Length标题,因为它知道撒谎是不好的;-)

事实上:如果合适的话,在第 535-550 行sun.net.www.protocol.HttpURLConnection设置。Content-Length这发生设置用户指定的标头之后,因此该值将被覆盖。

这是正确的:如果您传输的数据量与声称的数量不匹配,那么您只会混淆另一端。

检查它的来源sun.net.www.protocol.http.HttpURLConnection似乎有一个标题列表受到限制,并且在调用时会被忽略setRequestPropertyContent-Length是其中之一。不幸的是,这似乎没有记录(至少我找不到任何关于此的文档,这里只讨论一个相关问题)。

谷歌搜索引入此“功能”的 ChangeSet 中提到的错误 ID (?) ,似乎此更改是作为对安全漏洞CVE-2010-3541CVE-2010-3573的反应而引入的(Redhat 关于此主题的错误) .

sun.net.http.allowRestrictedHeaders可以通过将 System 属性设置为trueon JVM startup来手动禁用该限制。

于 2011-05-19T09:06:45.387 回答
0

这为我解决了:

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

“connection.setFixedLengthStreamingMode(myString.getBytes().length);” 在设置 Content-Length 标头之前。

于 2018-11-06T18:56:30.227 回答