AsyncHttpClient sets content-type inconsistently - java

I use AsyncHttpClient to create an http POST request:
AsyncHttpClient.BoundRequestBuilder reqBuilder;
reqBuilder = httpClient.preparePost(url);
reqBuilder.setBody(data);
It sometimes doesn't send content-type header and sometimes sends it as
Content-Type: text/html; charset=ISO-8859-1
which causes our request to fail at [REST API] server side.
I am at a loss to understand why it is inconsistent.
Client is created as below:
import com.ning.http.client.*;
AsyncHttpClient httpClient = new AsyncHttpClient(
new AsyncHttpClientConfig.Builder().build());

You can set headers by your self
reqBuilder.setHeader(String name, String value);
or add
reqBuilder.addHeader(String name, String value);

Related

apache cxf MultiPart request has no Content-Length header

I'm having below code to send a multipart/form-data request.
List<Attachment> multipartData = new ArrayList<>();
ContentDisposition cd1 = new ContentDisposition("form-data; name=\"file\";
filename="+fileObj.getName());
FileInputStream inputStream = new FileInputStream(fileObj);
multipartData.add(new Attachment("file",inputStream, cd1));
MultipartBody multipart = new MultipartBody(multipartData);
In my RestClient class, I'm using the below lines of code to send a POST request using JAX-RS Client object
if ("POST".equals(method)) {
response = this.client.getBuilder().post(Entity.entity(entity,MediaType.MULTIPART_FORM_DATA));
I checked the HTTP request body using Wiremock and is as below:
Transfer-Encoding: [chunked]
Accept: [*/*]
Cache-Control: [no-cache]
User-Agent: [Apache-CXF/3.2.5]
Connection: [keep-alive]
Host: [127.0.0.1:9990]
Pragma: [no-cache]
Content-Type: [multipart/form-data; boundary="uuid:04b491f5-50de-4f4f-b7c0-cd745136d3d1"]
--uuid:04b491f5-50de-4f4f-b7c0-cd745136d3d1
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <file>
Content-Disposition: form-data; name="file"; filename=sample.txt
<File content goes here>
I want to know how the content-length header is missing in the request payload. Is there any way to set the content-length header to the request?
Please help me.
I used the apache cxf WebClient to unset the transfer encoding as chunked.
if ("POST".equals(method)) {
Invocation.Builder builder = this.client.getBuilder();
WebClient.getConfig(builder).getHttpConduit().getClient().setAllowChunking(false);
response = builder.post(Entity.entity(entity,MediaType.MULTIPART_FORM_DATA));
}
With this, the client is able to send the request with content-length header.

Resteasy always get application/json content type on request

I have a web application that use Angularjs on frontend och Resteasy + Jackson on the back end. I'm sending a file from Angular component to a REST method, receiving method looks like this :
#POST
#Path("/upload/attachment/for/{eventId}")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(MultipartFormDataInput input,
final #PathParam("eventId") Long eventId,
#Context HttpServletRequest request) {
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
...my awesome stuff...
return Response.ok().build();
}
And request has following headers when sent :
Accept application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length 347085
Content-Type multipart/form-data; boundary=---------------------------12164806981346771846716776342
Cookie JSESSIONID=aoBd1hgzR3GM8bSG5P-9g-vQ; csrftoken=ziQ7kN7TlMehR2aURDrmaMLYAroMsSpu
Host localhost:9000
Referer http://localhost:9000/local/myapp/index.html
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:32.0) Gecko/20100101 Firefox/32.0
The problem is that THIS request ALWAYS has application/json as a Content-Type instead for multipart/form-data as it says in the headers. And I get :
20:12:00,490 WARN [org.jboss.resteasy.core.SynchronousDispatcher] (http-/127.0.0.1:8080-2) Failed executing POST /events/upload/attachment/for/null: org.jboss.resteasy.spi.UnsupportedMediaTypeException: Cannot consume content type
Already in HttpServletDispatcher the content is wrong.
I can't get if this is JBOSS that set Content-Type to wrong value or some thing else.
Ok, it was that I have an extra layer between angular and server which runs on Node.js and it just tunel requests to the server. I had to add following :
var r = null;
r = request.put({uri: url, json: inReq.body, headers: inReq.headers, form: inReq.form});
inReq.pipe(r).pipe(inRes);
This set all the headers from outgoing request and tunnel the request
Now I have right content-type

Jersey Client set content-type header as text/plain

Using jersey client sending HTTP request. Content-Type header is automatically set as "application/json" (as a nature), but i want to changing "content-type" header with "text/plain" regardless of any specification, standards etc. Jersey version is 2.4.1.
Code
String target = "http://192.168.1.2:10000";
String path = "test3";
Client c = ClientBuilder.newClient ();
WebTarget target = c.target (target).path (path);
Entity<SubscriberBean> json = Entity.json (subscriber);
Builder request = target.request ();
String response = request.post(json, String.class);
Request
POST /test3 HTTP/1.1
Accept: text/html
Content-Type: application/json
User-Agent: Jersey/2.4.1 (HttpUrlConnection 1.6.0_17)
Host: 192.168.1.2:10000
Connection: keep-alive
Content-Length: 278
///**** Some json data ***///
instead of
request.post(json, String.class);
try to use
request.type(MediaType.TEXT_PLAIN).post(json, String.class);
Use Entity.text(entityData) or Entity.entity(entityData, mediaType) methods instead of Entity.json() in your example.

Multipart JSON POST request

please read my post:
I need to post the image to the JSON WS with this parameters:
Content-Type: multipart/related; boundary="foo_bar_baz"
Content-Length: {number_of_bytes_in_entire_request_body} -- Check your rest client API's. Some would automatically determine content-length at runtime. Eg. jersey client api.
--foo_bar_baz
Content-Type: application/json;
{
"filename": "cloudx.jpg"
}
--foo_bar_baz
Content-Type: image/jpeg
{JPEG data}
--foo_bar_baz--
I'm building Android application and I need to write the request to send the image to the above WS. I was looking around for some time and I didn't found good resource to study this issue I have.
following may give you basic idea
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(<URI>);
HttpEntity entity = new FileEntity(file,ContentType.MULTIPART_FORM_DATA);
//there are other types of entities and content types too check documentation
req.setEntity(entity);
HttpResponse response = httpClient.execute(req);

Is Jakarta HttpClient sutitable for the following task?

I try to talk to a server, by telneting to it, and send the following command through telnet terminal :
POST /%5bvUpJYKw4QvGRMBmhATUxRwv4JrU9aDnwNEuangVyy6OuHxi2YiY=%5dImage? HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 164
[SORT]=0,1,0,10,5,0,KL,0&[FIELD]=33,38,51,58,68,88,78,98,99,101,56,57,69,70,71,72,89,90,91,92,59,60,61,62,79,80,81,82&[LIST]=1155.KL,1295.KL,7191.KL,0097.KL,2267.KL
This works very fine. Now, I wish I can use HttpClient, to talk to the server, as I use telnet to talk to the server. The reason I wish to use HttpClient, instead of using raw TCP socket, is because HttpClient does support NTLM.
However, when I use POST method with NameValuePair :
new NameValuePair("[SORT]", "0,1,0,10,5,0,KL,0")
The request will become URL encoded. The server doesn't understand URL encoded request.
%5BSORT%5D: 0%2C1%2C0%2C10%2C5%2C0%2CKL%2C0
Is there any way I can avoid this? If not, what is the alternative library I can use? I wish to support NTLM as well.
As I mentioned in the other thread, this is not even valid HTTP POST. So you can't do it with default post mechanism in HttpClient. You need to make the invalid body yourself and post it.
Assuming you are using HttpClient 3, following code should work,
HttpClient httpClient = new HttpClient();
PostMethod method = new PostMethod(url);
String badFormPost = "[SORT]=0,1,0,10,5,0,KL,0&[FIELD]=33,38,51,58,68,88,78,98,99,101,56,57,69,70,71,72,89,90,91,92,59,60,61,62,79,80,81,82&[LIST]=1155.KL,1295.KL,7191.KL,0097.KL,2267.KL";
RequestEntity entity = new StringRequestEntity(badFormPost,
"application/x-www-form-urlencoded", "UTF-8");
method.setRequestEntity(entity);
method.setContentChunked(false);
httpClient.executeMethod(method);
...
It's getting URL encoded because your request formed with HTTPClient may be a GET request instead of a POST and is missing this header:
Content-Type: application/x-www-form-urlencoded
Look for the HTTPClient setting to set the Content-Type header correctly and make sure your request is a POST, not a get and you should be golden.

Categories