Length required 411: File upload using apache(4.3) HttpPost and MultipartEntityBuilder. - apache

I am using HttpClient 4.3.3. My task is to upload files onto a server.
Following is my code:
InputStream inputStream = new FileInputStream(new File("/path/to/file"));
byte[] data;
data = IOUtils.toByteArray(inputStream);
InputStreamBody inputStreamBody = new InputStreamBody(new ByteArrayInputStream(data),"file-name-on-ser");
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("file",inputStreamBody);
HttpPost httpPost = new HttpPost("file upload URL");
httpPost.setEntity(multipartEntity.build());
CloseableHttpResponse response = httpclient.execute(httpPost);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null)
{
System.out.println(line);
}
When I run this code it successfully connects to the server.But the the output of the response is
<html>
<head><title>411 Length Required</title></head>
<body bgcolor="white">
<center><h1>411 Length Required</h1></center>
<hr><center>server-name</center>
</body>
</html>
When I use firebug for debug, I see the following Request header.
Response Headersview source
Cache-Control no-store, no-cache
Connection keep-alive
Date Thu, 22 May 2014 08:58:02 GMT
Keep-Alive timeout=30
Server *****
Set-Cookie **** Path=/
Transfer-Encoding chunked
Request Headersview source
Accept text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Cookie ****
Host *****
Referer https://****/shareupload/
User-Agent Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
Request Headers From Upload Stream
Content-Length 12642
Content-Type multipart/form-data; boundary=---------------------------105143784893
I have seen similar questions on stack overflow.
1)411 Content-Length Required
2)File upload using apache's httpclient library not working
but still i am not able to find solution to my problem.
Do I need to set up the Content-Length and Content-Type parameter in request header?
Thank you in advance.

try like:
InputStreamBody inputStreamBody = new InputStreamBody(new ByteArrayInputStream(data),"file-name-on-ser"){
#Override
public long getContentLength(){return data.length();}
};

Related

Content-Type header property value quoting doesn't work with third-party server

Is it correct to quote the boundary property value of Content-Type header?
I have sent an http-request with two files to a third-party server and get the following response:
Boundary '--"38b14895-fd44-4acc-8287-9f0378691da2"' not found in message body
because RestSharp quotes the boundary value, but the server doesn't unquote it. I can neither change the third-party server nor customize RestSharp header quoting.
What is the problem? Does the http spec allow escaped strings in header property values? I've read the spec, but haven't found a place where this would be explicitly defined.
I create the RestRequest something like this:
private RestRequest CreateRequest( ... )
{
var request_url = $"url?param=value";
var request = new RestRequest( request_url, Method.Post );
request.AddFile( "file1", ..., "file1", "application/xml" );
request.AddFile( "file2", ..., "file2", "audio/x-wav" );
request.AddHeader( "Content-Type", "multipart/form-data" );
return request;
}
and get the following HTTP-request:
POST /url?param=value
Host: 192.168.1.1:80
Accept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml
User-Agent: RestSharp/108.0.1.0
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary="38b14895-fd44-4acc-8287-9f0378691da2"
Content-Length: 227841
--38b14895-fd44-4acc-8287-9f0378691da2
Content-Type: application/xml
Content-Disposition: form-data; name="file1"; filename="file1"
[data]
--38b14895-fd44-4acc-8287-9f0378691da2
Content-Type: audio/x-wav
Content-Disposition: form-data; name="file2"; filename="file2"
[data]
--38b14895-fd44-4acc-8287-9f0378691da2--
Okay so I have just been dealing with a very similar issue. I found this GitHub Issue which gives some good context into the actual issue that is occurring here but I have also found a fix.
Firstly, you shouldn't manually add the "Content-Type" header. RestSharp will do this for you since you are using the AddFile() method.
I am assuming you are using the latest version of RestSharp, if so you can set the request.OnBeforeRequest property of the RestRequest to handle this and strip out the double quotes around the boundary before the request is sent:
request.OnBeforeRequest = (http) =>
{
var boundary = http.Content.Headers.ContentType.Parameters.First(o => o.Name == "boundary");
boundary.Value = boundary.Value.Replace("\"", String.Empty);
return default;
};
Hope this helps!

Why does this REST request work from every client except Talend API tester

