Problem details

The following method accepts int values as http status code of the built response entity. There is a validation in the HttpStatusCode#valueOf, but in some cases it defaults to a DefaultHttpStatusCode instance, even if the passed in code does not figure in the known http status' codes list

https://github.com/spring-projects/spring-framework/blob/b64edb2d2abf5068a0d5fa0289a809aa53803f0f/spring-web/src/main/java/org/springframework/http/ResponseEntity.java#L213-L215

Impact

If a controller returns a response with a status code that does not figure in the Hypertext Transfer Protocol (HTTP) Status Code Registry, the request hangs until a timeout is reached, and returns an empty response.

Reproduction

1- Having a Rest Controller

@GetMapping("some/endpoint")
    public ResponseEntity testWithInt() {
        return ResponseEntity.status(108)
                .build();
    }

2- Perform a curl command

 curl --request GET --url http://localhost:8070/some/endpoint

3- The result is

HTTP/1.1 108 
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Date: .........

curl: (52) Empty reply from server

Comment From: bclozel

Quoting the RFC:

HTTP status codes are extensible. HTTP clients are not required to understand the meaning of all registered status codes, though such understanding is obviously desirable. However, a client MUST understand the class of any status code, as indicated by the first digit, and treat an unrecognized status code as being equivalent to the x00 status code of that class, with the exception that a recipient MUST NOT cache a response with an unrecognized status code.

I guess in this case the client hangs because this is the nature of the 1xx series.

We do not prevent applications from using custom status codes and the RFC does not forbid it.

Comment From: bclozel

What about ˋHttpStatusCode.valueOf(int)`?