How do I explicitly disable chunked streaming mode for HTTP connections in Android?

Thomas Keller picture Thomas Keller · Aug 22, 2012 · Viewed 9.4k times · Source

I'm targeting a REST web service from Android 4.0 using HttpsURLConnection. This works fine unless I try to POST something. This is the relevant code section:

   connection.setDoOutput(true);
   connection.setChunkedStreamingMode(0);

   ByteArrayOutputStream out = new ByteArrayOutputStream();
   serializeObjectToStream(out, object);
   byte[] array = out.toByteArray();
   connection.getOutputStream().write(array, 0, array.length);

This throws the following exception:

   java.net.HttpRetryException: Cannot retry streamed HTTP body

From debugging I realized that the output stream I get via connection.getOuputStream() is of type ChunkedOutputStream and from digging in Androids source code I figured that if a request needs to be retried (for whatever reason), it pokes with the above exception, because it figures out that it is not using a RetryableOutputStream that it wants there.

The question is now: How do I make my HttpsURLConnection return such a RetryableOutputStream, or rather, how can I prevent chunked request encoding properly? I thought I did that already with setChunkedStreamingMode(0), but apparently this is not the case...

[edit]

No, the implementation of java.net.HTTPUrlConnection ignores a streaming mode of 0 or lower:

 public void setChunkedStreamingMode(int chunkLength) {
    [...]
    if (chunkLength <= 0) {
        this.chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH;
    } else {
        this.chunkLength = chunkLength;
    }
}

Answer

Thomas Keller picture Thomas Keller · Aug 27, 2012

Bummer! The solution is to not call setChunkedStreamingMode() (or even setFixedStreamingMode()) from the client code at all! "-1" are the internal default values for fixedLength and chunkedLength and cannot be set client-side, because setting a value lower or equal to "0" lets it default to HttpEngine.DEFAULT_CHUNK_LENGTH (or throws an exception in the fixed streaming mode case).