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