Error 406 Not Acceptable when generating PNG response - java

I have a problem with method generating PNG image responses.
#RequestMapping(value = "/thumb/{id}.png", produces = "image/png")
#ResponseBody
public char[] thumb(#PathVariable UUID id)
{
// action logic here
return CatalogController.PLACEHOLDER_THUMB;
}
However I can't access this action - it is executed correctly (I see logic effects in database), but client gets 406 Not Acceptable.
Here is how I simulate the request (same happens in Chrome and Internet Explorer):
$ wget "http://localhost:8080/thumb/13164e6b-fc0f-4c67-a7d3-e2c56224384b.png" -O - --header="Accept: image/png"
--2013-11-18 18:37:30-- http://localhost:8080/thumb/13164e6b-fc0f-4c67-a7d3-e2c56224384b.png
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8080... connected.
HTTP request sent, awaiting response... 406 Not Acceptable
2013-11-18 18:37:30 ERROR 406: Not Acceptable.
Edit
Here is more detailed description displayed in browser:
description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ().

Ok, thanks for everyone for helping, but the answer is far more trivial - it's simply not possible to use char[] as response content.
Switched to byte[] and everything worked fine!
(probably could be possible to register handler for byte[] but it's not needed for me, so can't confirm that).

Related

HttpClientErrorException 406 null is thrown in rest template spring mvc [duplicate]

In my Ruby on Rails application I tried to upload an image through the POSTMAN REST client in Base64 format. When I POST the image I am getting a 406 Not Acceptable Response. When I checked my database, the image was there and was successfully saved.
What is the reason for this error, is there anything I need to specify in my header?
My request:
URL --- http://localhost:3000/exercises.json
Header:
Content-Type - application/json
Raw data:
{
"exercise": {
"subbodypart_ids": [
"1",
"2"
],
"name": "Exercise14"
},
"image_file_name": "Pressurebar Above.jpg",
"image":"******base64 Format*******"
}
Your operation did not fail.
Your backend service is saying that the response type it is returning is not provided in the Accept HTTP header in your Client request.
Ref: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
Find out the response (content type) returned by Service.
Provide this (content type) in your request Accept header.
http://en.wikipedia.org/wiki/HTTP_status_code -> 406
406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not
acceptable according to the accept headers sent in the request.
406 happens when the server cannot respond with the accept-header specified in the request.
In your case it seems application/json for the response may not be acceptable to the server.
You mentioned you're using Ruby on Rails as a backend. You didn't post the code for the relevant method, but my guess is that it looks something like this:
def create
post = Post.create params[:post]
respond_to do |format|
format.json { render :json => post }
end
end
Change it to:
def create
post = Post.create params[:post])
render :json => post
end
And it will solve your problem. It worked for me :)
"Sometimes" this can mean that the server had an internal error, and wanted to respond with an error message (ex: 500 with JSON payload) but since the request headers didn't say it accepted JSON, it returns a 406 instead. Go figure. (in this case: spring boot webapp).
In which case, your operation did fail. But the failure message was obscured by another.
You can also receive a 406 response when invalid cookies are stored or referenced in the browser - for example, when running a Rails server in Dev mode locally.
If you happened to run two different projects on the same port, the browser might reference a cookie from a different localhost session.
This has happened to me...tripped me up for a minute. Looking in browser > Developer Mode > Network showed it.
const request = require('request');
const headers = {
'Accept': '*/*',
'User-Agent': 'request',
};
const options = {
url: "https://example.com/users/6",
headers: headers
};
request.get(options, (error, response, body) => {
console.log(response.body);
});
Changing header to Accept: */* resolved my issue and make sure you don't have any other Accept Header
In my case, I added:
Content-Type: application/x-www-form-urlencoded
solved my problem completely.
If you are using 'request.js' you might use the following:
var options = {
url: 'localhost',
method: 'GET',
headers:{
Accept: '*/*'
}
}
request(options, function (error, response, body) {
...
})
In my case for a API in .NET-Core, the api is set to work with XML (by default is set to response with JSON), so I add this annotation in my Controller :
[Produces("application/xml")]
public class MyController : ControllerBase {...}
Thank you for putting me on the path !
It could also be due to a firewall blocking the request. In my case the request payload contained string properties - "like %abc%" and ampersand symbol "&" - which caused the firewall to think it is a security risk (eg. a sql injection attack) and it blocked the request. Note here the request does not actually go to the server but is returned at the firewall level itself.
In my case, there were no application server logs generated so I knew that the request did not actually reach the server and was blocked before that. The logs that helped me were Web application firewall (WAF) logs.

HTTP 405 - Method Not Allowed error on a 200 OK response

