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

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.

Related

java httpServer Post request work

I'm start learning java programming, and I want make a simple server application. I read about com.sun.net.httpserver.HttpServer and find a good example on this link: https://github.com/imetaxas/score-board-httpserver-corejava.
I understand how to do Get-request in url, but I don't know how POST works. I think it must be sent a form or data on the server.
I attach the link of project, which I'm learning, in readme the author wrote http://localhost:8081/2/score?sessionkey=UICSNDK - it's not working...
I wrote in url and get sessionkey: "localhost:8081/4711/login --> UICSNDK"
I wrote in url this for Post request: "localhost:8081/2/score?sessionkey=UICSNDK" - not working and in chrome return 404 bad request
3.wrote in url this:"localhost:8081/2/highscorelist"
Please help me, I am beginner.
The difference between GET and POST is that with a GET request the data you wish to pass to the endpoint is done by modifying the url itself by adding parameters to it.
With a POST any data you wish to send to the endpoint must be in the body of the request.
The body of a request is arbitrary data that comes after a blank line in the header The reqiest has the request line, following by any number of header attributes, then a blank line.
The server would need to know what the format of the body of the request was and parse it as appropriate.
Of course 'modern' frameworks like jax-rs allow you to automatically convert request data to objects, so that it is much simpler.

How to correctly deliver errors from a RESTful API?

