From 23be5dfb0ea52ac08854aad2a5ed0caf696877c3 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 12 Sep 2019 20:57:30 +0100 Subject: [PATCH] Handle invalid MediaType in Jetty/Tomcat adapters See: gh-23553 --- .../server/reactive/AbstractServerHttpResponse.java | 9 +++++++-- .../server/reactive/JettyHttpHandlerAdapter.java | 9 ++++++++- .../server/reactive/ServletServerHttpResponse.java | 13 ++++++++++++- .../server/reactive/TomcatHttpHandlerAdapter.java | 9 ++++++++- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java index 3936a6824a..4f2f51214d 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java @@ -262,8 +262,13 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse { protected abstract void applyStatusCode(); /** - * Apply header changes from {@link #getHeaders()} to the underlying response. - * This method is called once only. + * Invoked when the response is getting committed allowing sub-classes to + * make apply header values to the underlying response. + *

Note that most sub-classes use an {@link HttpHeaders} instance that + * wraps an adapter to the native response headers such that changes are + * propagated to the underlying response on the go. That means this callback + * is typically not used other than for specialized updates such as setting + * the contentType or characterEncoding fields in a Servlet response. */ protected abstract void applyHeaders(); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java index b29a592dab..4f2c7128e9 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHttpHandlerAdapter.java @@ -101,8 +101,15 @@ public class JettyHttpHandlerAdapter extends ServletHttpHandlerAdapter { @Override protected void applyHeaders() { - MediaType contentType = getHeaders().getContentType(); HttpServletResponse response = getNativeResponse(); + MediaType contentType = null; + try { + contentType = getHeaders().getContentType(); + } + catch (Exception ex) { + String rawContentType = getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); + response.setContentType(rawContentType); + } if (response.getContentType() == null && contentType != null) { response.setContentType(contentType.toString()); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java index ffcddb680f..429c665da8 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java @@ -118,7 +118,14 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse { this.response.addHeader(headerName, headerValue); } }); - MediaType contentType = getHeaders().getContentType(); + MediaType contentType = null; + try { + contentType = getHeaders().getContentType(); + } + catch (Exception ex) { + String rawContentType = getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); + this.response.setContentType(rawContentType); + } if (this.response.getContentType() == null && contentType != null) { this.response.setContentType(contentType.toString()); } @@ -126,6 +133,10 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse { if (this.response.getCharacterEncoding() == null && charset != null) { this.response.setCharacterEncoding(charset.name()); } + long contentLength = getHeaders().getContentLength(); + if (contentLength != -1) { + this.response.setContentLengthLong(contentLength); + } } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java index 2bdf901b1c..78ad8d2970 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHttpHandlerAdapter.java @@ -204,7 +204,14 @@ public class TomcatHttpHandlerAdapter extends ServletHttpHandlerAdapter { @Override protected void applyHeaders() { HttpServletResponse response = getNativeResponse(); - MediaType contentType = getHeaders().getContentType(); + MediaType contentType = null; + try { + contentType = getHeaders().getContentType(); + } + catch (Exception ex) { + String rawContentType = getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); + response.setContentType(rawContentType); + } if (response.getContentType() == null && contentType != null) { response.setContentType(contentType.toString()); }