how to set no content-type using apache httpclient - apache

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

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!

Correctly perform the DELETE with RestSharp

Till now I've used RestSharp to perform POST/GET passing a JSON payload as parameter/body.
Now I've to perform a delete (you can see the example form documentation just here)
DELETE https://api.xxx.it/shipment
HTTP/1.1 Accept-Encoding: gzip,deflate
Content-Type: application/x-www-form-urlencoded
X-API-KEY: APIKEY123456789
Content-Length: 10 Host: api.xxx.it
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
id=1234567
and my code below.
public Task PerformShipmentDeleteAsync(ShipmentDeleteRequest objectRequest)
{
var client = new RestClient(settingsService.Endpoint);
var request = new RestRequest("shipment", DataFormat.Json);
request.AddHeader(Constants.XApiKey, settingsService.ApiXKey);
request.AddParameter( "text/plain",$"id={objectRequest.Id}", ParameterType.RequestBody);
var res = client.Delete(request);
return Task.CompletedTask;
}
and ShipmentDeleteRequest.cs
public class ShipmentDeleteRequest
{
[JsonProperty("id")]
public int Id { get;set; }
}
The only way I've found is to format the string in this way, but It's a hack.
How do I correctly pass the body as the example without passing a string but just the C# object?

.net core web api upload file fail with badrequest

I am trying to upload several files to a web api endpoint with .net core 2.1 web api
this is my controller and the method to upload
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class PagosController : ControllerBase{
[HttpPost("UploadDescuento")]
public async Task<IActionResult> UploadDescuento(IEnumerable<IFormFile> files)
{
return Ok();
}
}
with postman i made a request to de controller but i am getting a badrequest
the first time I thought my request is bad so i do the same request in postman
POST /api/pagos/UploadDescuento HTTP/1.1
Host: localhost:59039
User-Agent: PostmanRuntime/7.16.3
Accept: */*
Cache-Control: no-cache
Postman-Token: 7535f283-89fb-4f86-bbb9-3d78ec302ebe,19a709dd-37c9-48ef-a157-c21f99861260
Host: localhost:59039
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Accept-Encoding: gzip, deflate
Content-Length: 1320022
Connection: keep-alive
cache-control: no-cache
Content-Disposition: form-data; name="files"; filename="/C:/Users/jcpc9/Pictures/0-5616x3744.jpg
------WebKitFormBoundary7MA4YWxkTrZu0gW--,
Content-Disposition: form-data; name="files"; filename="/C:/Users/jcpc9/Pictures/0-5616x3744.jpg
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="files"; filename="/C:/Users/jcpc9/Pictures/101-2621x1747.jpg
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="pago"
234235834
------WebKitFormBoundary7MA4YWxkTrZu0gW--
but im getting badrequest
{
"": [
"The input was not valid."
]
}
my solution was remove de attribute ApiController i dont know why the documentation doesnt say to much [https://learn.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-2.2#multipartform-data-request-inference] i dont understend what is the problem
[Produces("application/json")]
[Route("api/[controller]")]
//[ApiController]<<remove this
public class PagosController : ControllerBase
and the method
[HttpPost("UploadDescuento")]
public async Task<IActionResult> UploadDescuento(IEnumerable<IFormFile> files)
if someone know why this propertie "[ApiController]" causing this problema i hope you can explain or at leas an good article
You're not uploading the file. You're just sending the path of the file on the client machine, which the server can't do anything with (unless the server and client machines will always be the same).
Postman does have the option of sending a file properly. See this answer.
You need to select form-data in the body in postman and set up a key "files" as file type example

Why does alps (or profile) path in spring-data-rest return json body with non matching header Content-Type: text/html?

Right now the default Content-Type of my spring-data-rest (spring-boot 1.4.3.RELEASE) provided controllers are application/hal+json which makes sense. If I use chrome I get application/hal+json for the root of my application for instance since chrome uses an Accept header of "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8". However, the /profile (formally /alps) URLs provide text/html even though the response body is json (making the Content-Type not match the body). If you specifically ask for only application/json then you get the correct response header.
Here is the incorrectly working case (returns text/html when the document/body returned is NOT text/html):
$ http --verbose "http://localhost:8080/v1/profile/eldEvents" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
GET /v1/profile/eldEvents HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/0.9.2
HTTP/1.1 200
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Location, X-Auth, Authorization
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html;charset=UTF-8
Date: Fri, 03 Feb 2017 01:16:14 GMT
Expires: 0
Pragma: no-cache
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Transfer-Encoding: chunked
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
{
"alps" : {
"version" : "1.0",
"descriptors" : [ {
"id" : "eldEvent-representation",
"href" : "http://localhost:8080/v1/profile/eldEvents",
"descriptors" : [ {
"name" : "sequenceId",
"type" : "SEMANTIC"
}, {
...
Cut out the rest of the response, you can see from above it is json data.
I believe the correct Content-Type for the above request should be something similar to "application/json".
If this is still relevant for you: I've solved this by manually overriding all requests against /profile/* with no content-type defined.
#Component
public class ProfileContentTypeFilter extends OncePerRequestFilter
{
private static final AntPathMatcher matcher = new AntPathMatcher();
#Override
protected void doFilterInternal (HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException
{
if (request.getContentType() == null && matcher.match("/profile/*", request.getRequestURI()))
{
// Override response content type for unspecified requests on profile endpoints
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
}
filterChain.doFilter(request, response);
}
}

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

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