Reputation: 57
I'm trying to upload an InputStream
via HttpPut
using the Apache HttpClient 4.5.6:
InputStream inputStream = ..
CredentialsProvider provider = ..
HttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(provider)
.build();
HttpPut method = new HttpPut("MY_REMOTE_URL");
InputStreamEntity entity = new InputStreamEntity(inputStream);
method.setEntity(entity);
client.execute(method);
Uploading requires authentication and in my case I don't know if the Server used digest or basic authentication, therefore the client automatically sends multiple requests to determine the authentication scheme. But InputStreamEntity
is non repeatable , leading to the following errors:
org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
I can wrap the entity with BufferedHttpEntity
which makes it repeatable:
..
BufferedHttpEntity entity = new BufferedHttpEntity(new InputStreamEntity(inputStream));
method.setEntity(entity);
..
.. but then the stream first gets buffered and then sent in total, not chunked / streamed. This does not work for bigger files.
I can add a hardcoded header with the correct authentication to prevent the request from being repeated. But as I said, I don't know the authentication scheme.
I upload an empty file first, harvest the context and add it to my InputStream PUT request:
HttpPut testMethod = new HttpPut("MY_REMOTE_DUMMY_URL");
FileEntity testEntity = new FileEntity(testFile);
testMethod.setEntity(testEntity);
HttpContext context = new BasicHttpContext();
client.execute(testMethod, context);
// .. delete the testEntity from server ..
HttpPut method = new HttpPut("MY_REMOTE_URL");
InputStreamEntity entity = new InputStreamEntity(inputStream);
method.setEntity(entity);
client.execute(method, context);
It works, but it seems like a hack. Should I do this? Are there alternatives?
Upvotes: 2
Views: 3305
Reputation: 27583
Activate expect-continue
handshake instead.
HttpClientContext context = HttpClientContext.create();
RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build();
context.setRequestConfig(config);
Upvotes: 1