From 19cc38886148e9f0814cbcbfd79066aef5c232c9 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 10 Mar 2020 12:51:32 +0000 Subject: [PATCH] Test Tomcat's handling of a request on an idle connection See gh-4657 --- .../TomcatServletWebServerFactoryTests.java | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java index 5a5c11e396ff..47b26d79e638 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactoryTests.java @@ -18,6 +18,7 @@ import java.io.File; import java.io.IOException; +import java.net.SocketException; import java.net.URISyntaxException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -57,7 +58,9 @@ import org.apache.coyote.ProtocolHandler; import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; import org.apache.http.conn.HttpHostConnectException; +import org.apache.http.impl.client.HttpClients; import org.apache.jasper.servlet.JspServlet; import org.apache.tomcat.JarScanFilter; import org.apache.tomcat.JarScanType; @@ -582,8 +585,40 @@ void whenServerIsShuttingDownGracefullyThenNewConnectionsCannotBeMade() throws E assertThat(shutdownResult.get()).isEqualTo(false); blockingServlet.admitOne(); assertThat(request.get()).isInstanceOf(HttpResponse.class); - this.webServer.stop(); assertThat(unconnectableRequest.get()).isInstanceOf(HttpHostConnectException.class); + this.webServer.stop(); + } + + @Test + void whenServerIsShuttingDownARequestOnAnIdleConnectionResultsInConnectionReset() throws Exception { + AbstractServletWebServerFactory factory = getFactory(); + Shutdown shutdown = new Shutdown(); + shutdown.setGracePeriod(Duration.ofSeconds(5)); + factory.setShutdown(shutdown); + BlockingServlet blockingServlet = new BlockingServlet(); + this.webServer = factory.getWebServer((context) -> { + Dynamic registration = context.addServlet("blockingServlet", blockingServlet); + registration.addMapping("/blocking"); + registration.setAsyncSupported(true); + }); + HttpClient httpClient = HttpClients.createMinimal(); + this.webServer.start(); + int port = this.webServer.getPort(); + Future keepAliveRequest = initiateGetRequest(httpClient, port, "/blocking"); + blockingServlet.awaitQueue(); + blockingServlet.admitOne(); + assertThat(keepAliveRequest.get()).isInstanceOf(HttpResponse.class); + Future request = initiateGetRequest(port, "/blocking"); + blockingServlet.awaitQueue(); + initiateGracefulShutdown(); + Future idleConnectionRequest = initiateGetRequest(httpClient, port, "/blocking"); + blockingServlet.admitOne(); + Object response = request.get(); + assertThat(response).isInstanceOf(HttpResponse.class); + Object idleConnectionRequestResult = idleConnectionRequest.get(); + assertThat(idleConnectionRequestResult).isInstanceOf(SocketException.class); + assertThat((SocketException) idleConnectionRequestResult).hasMessage("Connection reset"); + this.webServer.stop(); } @Override