Affects: 5.2.23

Problem

When org.springframework.http.HttpHeaders.getContentType is called on an invalid content type value, it throws an InvalidMediaTypeException.

HttpHeaders.getContentType states that it "Returns null when the content-type is unknown", and is annotated with @Nullable which leads the consumer to assume it won't throw an exception, and would return null if an invalid content-type was provided. https://github.com/spring-projects/spring-framework/blob/a3c89092e1ff9d07e4143af383090afa91a62c15/spring-web/src/main/java/org/springframework/http/HttpHeaders.java#L990-L996

The exception is thrown because HttpHeaders.getContentType delegates the MediaType parsing to MediaType.parseMediaType which either reutrns a non-null MediaType or throws an InvalidMediaTypeException. https://github.com/spring-projects/spring-framework/blob/a3c89092e1ff9d07e4143af383090afa91a62c15/spring-web/src/main/java/org/springframework/http/HttpHeaders.java#L998

Impact on spring-boot-webflux projects

On a @RestController annotated class with a @PostMapping method that accepts a @RequestBody annotated argument, a HTTP POST request with an invalid Content-Type header will trigger an internal server error:

{
    "timestamp": "2022-11-24T05:07:43.258+00:00",
    "path": "/",
    "status": 500,
    "error": "Internal Server Error",
    "requestId": "b68b77c7-1"
}

This is because the AbstractMessageReaderArgumentResolver.readBody attempts to call HttpHeaders.getContentType and store it as a variable contentType, assuming it won't throw an Exception. https://github.com/spring-projects/spring-framework/blob/a3c89092e1ff9d07e4143af383090afa91a62c15/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java#L135-L148

Steps to reproduce

  1. Create a Spring Boot project with spring-boot-starter-webflux dependency
  2. Add a RestController annotated class with the following method: ```

    @PostMapping("/") public String index(@RequestBody String body) { return body; } `` 3. Run the application, and make a HTTPPOSTrequest to the route with an invalidContent-Typeheader.curl -X POST http://localhost:8080/ -H "Content-Type: unknown` 4. An internal server error is triggered

Proposal

Wrap the call to MediaType.parseMediaType in a try catch block which returns null if an InvalidMediaTypeException is caught.

Comment From: rstoyanchev

I think "content-type is unknown" means the client didn't specify it and therefore it is not known to the server, in which case the method does return null as the annotation correctly indicates. The Javadoc, however, should also have @throws InvalidMediaTypeException since it can fail with a parse error. I'll update the Javadoc there.

As for AbstractMessageReaderArgumentResolver, by comparison Spring MVC's AbstractMessageConverterMethodArgumentResolver does expect and handle this as an exception that results in a 400 response. We need to the same.

Thanks for spotting and reporting these.