Failed to decode chunked response in webclient - java

I was trying to call a backend using webclient, which is "chunked" response. But, it appears StringDecoder failed to decode chunked response. As I can see following line logged
LN="o.s.c.c.StringDecoder" [3d736ae4] Decoded "?�????????�V�RPPPrO-?J-.��+NU�R220P(.MNN-.N+�Q�?+).I,)-�?�%�??)(y$??T*?$�d(��?)���(䦖d�(q�r??���}X???"
However, actual response from backend is plain json with following response header :
Content-Encoding : gzip
Vary : Accept-Encoding, User-Agent
Transfer-Encoding : chunked
Couldn't find any similar post on SO, which could point to handle chunked type response using webclient.
Code snippet of webclient part :
Mono<ResponseEntity<String>> response = client.get().uri(url)
.retrieve();
.onStatus(HttpStatus::isError, t -> Mono.empty())
.toEntity(String.class);

Related

after using Zuul as API Gateway, the downloaded image is being chunked and damaged and cannot be displayed. without Zuul, everything is fine. why?

I have microservice which is written with Spring Boot and I use Zuul as API Gateway.
in this microservice, I'm calling an external service which receive and get an image.
when I call that external service without Zuul being up, I receive the image correctly and I can open and see the image.
this is my code in my microservice which calls the external service:
#Override
public ResponseEntity<byte[]> getFile(String nodeId) {
String serviceUrl = this.path;
HttpHeaders headers = new HttpHeaders();
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add(Headers.NAME.value, this.name);
headers.add(Headers.PASSWORD.value, this.password);
HttpEntity<Void> requestEntity = new HttpEntity<>(headers);
return restTemplate
.exchange(serviceUrl, HttpMethod.GET, requestEntity, byte[].class);
}
this is the response that I received when I called the external service without zuul:
and this is the image which I receive:
every thing is fine until I start Zuul. after starting Zuul, now when I call that external service, I receive response like this (the colored boxes are those ones which are new in the response):
and the received file cannot be displayed and actually it is crashed and corrupted file:
after using Zuul, two things have been added to the response. Content-Type became image/jpeg;charset=UTF-8 AND there is no Content-Length in response anymore and instead, we have Transfer-Encoding with chunked value.
I removed the charset=UTF-8 with this code:
spring:
http:
encoding:
charset: utf-8
force: false
but the problem hasn't solved. so I guess that it might be related to Transfer-Encoding with chunked value.
what's wrong with this code? what should I do? why with using Zuul, the received image is damaged?
Thank you (sorry for my bad English)
Edit:
I added this line to my application.yml file:
zuul.set-content-length=true
and this is the response:
Transfer-Encoding with chunked value has been deleted and Content-Length has been added to headers BUT the file is still damaged and it took about 10 seconds (the timeout that has been specified in my application.yml for zuul- actually I changed that to 6 minutes and it take exactly 6 minutes and then result was same.) to download the image.

Send HTTP post with the given Request body and headers and get the respone

My question is that how i send http post to a server with request body and headers and get the response code and also get response content in String format
post url
http://192.168.1.2/default/en_US/sms_info.html?type=sms
request body
action:sms
send:send
line1:1
line2:1
line3:1
smscontent:im sending you this message from website
telnum:03459347900
headers
Origin:http://192.168.8.1
Upgrade-Insecure-Requests:1
Content-Type:application/x-www-form-urlencoded
Authorization:Basic YWRtaW46YWRtaW4=
Just use the Postman or any other HTTP client.

OData POST Response

I am giving request to OData POST in Json format and it's returning the same request to me.
POST URL= http://localhost:8085/MagicXpiOData/Odata_get.OData_1/Student_details
Body:
{"Division": "Nashik"}
Content-Type = application/json
Response:
{
"#odata.context": "$metadata#Student_details",
"Division": "Nashik"
}
Is this a correct response?
I think it should return a status code for success or not.
What you show above is the response body, which usually contains the OData.Context. Beside that you should find the HTTP Status Code in the header, which might be something like
HTTP/1.1 200 OK
HTTP/1.1 201 Created
and when you create a new entry also a location header.
Some examples that show typical requests and responses can be found in this Basic Tutorial
So generally your response looks ok. Maybe you can add the response header in your question, then we can see if everything is there what should be there.
When you send your request with a tool like Postman or Fiddler, you might by default only see the response body. To see the headers you need to switch to Headers, or Raw in Fiddler to see the full response (header and body).

