When using apache-httpclient-4.x's HttpClient class to process a URL that returns gzip compressed response, there's no "Content-Encoding" header in the response we get. However, if you visit the URL directly in the browser you can get the header.
It seems there's some step that deletes some headers while processing the compression.
https://github.com/apache/httpcomponents-client/blob/73e72f226845c790e4a6e6dccaed50ee32791f45/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java#L124
if (decoderFactory != null) {
response.setEntity(new DecompressingEntity(response.getEntity(), decoderFactory));
response.removeHeaders("Content-Length");
response.removeHeaders("Content-Encoding");
response.removeHeaders("Content-MD5");
}
How can we keep the headers?
Related
Im having problems on posting a multipart/formdata request to a REST api. The request returns an 400 Bad Request response.
This is how the request should look like. The link shows you a screenshot captured on a successful request by the web interface.
Successful request
This is the Java code I created.
public void importModel(String projectId, String modelId, MultipartFile file, String fileName) throws IOException {
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("data", file.getBytes(), MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "form-data; name=data; filename=" + fileName);
MultiValueMap<String, HttpEntity<?>> parts = builder.build();
WebClient webClient = WebClient.builder()
.filters(exchangeFilterFunctions -> {
exchangeFilterFunctions.add(logRequest());
exchangeFilterFunctions.add(logResponse());
})
.build();
String request = webClient.post()
.uri(getBaseUriBuilder()
.pathSegment(getTeamSlug())
.path(API_PATH_PROJECTS)
.pathSegment(projectId)
.path(API_PATH_MODEL)
.pathSegment(modelId)
.path("/importasync")
.build())
.contentType(MediaType.MULTIPART_FORM_DATA)
.contentLength(file.getSize())
.header(HttpHeaders.AUTHORIZATION, getPrefixedAuthToken())
.body(BodyInserters.fromMultipartData(parts))
.exchange()
.flatMap(FlatService::apply)
.block();
return;
}
Any help is much appreciated. Thank in advance!
Have you tried to send the request with alternative Software like POSTMAN.
There you can check for the request properties that are being sent with the request
a 400 error can occur due to the following issues with your request
Wrong URL: Same as 404-Error a Bad Request is generated, when the user types in a wrong internet address or he adds special chars to the address.
Error full Cookies: If the Cookie inside your browser is to old or broken it can also be a 400.
Old outdated DNS-Entries: In your DNS-Cache could lie files that point to wrong or outdated IP- addresses
Too big files: when you try to upload very large files, the server can deny the request.
Too long header lines: the communication between the client and server is done with header information about the request. some servers set a limit to the header length.
Also if you can find out the more specific 400 error like this:
400.1: Invalid Destination Header
400.2: Invalid Depth Header
400.3: Invalid If Header
400.4: Invalid Overwrite Header
400.5: Invalid Translate Header
400.6: Invalid Request Body
400.7: Invalid Content
400.8: Invalid Timeout
400.9: Invalid Lock Token
If you are not the server admin you could ask him about specifications of the server. or use tools like postman where you can try to send requests to the server and find out more specific error codes.
Using postman I am able to get response but the jersey API gives bad response as it is not setting the content length by default. below is my code part.
ClientResponse response = webResource.header("X-FeApi-Token", apiToken )
.header( "X-FeClient-Token",clientToken)
.header("Content-Type","multipart/form-data;boundary=----"+boundary+"----")
.header("Host","")
.header("Accept","application/json")
.post( ClientResponse.class,formData);
Postman tool has content-length header by default and they have mentioned like the value for the content length will be calculated while sending request. it gives success response.
Success Response When Content-Length is checked in postman
In jersey API, it is giving bad response even though there is content-length header added. jersey API gives bad response which is same as the response from postman when I uncheck the content length header.
Error Response When Content-Length is not checked in the postman
I'm trying to download a file with the Jersey client.
I'm requesting an API, and I don't have API source code.
For one URL, the API returns an empty "Content-Type" header (the header is present but empty).
Jersey does not like this:
Unable to parse "Content-Type" header value: ""
I'd like to keep the Jersey client if possible
Is an API supposed to return an empty content-type?
Is there any header I can add to my request that may solve the problem? I tried content-type and accept without success.
You can set the Content-Type header manually after you receive the response.
Response res = target.request().get();
res.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/octect-stream");
InputStream file = res.readEntity(InputStream.class);
I'm building a Jersey 2 client, which calls a service to get a file from the server.
The service returns binary file content as application/octet-stream
NOw, this is my code where I call the webservice
Response response = target.request().header(HttpHeaders.COOKIE, this.cookie)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM)
.accept(MediaType.APPLICATION_OCTET_STREAM).get();
I get a HTTP 200 Response. But i don't understand how I can get the file content from the response.
EDIT
The service documentation says "To GET the binary file content and the metadata, use header Accept: multipiart/mixed"
So, I tried the below
Response response = target.request()
.header(HttpHeaders.COOKIE, this.cookie)
.header(HttpHeaders.CONTENT_TYPE, "multipart/mixed")
.accept("multipart/mixed").get();
Even here, I get a HTTP status 200 response. But How do I read the file content??
Please help!!
Take a look at the documentation you will see that response has a readEntity method that you can use to read the inputstream:
InputStream in = response.readEntity(InputStream.class);
... // Read from the stream
in.close();
I need to check ETag from the header response of requesting URL.
I know that when request URL, then response will be html, css, js and images.
My issue: How to read header for all these resources including the html when requesting URL?
For HttpClient if you enter URL then it will give header and response only for html!! it didn't return the header for all loading resources which are involved with this URL and will be loaded associated with this URL.
if I request only css, then it will give me a right header response for this style.
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet("http://www.mkyong.com/wp-content/themes/mkyong/css/prism.css");
HttpResponse response = client.execute(request);
for (Header header : response.getHeaders("ETag"))
System.out.println(header.getName()+" == "+header.getValue());
but if I tried to but the main URL:http://www.mkyong.com, then it will give me only response for the main html
How to fetch them?