Why does Content-Length HTTP header field use a value other than the one given in Java code?

荒凉一梦 提交于 2019-12-17 20:11:23

问题


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);

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?

I searched in HTTP spec but found no hint. I did not use any Transfer-Encoding or Transfer-coding.


回答1:


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 ;-)

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.

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).

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).

The restriction can manually be disabled by setting the System property sun.net.http.allowRestrictedHeaders to true on JVM startup.




回答2:


This solved for me:

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

"connection.setFixedLengthStreamingMode(myString.getBytes().length);" before set the Content-Length header.



来源:https://stackoverflow.com/questions/6056125/why-does-content-length-http-header-field-use-a-value-other-than-the-one-given-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!