From 8d157cb5b54c8fc2af116ef62831ef35a4a95a65 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 30 Apr 2018 21:02:36 -0400 Subject: [PATCH] Consistent handling of URISyntaxException Issue: SPR-16778 --- .../reactive/ServletHttpHandlerAdapter.java | 19 ++++++++++++++++-- .../reactive/ServletServerHttpRequest.java | 20 ++++++++----------- .../reactive/TomcatHttpHandlerAdapter.java | 6 ++++-- .../reactive/UndertowHttpHandlerAdapter.java | 15 ++++++++++++-- .../reactive/UndertowServerHttpRequest.java | 9 ++++++--- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java index 8c81f62a115..e8e620c7616 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletHttpHandlerAdapter.java @@ -17,6 +17,7 @@ package org.springframework.http.server.reactive; import java.io.IOException; +import java.net.URISyntaxException; import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; import javax.servlet.AsyncContext; @@ -155,6 +156,7 @@ public class ServletHttpHandlerAdapter implements Servlet { @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { + if (DispatcherType.ASYNC.equals(request.getDispatcherType())) { Throwable ex = (Throwable) request.getAttribute(WRITE_ERROR_ATTRIBUTE_NAME); throw new ServletException("Write publisher error", ex); @@ -164,7 +166,18 @@ public class ServletHttpHandlerAdapter implements Servlet { AsyncContext asyncContext = request.startAsync(); asyncContext.setTimeout(-1); - ServerHttpRequest httpRequest = createRequest(((HttpServletRequest) request), asyncContext); + ServerHttpRequest httpRequest; + try { + httpRequest = createRequest(((HttpServletRequest) request), asyncContext); + } + catch (URISyntaxException ex) { + if (logger.isWarnEnabled()) { + logger.warn("Invalid URL for incoming request: " + ex.getMessage()); + } + ((HttpServletResponse) response).setStatus(400); + asyncContext.complete(); + return; + } ServerHttpResponse httpResponse = createResponse(((HttpServletResponse) response), asyncContext); if (httpRequest.getMethod() == HttpMethod.HEAD) { @@ -179,7 +192,9 @@ public class ServletHttpHandlerAdapter implements Servlet { this.httpHandler.handle(httpRequest, httpResponse).subscribe(subscriber); } - protected ServerHttpRequest createRequest(HttpServletRequest request, AsyncContext context) throws IOException { + protected ServerHttpRequest createRequest(HttpServletRequest request, AsyncContext context) + throws IOException, URISyntaxException { + Assert.notNull(this.servletPath, "Servlet path is not initialized"); return new ServletServerHttpRequest( request, context, this.servletPath, getDataBufferFactory(), getBufferSize()); diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java index db7c5995779..6949296b4bb 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java @@ -79,7 +79,8 @@ class ServletServerHttpRequest extends AbstractServerHttpRequest { public ServletServerHttpRequest(HttpServletRequest request, AsyncContext asyncContext, - String servletPath, DataBufferFactory bufferFactory, int bufferSize) throws IOException { + String servletPath, DataBufferFactory bufferFactory, int bufferSize) + throws IOException, URISyntaxException { super(initUri(request), request.getContextPath() + servletPath, initHeaders(request)); @@ -98,19 +99,14 @@ class ServletServerHttpRequest extends AbstractServerHttpRequest { this.bodyPublisher.registerReadListener(); } - private static URI initUri(HttpServletRequest request) { + private static URI initUri(HttpServletRequest request) throws URISyntaxException { Assert.notNull(request, "'request' must not be null"); - try { - StringBuffer url = request.getRequestURL(); - String query = request.getQueryString(); - if (StringUtils.hasText(query)) { - url.append('?').append(query); - } - return new URI(url.toString()); - } - catch (URISyntaxException ex) { - throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex); + StringBuffer url = request.getRequestURL(); + String query = request.getQueryString(); + if (StringUtils.hasText(query)) { + url.append('?').append(query); } + return new URI(url.toString()); } private static HttpHeaders initHeaders(HttpServletRequest request) { 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 53abe4186cd..792ddfd8392 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 @@ -17,6 +17,7 @@ package org.springframework.http.server.reactive; import java.io.IOException; +import java.net.URISyntaxException; import java.nio.ByteBuffer; import javax.servlet.AsyncContext; import javax.servlet.ServletRequest; @@ -50,7 +51,7 @@ public class TomcatHttpHandlerAdapter extends ServletHttpHandlerAdapter { @Override protected ServerHttpRequest createRequest(HttpServletRequest request, AsyncContext asyncContext) - throws IOException { + throws IOException, URISyntaxException { Assert.notNull(getServletPath(), "servletPath is not initialized."); return new TomcatServerHttpRequest(request, asyncContext, getServletPath(), @@ -68,7 +69,8 @@ public class TomcatHttpHandlerAdapter extends ServletHttpHandlerAdapter { private final class TomcatServerHttpRequest extends ServletServerHttpRequest { public TomcatServerHttpRequest(HttpServletRequest request, AsyncContext context, - String servletPath, DataBufferFactory factory, int bufferSize) throws IOException { + String servletPath, DataBufferFactory factory, int bufferSize) + throws IOException, URISyntaxException { super(request, context, servletPath, factory, bufferSize); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java index e9ad7d90ed3..2ca55f0e046 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHttpHandlerAdapter.java @@ -17,6 +17,7 @@ package org.springframework.http.server.reactive; import java.io.IOException; +import java.net.URISyntaxException; import io.undertow.server.HttpServerExchange; import org.apache.commons.logging.Log; @@ -64,8 +65,18 @@ public class UndertowHttpHandlerAdapter implements io.undertow.server.HttpHandle @Override - public void handleRequest(HttpServerExchange exchange) throws Exception { - ServerHttpRequest request = new UndertowServerHttpRequest(exchange, getDataBufferFactory()); + public void handleRequest(HttpServerExchange exchange) { + ServerHttpRequest request = null; + try { + request = new UndertowServerHttpRequest(exchange, getDataBufferFactory()); + } + catch (URISyntaxException ex) { + if (logger.isWarnEnabled()) { + logger.warn("Invalid URL for incoming request: " + ex.getMessage()); + } + exchange.setStatusCode(400); + return; + } ServerHttpResponse response = new UndertowServerHttpResponse(exchange, getDataBufferFactory()); if (request.getMethod() == HttpMethod.HEAD) { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java index 66b0992d8e3..8ef9eb90c3f 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpRequest.java @@ -21,6 +21,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.URI; +import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.util.function.IntPredicate; import javax.net.ssl.SSLSession; @@ -59,19 +60,21 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest { private final RequestBodyPublisher body; - public UndertowServerHttpRequest(HttpServerExchange exchange, DataBufferFactory bufferFactory) { + public UndertowServerHttpRequest(HttpServerExchange exchange, DataBufferFactory bufferFactory) + throws URISyntaxException { + super(initUri(exchange), "", initHeaders(exchange)); this.exchange = exchange; this.body = new RequestBodyPublisher(exchange, bufferFactory); this.body.registerListeners(exchange); } - private static URI initUri(HttpServerExchange exchange) { + private static URI initUri(HttpServerExchange exchange) throws URISyntaxException { Assert.notNull(exchange, "HttpServerExchange is required."); String requestURL = exchange.getRequestURL(); String query = exchange.getQueryString(); String requestUriAndQuery = StringUtils.isEmpty(query) ? requestURL : requestURL + "?" + query; - return URI.create(requestUriAndQuery); + return new URI(requestUriAndQuery); } private static HttpHeaders initHeaders(HttpServerExchange exchange) {