I have a small REST-ful Java back-end that some clients written in C connect to. There is a certain POST method they call where they send some information, I save that to a database and respond with 200 OK, if all goes well. Basic structure shown below.
#POST
#Path("/mypath")
#Produces("text/html")
public Response processMessage(final String message, #Context final HttpServletRequest request) throws IOException {
.....
return Response.ok().build();
}
My issue is that on this response, I get the following error in the log:
javax.ws.rs.NotAllowedException: No resource method found for , return 405 with Allow header
I understand what this error means in circumstances when let's say you try to execute a GET on an endpoint that is supposed to be a POST, for example. I can't understand though why I would get this after my response goes out, and it clearly shows that the request type is empty.... so odd.
Some additional info - the code on the client side has been buggy with incorrect HTTP code... but what would have to be wrong on the client side to cause this kind of response? (I do not have access to the client side code).
Also, there is no client side code in my app, if you are wondering if there is some other code making a call out of my webapp.
Thanks for any ideas!
The issue is most likely on the client side, so without seeing that code it is difficult to offer more detailed information -- but my expectation would be that this is a result of your client attempting to do something like POST or PUT credentials, or something along that line.
Your only recourse is to enable verbose request logging, log the requests that are generating 405 errors, and report it to the client developers.
Worth noting, however, that any publicly-exposed APIs will generate piles of 405s and 404s because "hackers" will try to execute things like WordPress hacks and so on against any known URL.

How to do a server side HTTP redirection instead of a meta refresh

According to W3 Meta refresh is discouraged and they recommend Server side redirection. So my question is how am I supposed to do that in HTTPServer?
The API does not provide any redirection method here:
http://docs.oracle.com/javase/7/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/HttpServer.html
If this "redirection" is not that abstract thing, then what would be the idea behind that?
What the W3 means when is says this, is that instead of your HTTP server returning a status-code of 200 (OK) with a response body that has HTML with a
<META HTTP-EQUIV=REFRESH CONTENT="1; URL=http://www.example.org/bar">
you have your HTTP server return a suitable 3xx (redirect) status code, with a Location header that gives the location to be redirected to.
The most suitable status code would be 302 (Found) if you still expect people to use the original URL as an alias for the URL being redirected too (the HTTP standard says "the client SHOULD continue to use the Request-URI for future requests").
If you want users to stop using the original URL the most suitable status code would be 301 (Moved Permanently).

Jersey Response.seeOther() not giving HTTP 303 status code

I have a social networking site in which we have a restricted community.
When a guest user applies requests for membership, a membership request is generated. I am performing this task through a REST API.
I am using RESTClient plugin in firefox to send requests.
When I send a POST resquest for adding self to the restricted community, the response is the memebership request generated for the same. Hence, the underlying HTTP status code is 303 See Other POST/GET.
I get proper response for the same with the membership request in response but the status code is 200 OK(which I think is the code for the GET on the membership request).
But, I need the same to be 303. I have tried debugging also. My finding is that the Jersey Response.seeOther() is not returning 303.
Please help.
The code snippets are as follows :
addUserToCommunity method :
MembershipRequestModel membershipRequest = null;
membershipRequest = communityService.addUserToCommunity(communityId, userId);
if(membershipRequest != null) {
// Add code 303 if returning membershiprequest
return seeOther( membershipRequest,
String.valueOf(membershipRequest.getId()),
MembershipRequestRestHandlerImpl.class);
} else {
return ok(null);
}
seeOther method which in turn calls Response.seeOther() :
public Response seeOther(Object model, String id, Class<?> resource){
URI location = buildLocation(resource, id);
return Response.seeOther(location).entity(createResponseItems(model)).build();
}
303 - See Other is essentially a redirect - browser would automatically follow the URL provided in location header. Are you sure this is not what you see? I.e. maybe the firefox plugin you are using is simply following the redirect (behind the scenes) and returning the result of a GET method on that location URL. Try FireBug which shows you exact requests that went on the wire - you should be able to see the redirect there.
If you want to geht the 303 instead of the 200 Response:
httpClient.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, false);
The redirect URL ist in the Location: header
This is actually a problem with RESTClient i.e; the browser as Martin says.
The browser actually performs the redirect and does not give 303.
Instead try hitting the URI using cURL in the shell or using puTTY. It works fine.
Thank you.

Does the server send response only when its HTTP 200?

im writing a java application that sends a post request to a server and expect a json from the server. Now when i need to get the response from the server do i only need to get it from the inputStream when the http code is 200 (HTTP OK) or is there any other cases ? , example :
//...
if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
// only here try to get the response
}
//...
It depends on how the server is implemented. Check the API, if the server has one. If it's internal, ask your server guy.
Generally speaking, if your response code is either 2xx or 3xx, I would check the response anyway...
If the server your communicating with is following the spec then either 200 or 201 responses are valid to contain an entity. A 204 response is successful but has no data in the response.
See section 9.5 here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 for details of acceptable responses to a POST. Extract below:
The action performed by the POST method might not result in a resource
that can be identified by a URI. In this case, either 200 (OK) or 204
(No Content) is the appropriate response status, depending on whether
or not the response includes an entity that describes the result.
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30).
There are three things to consider:
All 2xx codes denote success of some sort. But depending on the exact code, your reading code might be different. (204 for example means success but no content.)
There are redirecting codes (3xx). These are usually automatically followed by the http client library but you can also set them not to, in which case you need to have custom code that handles these cases.
There can be valuable information returned in the stream even if you get a code that denotes an error. Whether you want to process it depends on your exact needs.

Categories

Resources