Java HttpURLConnection: Content Length computation

2019-06-18 23:06发布

问题:

I'm currently developing a library for the bitbucket issues RESTful API. I made good progress and now I'm going to tackle the section Updating an Issue which demands an HTTP PUT Request.

Now I'm stuck because of the HTTP Error Code 411 Length Required. After a bit of googling, I found the following code example:

// CORRECT: get a UTF-8 encoded byte array from the response
// String and set the content-length to the length of the
// resulting byte array.
String response = [insert XML with UTF-8 characters here];
byte[] responseBytes;
try {
    responseBytes = response.getBytes("UTF-8");
}
catch ( UnsupportedEncodingException e ) {
    System.err.print("My computer hates UTF-8");
}

this.contentLength_ = responseBytes.length;

Now my question: What is exactly measured?

  • the query string
  • the urlencoded query string
  • only the values of the parameters...??

And is connection.setRequestProperty("Content-Length", String.valueOf(<mycomputedInt>)); an appriopate way of setting the content length attribute?

Examples appreciated. Thanks in advance.


edit:

For instance, you could explain computation with the following curl example from the bitbucket wiki entry:

curl -X PUT -d "content=Updated%20Content" \
https://api.bitbucket.org/1.0/repositories/sarahmaddox/sarahmaddox/issues/1/

回答1:

Your are doing the request, right. The content-length is the number of bytes of your request body. In your case

int content-length = "content=Updated%20Content".getBytes("UTF-8").length;

What is exactly measured?

the url encoded query string (when in the request/entity body)



回答2:

HTTP spec on 411:

The server refuses to accept the request without a defined Content- Length. The client MAY repeat the request if it adds a valid Content-Length header field containing the length of the message-body in the request message.

HTTP spec on the Content-Length header:

The Content-Length entity-header field indicates the size of the entity-body, in decimal number of OCTETs

HTTP spec on HTTP entity length:

entity-body := Content-Encoding( Content-Type( data ) )

The entity-length of a message is the length of the message-body before any transfer-codings have been applied.


To summarise if you want to send an un-compressed UTF-8 string you would determine the bytes to send as:

Identity( UTF-8( "content=Updated%20Content" ) )

The Content-Length is set to the number of bytes output.

If you are sending UTF-8 data I would also strongly suggest you set a Content-Type header.