Ignore invalid Accept headers in WebFlux error handling

Prior to this commit, the `DefaultErrorWebExceptionHandler` would parse
the HTTP "Accept" headers when routing the request to the error handler;
if an error occured during parsing, an `InvalidMediaTypeException` would
be thrown and break the error handling for this request.

This commit ignores those exceptions and makes sure that the error
handling function does not override the response status or the error
itself with those exceptions.

Closes: gh-13372
This commit is contained in:
Brian Clozel 2018-06-06 14:02:04 +02:00
parent 47615154de
commit 7cbbd95fc9
2 changed files with 21 additions and 5 deletions

View File

@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.InvalidMediaTypeException;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.RequestPredicate;
@ -184,11 +185,16 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa
*/
protected RequestPredicate acceptsTextHtml() {
return (serverRequest) -> {
List<MediaType> acceptedMediaTypes = serverRequest.headers().accept();
acceptedMediaTypes.remove(MediaType.ALL);
MediaType.sortBySpecificityAndQuality(acceptedMediaTypes);
return acceptedMediaTypes.stream()
.anyMatch(MediaType.TEXT_HTML::isCompatibleWith);
try {
List<MediaType> acceptedMediaTypes = serverRequest.headers().accept();
acceptedMediaTypes.remove(MediaType.ALL);
MediaType.sortBySpecificityAndQuality(acceptedMediaTypes);
return acceptedMediaTypes.stream()
.anyMatch(MediaType.TEXT_HTML::isCompatibleWith);
}
catch (InvalidMediaTypeException ex) {
return false;
}
};
}

View File

@ -279,6 +279,16 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests {
});
}
@Test
public void invalidAcceptMediaType() {
this.contextRunner.run((context) -> {
WebTestClient client = WebTestClient.bindToApplicationContext(context)
.build();
client.get().uri("/notfound").header("Accept", "v=3.0").exchange()
.expectStatus().isEqualTo(HttpStatus.NOT_FOUND);
});
}
@Configuration
public static class Application {