I am referring to this project on Github. So this is supposed to be a RESTful API for managing a movie rental service. I mean it technically "works" right now, but one of the things it will do is deliver the error messages directly to the client from the internal methods.
Take this code for example:
/*
GET films
*/
get("/films", (req, res) -> {
try {
String json_output = get_film_list();
return json_output;
} catch (Exception e) {
return "{\"error\":\"There was an error: " + e.toString().replace("\"","") + "\"}";
}
});
And we have the get_film_list() method:
public static String get_film_list() throws SQLException, URISyntaxException{
Connection connection = ConnectionPool.getDBCP2Connection();
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM films");
String output = "{\"films\":[";
int got_result = 0;
while (rs.next()) {
output += "{\"id\":\""+rs.getInt(1)+"\",\"name\":\""+rs.getString(2)+"\",\"type\":\""+rs.getInt(3)+"\"},";
got_result = 1;
}
rs.close();
stmt.close();
output = output.substring(0, output.length()-1) + "]}";
if (got_result == 1){
return output;
}else{
throw new SQLException("No films.");
}
}
So the errors are delivered to the user via the API. I found this pretty convenient for development. I knew that if the server response contains the error property then there was an error, and it supplies the error message. I have heard through code review that this is not the way to do this at all. I also suspect that perhaps you're supposed to give formal HTTP errors or something. But at the same time I figured I would want my api to always return nice JSON formatted strings.
When a user hasn't authenticated, they will see this:
{"error":"Please Authenticate."}
I created an error in the DB connection class, and the user would see this:
{"error":"There was an error: java.sql.SQLException: Cannot load JDBC
driver class 'org.postgresql.Drive'"}
So, my question comes down to, what is the proper way to return error messages to the users with a RESTful API. One of this sort which uses returns JSON data.
Thanks!
RESTful services are based on 2 things, the response code and the actual response itself.
Well, basically it boils down to what error you want to handle. This particular scenario means no data being found and you would find different ways of handling this scenario. Any other error conditions would be handled differently
The 2 approaches to handling this error are
Scenario 1:
Response Code: 200 OK
Response: {}
which means that there was no data for the request specified(more so the parameters supplied with the request)
Scenario 2:
Response Code: 404 Not Found
Response: {"error":"Error Message"}
but this could potentially be confusing to indicate that the service was not found. But this depends on how you've defined your RESTful API.
From what I understand, the above scenario is a mix of both, where it sends out a 200 OK, but at the same time an error message too which is not the way to do it.
Its best to read through the rules of REST and then come up with your API.
Also it might be worth documenting your API through SWAGGER or RAML which makes it meaningful to someone using the service without going through tons of code to understand it.
Since you're using http you should use the http status codes properly, for example the SQL exception would probably result in a response code of 500 Internal Server Error, but you shouldn't expose the actual stack trace or exception at least for two reasons
The api-user has no use of that error message, he can't act upon it or take any reasonable actions to fix it.
You're exposing the applications internals, this could provide someone with malicious intent with valuable information.
When it comes to actually displaying an error. Hopefully something that the user can have some sort of use of. You can pretty much do it in any manner you feel fits your api. The important thing is that the api is consistent.
I'd say that the body of the response you're giving now is okay, except for the fact that the actual message probably doesn't mean anything to the intended user when you just call toString() on an Exception, that information is intended for the developers and should probably be logged.
What you need to do is, translate the exceptions to usable error messages and use http status codes.
When creating a REST API on the top of the HTTP protocol, the HTTP status codes are the proper way to indicate the result of the operation. Along with the status code, you can return a message with more details about the error.
Find below the most common status codes of errors for situations when the client seems to have erred:
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
409 Conflict
422 Unprocessable Entity
Don't define your own status codes. Stick to the standards.
When returning a message, your HTTP response can be like:
HTTP/1.1 404 Not Found
Content-Type: application/json
{ "error" : "Resource not found with the requested identifier" }

turn http post request to http get

I want to setup a proxy or a standalone aplication where a "server A" can do some POST request to this proxy and turn the POST request to a GET request to "server B".
Then the GET response must be redirected to "server A" which is waiting a response for the POST.
¿Is it possible?
What I want to get from the request is a static pdf.
Any idea how to do it would be great
Thanks
You should not do this as the semantics are different.
GET requests are designed to be cached (i.e. usually static stuff). POST on the other hand is more dynamic and is not cached.
You are very likely to get undesired behaviour if you do this.

XML-RPC authentication (http vs. XmlRpcNotAuthorizedException)

I could not find an exact answer to my question (either google or here), so my apologies if this is a repeat that I missed:
I am writing a XML-RPC server using Apache's XML-RPC libraries (which I'm regretting a bit) in Java that needs to conform to a given specification. With authentication, the server generates an org.apache.xmlrpc.common.XmlRpcNotAuthorizedException. This is not the behaviour that is required. I would like to return an HTTP error 401 (not authenticated) and 403 (forbidden) instead. However, Apache keeps on throwing these exceptions and I cannot find a way around it.
For example response received after sending correct username/password:
HTTP/1.1 200 OK
Content-Length:362
Content-Type:text/xml
Server:Jetty(7.x.y-SNAPSHOT)
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
...correct response information here
</methodResponse>
...and wrong username and password:
HTTP/1.1 200 OK
Content-Length:252
Content-Type:text/xml
Server:Jetty(7.x.y-SNAPSHOT)
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
...xmlrpc exception here
<methodResponse>
I don't want "HTTP/1.1 200 OK", I want "HTTP/1.1 401 Unauthorized"
I was considering inheriting Apache's ReflectiveXmlRpcHandler (or something similar) and trying to intercept the exception, but I was wondering if someone else have found a better idea to this problem.
Any ideas?
That seems to be difficult. As stated in the XML-RPC Specification
Response format
Unless there's a lower-level error, always return 200 OK.
Bad Authentication Credentials is not a low-level error, it's just a particular use case.
But you can enable Exceptions on the client side (be aware of security issues) to handle this particular case
I would post code but it touches a few too many places and by the time I had it here, it was an essay...
What I did:
Created PropagatedHttpException extending RuntimeException. It just has one field, code, which is the HTTP error code.
Extend XmlRpcServletServer:
Override writeError to check if the error is a PropagatedHttpException and if it is,
throw it back out immediately.
Override execute(HttpServletRequest, HttpServletResponse) to catch
PropagatedHttpException and pass it on as a proper HTTP error.
Extend XmlRpcServlet:
Set a custom AuthenticationHandler which throws PropagatedHttpException for
specific HTTP error codes.
Override newXmlRpcServer to return the custom XmlRpcServletServer.
We already had a custom authentication handler when we started to figure out how this would work but in your case maybe it isn't needed and the writeError code could be adjusted to check for XmlRpcNotAuthorizedException. Actually I had no idea this exception existed until today...
The problem you'll have now is that from the client side, Apache XML-RPC doesn't check the error code it gets back and then tries to parse the XML response irrespective of the result.
Grooveek's answer is extremely disheartening to us as we want authentication to be hooked into the JRE's built-in authentication so that things like NTLM can work, but if it's going to return an HTTP 200 then it is impossible for this to ever work without breaking the spec.

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