You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/05/09 20:01:29 UTC
[03/50] httpcomponents-core git commit: HTTPCORE-434: Handling of
HEAD responses without payload headers
HTTPCORE-434: Handling of HEAD responses without payload headers
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1763889 13f79535-47bb-0310-9956-ffa450edef68
Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/441c9c46
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/441c9c46
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/441c9c46
Branch: refs/heads/4.4.x
Commit: 441c9c46f6f2c8fb1c54c7c9233f578a4e4056a5
Parents: 5b2dee7
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Sat Oct 8 11:11:09 2016 +0000
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Sat Oct 8 11:11:09 2016 +0000
----------------------------------------------------------------------
.../impl/DefaultConnectionReuseStrategy.java | 42 +++++++++++++++-----
.../TestDefaultConnectionReuseStrategy.java | 24 +++++++++++
2 files changed, 55 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/441c9c46/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java
----------------------------------------------------------------------
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 8f73a6e..7a81d45 100644
--- a/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java
+++ b/httpcore/src/main/java/org/apache/http/impl/DefaultConnectionReuseStrategy.java
@@ -30,18 +30,20 @@ package org.apache.http.impl;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.ParseException;
import org.apache.http.ProtocolVersion;
import org.apache.http.TokenIterator;
-import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.annotation.Contract;
-import org.apache.http.message.BasicHeaderIterator;
+import org.apache.http.annotation.ThreadingBehavior;
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;
/**
@@ -78,6 +80,22 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
Args.notNull(response, "HTTP response");
Args.notNull(context, "HTTP context");
+ final HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST);
+ if (request != null) {
+ try {
+ final TokenIterator ti = new BasicTokenIterator(request.headerIterator(HttpHeaders.CONNECTION));
+ while (ti.hasNext()) {
+ final String token = ti.nextToken();
+ if (HTTP.CONN_CLOSE.equalsIgnoreCase(token)) {
+ return false;
+ }
+ }
+ } catch (final ParseException px) {
+ // invalid connection header. do not re-use
+ 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();
@@ -87,7 +105,7 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
return false;
}
} else {
- if (canResponseHaveBody(response)) {
+ if (canResponseHaveBody(request, response)) {
final Header[] clhs = response.getHeaders(HTTP.CONTENT_LEN);
// Do not reuse if not properly content-length delimited
if (clhs.length == 1) {
@@ -109,9 +127,9 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
// Check for the "Connection" header. If that is absent, check for
// the "Proxy-Connection" header. The latter is an unspecified and
// broken but unfortunately common extension of HTTP.
- Header[] connHeaders = response.getHeaders(HTTP.CONN_DIRECTIVE);
- if (connHeaders.length == 0) {
- connHeaders = response.getHeaders("Proxy-Connection");
+ HeaderIterator headerIterator = response.headerIterator(HTTP.CONN_DIRECTIVE);
+ if (!headerIterator.hasNext()) {
+ headerIterator = response.headerIterator("Proxy-Connection");
}
// Experimental usage of the "Connection" header in HTTP/1.0 is
@@ -137,9 +155,9 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
// it takes precedence and indicates a non-persistent connection.
// If there is no "close" but a "keep-alive", we take the hint.
- if (connHeaders.length != 0) {
+ if (headerIterator.hasNext()) {
try {
- final TokenIterator ti = new BasicTokenIterator(new BasicHeaderIterator(connHeaders, null));
+ final TokenIterator ti = new BasicTokenIterator(headerIterator);
boolean keepalive = false;
while (ti.hasNext()) {
final String token = ti.nextToken();
@@ -156,8 +174,7 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
}
} catch (final ParseException px) {
- // invalid connection header means no persistent connection
- // we don't have logging in HttpCore, so the exception is lost
+ // invalid connection header. do not re-use
return false;
}
}
@@ -180,7 +197,10 @@ public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy {
return new BasicTokenIterator(hit);
}
- private boolean canResponseHaveBody(final HttpResponse response) {
+ private boolean canResponseHaveBody(final HttpRequest request, final HttpResponse response) {
+ if (request != null && request.getRequestLine().getMethod().equalsIgnoreCase("HEAD")) {
+ return false;
+ }
final int status = response.getStatusLine().getStatusCode();
return status >= HttpStatus.SC_OK
&& status != HttpStatus.SC_NO_CONTENT
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/441c9c46/httpcore/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
----------------------------------------------------------------------
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 aad37ab..44f89ce 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,26 @@ public class TestDefaultConnectionReuseStrategy {
Assert.assertFalse(reuseStrategy.keepAlive(response, context));
}
+ @Test
+ public void testRequestClose() throws Exception {
+ final HttpRequest request = new BasicHttpRequest("GET", "/");
+ request.addHeader("Connection", "close");
+ context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+ response.addHeader("Content-Length", "10");
+ response.addHeader("Connection", "keep-alive");
+
+ Assert.assertFalse(reuseStrategy.keepAlive(response, context));
+ }
+
+ @Test
+ public void testHeadRequestWithout() throws Exception {
+ final HttpRequest request = new BasicHttpRequest("HEAD", "/");
+ context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
+ final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
+
+ Assert.assertTrue(reuseStrategy.keepAlive(response, context));
+ }
+
}