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));
+ }
}