I am using standalone jetty application as reverse proxy, While sending a request to a service directly without using reverse proxy application, I get the following response headers with the response.
Content-Type →application/xml
Transfer-Encoding →chunked
Server →Jetty(9.3.8.v20160314)
When sending the same request using reverse proxy application, I get the following response headers with the response
Date →Fri, 04 Jan 2019 08:12:41 GMT
Content-Type →application/xml
Server →Jetty(9.3.8.v20160314)
Content-Length →460
The problem is that I get content-length header here instead of Transfer-Encoding. So whether reverse proxy does not send the response chunked or it stores the entire response and forwards it entirely.
Related
I have a REST API which ONLY #Produces(MediaType.APPLICATION_JSON) and does not #Consume any MediaType.
Even still when I am consuming this REST API by creating an HTTP Request where MediaType is being set to multipart/form-data, I am still recieving:
HTTP/1.1 415 Unsupported Media Type
in raw HTTP Response.
However, when I am setting Content-Type to application/json, which this REST API #Produces, I am getting a proper HTTP Response.
Below is the REST API Annotations:
#POST
#Path("/somePath")
#Produces(MediaType.APPLICATION_JSON)
public JSONObject addDocument(AddDocBean addDocBean) {
...
"Now why do I want to send Content-Type as Multipart/form-data?"
That is because I am using this service to upload a file to the server and the file is to be sent in a BASE64 format.
Now the size of file is about 20Mb which I have been suggested is better sent as multipart/form-data
But HTTP server is unable to process this request returning ERROR 415 Unsupported MediaType in response.
REST client being used : SoapUI 5.4.0
What could possibly be wrong?
#Produces on Server Side corresponds to Accept: Header on the Client Side.
#Consume on Server Side corresponds to Media-Type: Header on the Client Side.
The API snippet you showed doesn't specify any explicit #Consume annotation and hence defaults to plain/text. And hence when you send the Header of application/multipart with your request you get Unsupported Media Type
You need to add an explicit
#Consume("MediaType.MULTIPART_FORM_DATA") // something similiar to this over your API to make your addDocument() method to support the form data that you are sending.
I work on a REST-like API that will support bulk operations on some resources. As it may take some time to finish such a request, I would like to return statuses of the operations in a chunked response. The media type should be JSON. How to do it with JAX-RS?
(I know that there is StreamingOutput, but it needs to manually serialize the data.)
Chunked Transfer encoding is usually used in cases where the content length is unknown when the sender starts transmitting the data. The receiver can handle each chunk while the server is still producing new ones.
This implies the the server is sending the whole time. I don't think that it makes too much sense to send I'm still working|I'm still working|I'm still working| in chunks and as far as I know chunked transfer-encoding is handled transparently by most application servers. They switch automatically when the response is bigger then a certain size.
A common pattern for your use case looks like this:
The client triggers a bulk operation:
POST /batch-jobs HTTP/1.1
The server creates a resource which describes the status of the job and returns the URI in the Location header:
HTTP/1.1 202 Accepted
Location: /batch-jobs/stats/4711
The client checks this resource and receives a 200:
GET /batch-jobs/stats/4711 HTTP/1.1
This example uses JSON but you could also return plain text or add caching headers which tell the client how long he should wait for the next poll.
HTTP/1.1 200 OK
Content-Type: application/json
{ "status" : "running", "nextAttempt" : "3000ms" }
If the job is done the server should answer with a 303 and the URI of the resource he has created:
HTTP/1.1 303 See other
Location: /batch-jobs/4711
I'm building a server using JAX-RS (RESTEasy) that will provide a REST interface to clients. The server will act as a broker between the client and another server. The other server, a 3rd-party server (JasperReports), also has a REST interface. I'd like to use JAX-RS to have my broker talk to that server. (My broker server adds authentication and other services.) So, there you have the three parties: client, broker-server, reports-server.
I see the workflow this way. The broker-server implements JAX-RS (server) to get the client's requests, repackage them, and pass them along to the reports-server, using JAX-RS (client). When the broker-server has obtained a report, I'd like to relay that back to the client. But, so far, I believe that's where things break down.
Here's some code:
// Server gets a request and passes it to its (internal) client, handler.
#GET
#Path("/jobs")
public Response fetchAllScheduledJobs() {
ReportScheduleHandler handler = new ReportScheduleHandler();
Response response = handler.fetchAllScheduledJobs();
return response;
}
Here is the handler sending that off to the reports-server...
public Response fetchAllScheduledJobs() {
Client client = ClientBuilder.newClient();
client.register(getBasicAuthentication());
Response response =
client.target(getReportsBaseUri())
.request()
.accept("application/json")
.get();
client.close();
return response;
}
So, in my (misguided) thinking, I'm thinking that the broker-server just returns the response back to the client, and all is well. But, as I said above, the client is getting nothing back. I'm using a REST developer's client ("Postman"), and here are the headers I'm getting back:
Cache-Control →private
Content-Length →0
Content-Type →application/json
Date →Mon, 14 Jul 2014 16:05:46 GMT
Expires →Wed, 31 Dec 1969 19:00:00 EST
P3P →CP="ALL"
Server →Apache-Coyote/1.1
Transfer-Encoding →chunked
(Copied and pasted, it looks just like that. I have no idea why Postman shows these arrows!)
Any idea what I'm missing here? Does the broker need to somehow unpack the Response it receives from its internal client and repackage that before returning it to the original client? Please ask any questions you need for clarification. Thanks!
Edit
Wait! Could it be that my Response has an input stream and that I need to read that and write out and output stream to the client -- or something like that?
You're closing your client, therefore not unwrapping the Response in an open client context. Unwrap your response, close the client, and return your unwrapped object.
edit:
Sorry, not your client. I believe in the Response object you've got a close() method.
Pretty much like this:
Client client = ClientFactory.newClient();
WebTarget target = client.target("http://foo.com/resource");
Response response = target.request().get();
String value = response.readEntity(String.class);
response.close(); // You should close connections!
return value;
How can I override in Tomcat 7 the text of the HttpStatus.
I'm using HttpServletResponse.sendError(401, "Invalid username or Password"), but when I'm looking at the response status in the client it goves 401 Unauthorized.
Is there any way to override it?
Tomcat no longer supports USE_CUSTOM_STATUS_MSG_IN_HEADER property.
Changelog from 8.5.0:
RFC 7230 states that clients should ignore reason phrases in HTTP/1.1
response messages. Since the reason phrase is optional, Tomcat no
longer sends it. As a result the system property
org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER is no longer used
and has been removed. (markt)
RFC 7230, Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing, June 2014. Section 3.1.2:
The reason-phrase element exists for the sole purpose of providing
a textual description associated with the numeric status code,
mostly out of deference to earlier Internet application protocols
that were more frequently used with interactive text clients. A
client SHOULD ignore the reason-phrase content.
Edit catalina.properties and add the property:
org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER=true
With that set in my dev environment, then when I do:
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"A very very very bad request");
I see:
HTTP/1.1 400 A very very very bad request
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1024
Date: Fri, 20 Dec 2013 11:09:54 GMT
Connection: close
Also discussed here and here
No - the response codes are set according to RFC 2616. If you want to communicate a message to the user (to the API client) either write it in the body or in a response header
I am making an HttpGet to an url and I do not want the server to send the data gzipped. What header should I include in my HttpGet ?
With the default headers, the server sends gzipped data from time to time. I don't want this to happen. Thanks.
You want the Accept-Encoding HTTP request header.
Update: per #Selvin's comment, leave it empty or set it to "identity".
Update: The web application has to cooperate properly to be HTTP compliant, of course. If it's not honoring Accept-Encoding, look at its Content-Encoding HTTP response header. If it's "gzip", just read the response body with Java's GZIPInputStream.html. Then add "gzip" to your Accept-Encoding request header, since your client now handles GZIP. If the web application doesn't set the Content-Encoding header properly, that's another story altogether.
You should set the Accept-Encoding header to identity.
You could try to change the Accept-Encoding header, by removing the gzip|deflate value. If this doesn't work, you should also take into account that server doesn't care if the client supports the gzipped content (which is a bug and should be fixed).