Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Status 406 "Not Accepted" is not appropriate when no message converter can handle return type [SPR-13135]

Closed
spring-projects-issues opened this issue Jun 16, 2015 · 6 comments
Assignees
Labels
in: web type: enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jun 16, 2015

Yi EungJun opened SPR-13135 and commented

Spring Framework seems to response 406 Not Accepted if there is no proper converter. For example, the following controller method responses always 406 Not Accepted because there is no proper message converter for the method which returns java.io.OutputStream , even if the client requested with "Accept: \*/\*" header which means accept any media type.

@RequestMapping("/")
public OutputStream test() {
    return new ByteArrayOutputStream();
}

I think the behavior, which respones 4xx Client Error, is not correct because it is a server error. The reason of the failure of the content negitation is the server programmer's mistake. The programmer should write a controller method that returns supported return type or register a propert converter.

If the server responses 406 Not Accepted incorrectly, the person on the client will waste time to find "the proper media type", which does not exist, the server can send. But if the server responses 5xx correctly, the person will report it to the server programmer without wasting time.


Affects: 4.1.6

Referenced from: commits 8d7812b

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jun 16, 2015

Yi EungJun commented

I think there are two points we should check.

  1. In https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java#L120-L126

If there is no producibleMediaTypes, it seems to fail finding compatibleMediaTypes and then response 406 Not Acceptable, even if the requestedMediaTypes is
{"*/*"}

  1. In https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java#L149-L170

If there is no proper message converter it throws HttpMeidaTypeNotAcceptableException and finally respones 406 Not Acceptable. It is an incorrect behavior because it is not a client error but a server error because the server tried to make a response body from contents the server can't convert.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Sep 4, 2015

Yi EungJun commented

This still reproduces if a file extension is specified. Here is an example:

<code>
@RestController
public class HelloController {

// This responds 406 Not Acceptable even if the client requests with "Accept: */*" header.
@RequestMapping("/test.txt")
public Test test() {
    return new Test();
}

class Test {
    public int getA() {
        return 1;
    }
}

}
</code>

I guess this problem occurs if ContentNegotiationManager has PathExtensionContentNegotiationStrategy.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Sep 4, 2015

Rossen Stoyanchev commented

Depending on how content negotiation is configured, path extensions may be preferred over the Accept header.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Sep 7, 2015

Yi EungJun commented

Thanks for reply.

As my reading the code of Spring Framework, preferring path extensions over Accept header seems the default behavior of ContentNegotiationManagerFactoryBean. But I think the default behavior should be respecting Accept header rather than path extensions, to respect the HTTP specification. Using path extensions may be appropriate to be used as a fallback.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Sep 11, 2015

Rossen Stoyanchev commented

I think this is based on the fact that the Accept headers sent by browsers are not helpful. That said the presence of a path extension is deliberate so it shouldn't be an issue in itself.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Sep 11, 2015

Yi EungJun commented

Thanks for the explanation. Now I understand why Spring Framework prefers path extension over Accept header.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web type: enhancement
Projects
None yet
Development

No branches or pull requests

2 participants