DNA
DNA

Reputation: 42597

When POSTing a MultipartEntity using Apache HttpClient, ByteArrayBody works but InputStreamBody throws NoHttpResponseException

I am trying to POST some data taken from an InputStream. I was hoping to avoid having to gather all the data into a byte array first, and instead stream the data, to save memory (I am POSTing data of about 10MB).

If I run the following:

DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(target_url);
MultipartEntity entity = new MultipartEntity();
entity.addPart("data", new InputStreamBody(new ByteArrayInputStream(new byte[1]), 
    filename));
httpPost.setEntity(entity);
httpclient.execute(httpPost);

then I get:

org.apache.http.NoHttpResponseException: The target server failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:95)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:712)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:517)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
    [my code starts here]

However, if I change one line above, replacing the InputStreamBody with the equivalent ByteArrayBody, then all is well:

entity.addPart("data", new ByteArrayBody(new byte[1], filename));

What am I doing wrong?

(and would InputStreamBody actually stream the data, or am I wasting my time?)

I am using HttpClient-4.2.1

Upvotes: 2

Views: 5937

Answers (1)

ok2c
ok2c

Reputation: 27528

There is nothing wrong with what you are doing. The issue is likely to be that when using ByteArrayBody HttpClient is able to calculate the total request content length and delineates the message using Content-Length, while when using InputStreamBody HttpClient has to resort to content chunking (using Transfer-Encoding header). I suspect the server side script is simply unable to handle requests that do not have a Content-Length header.

Upvotes: 2

Related Questions