eclipse-ee4j / eclipse-ee4j/jersey
@Consumes incorrectly handles requests with no content type header
- Dominant language
- Java
- Stars
- 730
- Forks
- 382
- PR merge metrics
- No merged PRs in 30d
Description
From https://eclipse-ee4j.github.io/jaxrs-api/apidocs/2.1.6/javax/ws/rs/Consumes.html:
"Defines the media types that the methods of a resource class or MessageBodyReader can accept. If not specified, a container will assume that any media type is acceptable. Method level annotations override a class level annotation. A container is responsible for ensuring that the method invoked is capable of consuming the media type of the HTTP request entity body. If no such method is available the container must respond with a HTTP "415 Unsupported Media Type" as specified by RFC 2616."
Given the following definition:
@Consumes(MediaType.APPLICATION_JSON)
@Path("myresource")
@Produces(MediaType.APPLICATION_JSON)
public class MyResource {
@Consumes(MediaType.APPLICATION_JSON)
@POST
@Produces(MediaType.APPLICATION_JSON)
public String login() {
return "\n--Login!\n";
}
}
A request to "/myresource" with no 'content-type' header is accepted, login() is executed and a 200 OK response is returned. Example:
$ curl -v -X POST localhost:8080/myresource
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /myresource HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 10
<
--Login!
IMHO, the correct behavior would be to return "415 Unsupported Media Type" because the method and class are clearly annotated to handle only 'application/json'. A request with a missing 'content-type' header should not be interpreted as a valid/acceptable media type, it should be handled as an invalid media type because the lack of a content type should be equivalent to null and therefore it is not included in the list of acceptable media types indicated by the developer (only 'application/json' in this case).
Even if for some reason the lack of a content-type header results in assigning a 'default' content-type to the request, I'm guessing 'application/json' is not theorically this default content-type. Even if it is, I don't think this would be the correct behavior.
The response to a request with an unsupported content-type is correct:
> POST /myresource HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.0
> Accept: */*
> Content-type: text/plain
>
< HTTP/1.1 415 Unsupported Media Type
< Content-Length: 0
I don't know if this handled by Jersery or by the container, I tried with grizzly and jetty, and I also tested the same thing with RESTeasy and inexplicably (at least to me), requests with no content-type are accepted and processed, even when the class and method are annotated to handle only 'application/json'.
Perhaps this is not a Jersey issue but a container issue? anyways, this is so contrary to what I would expect @Consumes behavior to be, that I think this should be addressed asap. Let me know if I'm wrong!
Thank you!.
Contributor guide
Assessment
This issue has not been assessed yet.