diff options
author | Simone Bordet | 2014-05-04 14:03:26 +0000 |
---|---|---|
committer | Simone Bordet | 2014-05-04 14:04:32 +0000 |
commit | e892dc333cda1752aa5f4e1d99f8219fee4851cc (patch) | |
tree | 8fb058c13ba26a8c973dbf5abb9f45b64a106bd8 | |
parent | 27b1d6d5081e93d443e7e89a3139bf663cfb29a5 (diff) | |
download | org.eclipse.jetty.project-e892dc333cda1752aa5f4e1d99f8219fee4851cc.tar.gz org.eclipse.jetty.project-e892dc333cda1752aa5f4e1d99f8219fee4851cc.tar.xz org.eclipse.jetty.project-e892dc333cda1752aa5f4e1d99f8219fee4851cc.zip |
433916 - HttpChannelOverHttp handles HTTP 1.0 connection reuse incorrectly.
Fixed by properly checking the HTTP version and whether the
Connection: keep-alive header is present.
-rw-r--r-- | jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java | 12 | ||||
-rw-r--r-- | jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java | 38 |
2 files changed, 45 insertions, 5 deletions
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java index cd5bcf274f..b89a32bdb7 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpChannelOverHTTP.java @@ -20,10 +20,12 @@ package org.eclipse.jetty.client.http; import org.eclipse.jetty.client.HttpChannel; import org.eclipse.jetty.client.HttpExchange; +import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; +import org.eclipse.jetty.http.HttpVersion; public class HttpChannelOverHTTP extends HttpChannel { @@ -77,10 +79,12 @@ public class HttpChannelOverHTTP extends HttpChannel public void exchangeTerminated(Result result) { super.exchangeTerminated(result); - HttpFields responseHeaders = result.getResponse().getHeaders(); - boolean close = result.isFailed() || - responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()) || - receiver.isShutdown(); + Response response = result.getResponse(); + HttpFields responseHeaders = response.getHeaders(); + boolean implicitClose = response.getVersion().compareTo(HttpVersion.HTTP_1_1) < 0 && + !responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString()); + boolean explicitClose = responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()); + boolean close = result.isFailed() || implicitClose || explicitClose || receiver.isShutdown(); if (close) connection.close(); else diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java index 3313e224de..98c59c8530 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java @@ -24,7 +24,6 @@ import java.util.Arrays; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -37,6 +36,7 @@ import org.eclipse.jetty.client.api.Result; import org.eclipse.jetty.client.http.HttpDestinationOverHTTP; import org.eclipse.jetty.client.util.ByteBufferContentProvider; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.annotation.Slow; @@ -489,4 +489,40 @@ public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest Assert.assertEquals(0, idleConnections.size()); Assert.assertEquals(0, activeConnections.size()); } + + @Test + public void testConnectionForHTTP10ResponseIsRemoved() throws Exception + { + start(new EmptyServerHandler()); + + String host = "localhost"; + int port = connector.getLocalPort(); + HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination(scheme, host, port); + ConnectionPool connectionPool = destination.getConnectionPool(); + + final BlockingQueue<Connection> idleConnections = connectionPool.getIdleConnections(); + Assert.assertEquals(0, idleConnections.size()); + + final BlockingQueue<Connection> activeConnections = connectionPool.getActiveConnections(); + Assert.assertEquals(0, activeConnections.size()); + + client.setStrictEventOrdering(false); + ContentResponse response = client.newRequest(host, port) + .scheme(scheme) + .onResponseBegin(new Response.BeginListener() + { + @Override + public void onBegin(Response response) + { + // Simulate a HTTP 1.0 response has been received. + ((HttpResponse)response).version(HttpVersion.HTTP_1_0); + } + }) + .send(); + + Assert.assertEquals(200, response.getStatus()); + + Assert.assertEquals(0, idleConnections.size()); + Assert.assertEquals(0, activeConnections.size()); + } } |