Spring-boot: Spring Boot 1.4.0: HTTP Status Issue

Created on 3 Aug 2016  路  4Comments  路  Source: spring-projects/spring-boot

Bug

I have a GlobalExceptionHandler that catches exceptions and returns a HTTP Error codes.

@ControllerAdvice
@Component
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    ...

    // 404 - Not Found
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public void requestHandlingNoHandlerFound(HttpServletRequest request, Exception exception) {
        logger.error("Error Not Found (404): " + exception.getMessage());
    }

    ...

}

This works correctly and responds with a 404. But the HTTP response looks like this:

HTTP/1.1 404 
X-Application-Context: application:8080
Content-Length: 0
Date: Wed, 03 Aug 2016 14:36:52 GMT

But should return:

HTTP/1.1 404 Not Found
X-Application-Context: application:8080
Content-Length: 0
Date: Wed, 03 Aug 2016 14:36:52 GMT

The Not Found part is missing. This is the same for other errors. e.g. 500 - Internal Server Error

invalid

Most helpful comment

It came more from RFC 7230 than HTTP/2. In addition to the ABNF Andy quotes above, there is also the following text:

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.

Reason phrases added some overhead, especially if custom ones were used since Tomcat had to make them safe. Given the ABNF and the above text, we opted to drop the reason phrase entirely. To quote the comment in the relevant part of the Tomcat "Clients should ignore it (RFC 7230) and it just wastes bytes."

All 4 comments

That's a strange one. The problem's unlikely to be Spring (Boot or MVC) itself as we just call the servlet container to set the response status. Can you please provide some more details? I'm particularly interested in which container you're using. A sample that reproduces the problem would be ideal.

I've reproduced this. The details about a global exception handler are something of a red herring. The behaviour applies to all HTTP responses using Tomcat 8.5.4. If I downgrade to 8.0.36 the responses are as expected.

Having educated myself a bit, this behaviour is legal in terms of the HTTP spec where the reason phrase for the status is defined as being optional:

Reason-Phrase  = *<TEXT, excluding CR, LF>

The * means zero or more.

HTTP/2 removes the reason phrase entirely so I suspect this is a side-effect of Tomcat 8.5's support for HTTP/2 that's also affecting its support for HTTP 1.1.

In short, the change in behaviour is due to a change in Tomcat 8.5 and is legal in terms of the HTTP spec so I don't think there's anything that can/should be done in Spring Boot.

@markt-asf FYI, I thought you may be interested in this.

It came more from RFC 7230 than HTTP/2. In addition to the ABNF Andy quotes above, there is also the following text:

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.

Reason phrases added some overhead, especially if custom ones were used since Tomcat had to make them safe. Given the ABNF and the above text, we opted to drop the reason phrase entirely. To quote the comment in the relevant part of the Tomcat "Clients should ignore it (RFC 7230) and it just wastes bytes."

Was this page helpful?
0 / 5 - 0 ratings