This is an example of a REST POST request that works everywhere except Talend API tester. It give a 500 error.
Here is how I set the request up in my applications.
URLConnection connection = new URL("https://" + authHost + "/connect/token").openConnection();
logger.info("Connection oppened");
// message contains the form data: key=value&key=value&key=value
String message = "password=" + password + "&grant_type=password&username=" + username +
"&client_id=foolid&scope=mouthwash";
logger.info(message);
// Setting header fields.
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept", "application/json");
connection.getOutputStream().write(message.getBytes("UTF-8"));
Here is a working example in Postman
POST /connect/token HTTP/1.1
Host: identityserver.uat.example.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Cookie: ARRAffinity=6a37d2ecf3441e27913cb832c4b767c68cad0e45c8806b3c5344d1b52d57f67a; ARRAffinitySameSite=6a37d2ecf3441e27913cb832c4b767c68cad0e45c8806b3c5344d1b52d57f67a
Content-Length: 137
password=secret&grant_type=password&username=fool&client_id=foolid&scope=mouthwash
And here is what Talend say it sends, which gets the 500 error -- which I understand comes from the server.
POST /connect/token HTTP/1.1
Accept: application/json
Content-Length: 137
Content-Type: application/x-www-form-urlencoded
Host: identityserver.uat.example.com
password=secret&grant_type=password&username=fool&client_id=foolid&scope=mouthwash
What's happening here?

how to set no content-type using apache httpclient

i am facing one issue on apache httpclient(the latest release)
i am using
builder.addPart("_sid", new StringBody("abcd"));
to build form part, but in server, the request info is:
Content-Disposition: form-data; name="_sid"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
i want the http client do not send the two lines:
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
is there any code could help me?
refer to In apache http client, how to keep the Content-Type in a StringBody as empty or null? , i get the key:
- FormBodyPart bodyPart = new FormBodyPart("_sid", new StringBody(sessionID, ContentType.DEFAULT_TEXT)) {
#Override
protected void generateContentType(ContentBody body) {
}
#Override
protected void generateTransferEncoding(final ContentBody body){
}
};

Setting REQUEST header Http Client vb.net

Consider the following VB code:
Public Async Function someFunction(ByVal url As String, Optional ByVal methodPost As Boolean = False, Optional ByVal postContent As HttpContent = Nothing) As Threading.Tasks.Task(Of String)
Using client = New HttpClient
client.DefaultRequestHeaders.Authorization = makeAuthenticationHeader()
If methodPost Then
client.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
Dim Response = Await client.PostAsync(url, postContent)
Dim content As String = Await Response.Content.ReadAsStringAsync
Return content
Else
Return Await client.GetStringAsync(url)
End If
End Using
End Function
I want to set the request content type to application/json as well as the response content type to application/json.
If I add the following line of code:
client.DefaultRequestHeaders.Add("content-type", "application/json") then the system throws an exception Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects..
I've searched all over google for a way to set the requests header to JSON. Using fiddler (on the server) I can see that the request is sent as plain/text.
POST **URL REMOVED FOR SAFETY REASONS** HTTP/1.1
Authorization: Basic **HASHED AUTH DETAILS - REMOVED FOR SAFETY REASONS**
Accept: application/json
Content-Type: text/plain; charset=utf-8
Host: **HOST REMOVED FOR SAFETY REASONS**
Content-Length: 1532
Expect: 100-continue
Connection: Keep-Alive
Content-Type: text/plain; charset=utf-8 This is where I am having an issue. This needs to be set to a content type for JSON as the body of the request is JSON. How do I set this content-type to JSON in vb.net Code.
I found a solution, I don't know if it is the correct solution or if there is a better solution out there.
Basically you need to set the content-type header on the actual content that you are sending and not on the HTTP Client.
So basically adding content.Headers.ContentType = New MediaTypeWithQualityHeaderValue("application/json") to your code should set the REQUEST's content-type to JSON as well.
Public Async Function someDifferentFunction() As Threading.Tasks.Task(Of String)
Dim url As String = "http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Dim content As HttpContent = New StringContent(txtRequestBody.Text)
content.Headers.ContentType = New MediaTypeWithQualityHeaderValue("application/json")
Return Await someFunction(url, True, content)
End Function

How can I replace the 'Accept' http header in AS3

all
I send a http request from flash client(AS3) to a RESTFull service. The server side response json or xml data depend on the 'Accept' parameter in http header. But, I always accept xml format data even if I set the 'Accept' to 'application/json' in the client side. With wireshark I found that there are double 'Accept' parameter in the http header. Can somebody tell me why ? And/or how to get out of this.
POST /psplatform/rest/szdata/all HTTP/1.1
Host: 203.175.156.88:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-type: application/json
Accept: application/json
Content-length: 8
public function reload():void{
data = new Object();
new URLLoader(createJSONURLRequest("http://203.175.156.88:8080/psplatform/rest/szdata/all")).addEventListener(Event.COMPLETE, loaderCompleteHandler);
}
private function createJSONURLRequest(url:String):URLRequest{
var urlRequest:URLRequest = new URLRequest(url);
urlRequest.method = URLRequestMethod.POST;
urlRequest.contentType = "application/json";
//var urlVariables:URLVariables = new URLVariables("{}");
urlRequest.data = "{name:0}";
urlRequest.requestHeaders.push(new URLRequestHeader("Accept", "application/json"));
return urlRequest;
}