Not able to fetch header data in rest assured for rest web service of type GET

I have GET REST API, which sends some information in response header.
I am writing test case using rest assured framework, issue I am facing is, in response of GET API, I am not getting header string set by the server in rest API response.
I have checked the same API in Rest client and HTTP Resource, there I can see the header information set by server in API response.
But in rest assured Response object, header information set by server is not available.
Rest API code:
#Path("/download")
#GET
#Produces("application/zip")
public Response downloadContractZipFile(#PathParam("contractId") final String contractId) throws CMException{
ContractActionRequest contractActionRequest = new ContractActionRequest();
contractActionRequest.setId(contractId);
DownloadActionResponse downloadActionResponse = (DownloadActionResponse) executeAction(Action.DOWNLOAD, contractActionRequest);
Response res = Response
.ok(downloadActionResponse.getFilestream(), MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition",downloadActionResponse.getContentDisposition())
.header("Expires", "0")
.header("Content-Length", String.valueOf(downloadActionResponse.getContentLength()) )
.build();
return res;
}
Above you can see, API is returning Content-Length in header. But when I am invoking above API using rest assured framework, it does not receive "Content-Length" in header. Assert is getting failed.
Rest assured Test case code:
given().get(propertyURI).then().assertThat().header("Content-Length","7562");
java.lang.AssertionError: Expected header "Content-Length" was not "7562", was "null". Headers are:
X-Powered-By=Servlet/3.0
Cache-Control=no-cache, no-store
Cache-directive=no-cache
Pragma=no-cache
Pragma-Directive=no-cache
Expires=Thu, 01 Jan 1970 00:00:00 GMT
Content-Type=text/html;charset=UTF-8
x-authenticated=false
x-location=https://reena:9453/app/login.jsp?targetApp=OM
Content-Language=en-US
Transfer-Encoding=chunked
I suggest you try Karate instead of REST-Assured as it has much better support for validating response headers.
(disclaimer: am Karate dev)

jersey : receive response from web-service as json file

nni have a problem calling a web service using jersey client.
I tried successfully as a test with : "http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%2248907%22&format=json"
using this code :
Client client = Client.create();
WebResource webResource = client.resource("http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%2248907%22&format=json");
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
String json = response.getEntity(String.class);
System.out.println(json);
but i can't do it when i call amazon webservice : http://ws.amazon.com/widgets/q?Operation=GetResults&Keywords=cool&SearchIndex=All&multipageStart=0&InstanceId=0&multipageCount=10&TemplateId=8002&ServiceVersion=20070822&MarketPlace=US
Is it because, I get a json file as response ?
Any help please ?
After experimenting with the Amazon web service with various form HTTP requests. I finally figured out that the problem is because of the User-Agent value sent in the HTTP Header.
For some reason, Amazon Rest Service is not able to handle the presence of period character . in the HTTP Header under User-Agent.
When sending a HTTP request with . as below
GET http://ws.amazon.com/widgets/q?Operation=GetResults&Keywords=cool&SearchIndex=All&multipageStart=0&InstanceId=0&multipageCount=10&TemplateId=8002&ServiceVersion=20070822&MarketPlace=US HTTP/1.1
User-Agent: Java.
Host: ws.amazon.com
Connection: keep-alive
Amazon WS sends a HTTP response without Body content
HTTP/1.1 200 OK
Date: Fri, 27 Sep 2013 19:29:54 GMT
Server: Server
Content-Length: 0
Vary: Accept-Encoding,User-Agent
Cneonction: close
Content-Type: text/plain
If the . is removed from the Content-Type, the response body does contain the detailed Json Content. This most likely looks like an issue on Amazon Rest Service implementation.
You can change the code as follows to see the Json content and get away with the problem
ClientResponse response = webResource.header("User-Agent", "SomeAgentNameWithoutPeriodChar").get(ClientResponse.class);

Categories

Resources