From ef5134644b44edbcd079bd5d5f9455a686ddc9bd Mon Sep 17 00:00:00 2001 From: pmouawad Date: Thu, 31 Dec 2015 16:11:38 +0100 Subject: [PATCH] HTTPCORE-397: DefaultConnectionReuseStrategy to take into account request 'Connection: close' directive for 4.4.x branch --- .../impl/DefaultConnectionReuseStrategy.java | 15 +++++++ .../TestDefaultConnectionReuseStrategy.java | 39 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java b/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java index dcdda74ac4..bc43c1eeb8 100644 --- a/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java +++ b/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java @@ -30,6 +30,7 @@ import org.apache.http.ConnectionReuseStrategy; import org.apache.http.Header; import org.apache.http.HeaderIterator; +import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; @@ -41,6 +42,7 @@ import org.apache.http.message.BasicTokenIterator; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpCoreContext; import org.apache.http.util.Args; /** @@ -77,6 +79,19 @@ public boolean keepAlive(final HttpResponse response, Args.notNull(response, "HTTP response"); Args.notNull(context, "HTTP context"); + final HttpRequest request = (HttpRequest)context.getAttribute(HttpCoreContext.HTTP_REQUEST); + if (request != null) { + final Header[] connHeaders = request.getHeaders(HTTP.CONN_DIRECTIVE); + if (connHeaders.length != 0) { + final TokenIterator ti = new BasicTokenIterator(new BasicHeaderIterator(connHeaders, null)); + while (ti.hasNext()) { + final String token = ti.nextToken(); + if (HTTP.CONN_CLOSE.equalsIgnoreCase(token)) { + return false; + } + } + } + } // Check for a self-terminating entity. If the end of the entity will // be indicated by closing the connection, there is no keep-alive. final ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); diff --git a/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java b/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java index aad37ab573..1cb76cd32a 100644 --- a/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java +++ b/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java @@ -28,12 +28,15 @@ package org.apache.http.impl; import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.HttpVersion; +import org.apache.http.message.BasicHttpRequest; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpCoreContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -260,5 +263,41 @@ public void testNoContentResponseHttp10() throws Exception { Assert.assertFalse(reuseStrategy.keepAlive(response, context)); } + @Test + public void testRequestExplicitClose() throws Exception { + final HttpRequest request = new BasicHttpRequest("GET", "/"); + context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); + request.addHeader("Connection", "close"); + final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); + response.addHeader("Connection", "keep-alive"); + Assert.assertFalse(reuseStrategy.keepAlive(response, context)); + } + + @Test + public void testRequestNoExplicitClose() throws Exception { + final HttpRequest request = new BasicHttpRequest("GET", "/"); + context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); + request.addHeader("Connection", "blah, blah, blah"); + + final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); + response.addHeader("Connection", "keep-alive"); + Assert.assertTrue(reuseStrategy.keepAlive(response, context)); + } + + @Test + public void testRequestExplicitCloseMultipleTokens() throws Exception { + final HttpRequest request = new BasicHttpRequest("GET", "/"); + context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); + request.addHeader("Connection", "blah, blah, blah"); + request.addHeader("Connection", "keep-alive"); + request.addHeader("Connection", "close"); + + final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + response.addHeader("Transfer-Encoding", "chunked"); + response.addHeader("Connection", "keep-alive"); + Assert.assertFalse(reuseStrategy.keepAlive(response, context)); + } }