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.
The Content-Length header indicates the size of the message body, in bytes, sent to the recipient.
In PHP you would use something like this. header("Content-Length: ". filesize($filename)); In case of "Content-Type: application/x-www-form-urlencoded" the encoded data is sent to the processing agent designated so you can set the length or size of the data you are going to post.
Description. The Content-Length is optional in an HTTP request. For a GET or DELETE the length must be zero. For POST, if Content-Length is specified and it does not match the length of the message-line, the message is either truncated, or padded with nulls to the specified length.
As bytes are represented with two hexadecimal digits, one can divide the number of digits by two to obtain the content length (There are 12 hexadecimal digits in "48656c6c6f21" which equates to six bytes, as indicated in the header "Content-Length: 6" sent from the server).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With