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 2016/12/13 19:27:53 UTC
svn commit: r1774084 - in /httpcomponents/httpcore/trunk/httpcore5/src:
main/java/org/apache/hc/core5/http/
main/java/org/apache/hc/core5/http/impl/nio/
main/java/org/apache/hc/core5/http/protocol/
test/java/org/apache/hc/core5/http/protocol/
Author: olegk
Date: Tue Dec 13 19:27:53 2016
New Revision: 1774084
URL: http://svn.apache.org/viewvc?rev=1774084&view=rev
Log:
RFC 7230, HTTPCORE-158: support for HTTP/1.1 protocol upgrade
Modified:
httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/HeaderElements.java
httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/UpgradeableHttpConnection.java
httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestConnControl.java
httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/ResponseConnControl.java
httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java
Modified: httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/HeaderElements.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/HeaderElements.java?rev=1774084&r1=1774083&r2=1774084&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/HeaderElements.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/HeaderElements.java Tue Dec 13 19:27:53 2016
@@ -40,6 +40,7 @@ public final class HeaderElements {
public static final String CHUNKED_ENCODING = "chunked";
public static final String CLOSE = "close";
public static final String KEEP_ALIVE = "keep-alive";
+ public static final String UPGRADE = "upgrade";
public static final String CONTINUE = "100-continue";
}
Modified: httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/UpgradeableHttpConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/UpgradeableHttpConnection.java?rev=1774084&r1=1774083&r2=1774084&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/UpgradeableHttpConnection.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/UpgradeableHttpConnection.java Tue Dec 13 19:27:53 2016
@@ -32,7 +32,11 @@ import org.apache.hc.core5.reactor.IOEve
import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
/**
- * HTTP connection capable of upgrading its transport security and protocol.
+ * Represents an HTTP/1.1 connection capable of upgrading its transport security
+ * and communication protocol.
+ *
+ * @see TransportSecurityLayer
+ * @see IOEventHandler
*
* @since 5.0
*/
Modified: httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestConnControl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestConnControl.java?rev=1774084&r1=1774083&r2=1774084&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestConnControl.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestConnControl.java Tue Dec 13 19:27:53 2016
@@ -67,7 +67,11 @@ public class RequestConnControl implemen
if (!request.containsHeader(HttpHeaders.CONNECTION)) {
// Default policy is to keep connection alive
// whenever possible
- request.addHeader(HttpHeaders.CONNECTION, HeaderElements.KEEP_ALIVE);
+ if (request.containsHeader(HttpHeaders.UPGRADE)) {
+ request.addHeader(HttpHeaders.CONNECTION, HeaderElements.UPGRADE);
+ } else {
+ request.addHeader(HttpHeaders.CONNECTION, HeaderElements.KEEP_ALIVE);
+ }
}
}
Modified: httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/ResponseConnControl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/ResponseConnControl.java?rev=1774084&r1=1774083&r2=1774084&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/ResponseConnControl.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/ResponseConnControl.java Tue Dec 13 19:27:53 2016
@@ -28,11 +28,12 @@
package org.apache.hc.core5.http.protocol;
import java.io.IOException;
+import java.util.Iterator;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HeaderElement;
import org.apache.hc.core5.http.HeaderElements;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHeaders;
@@ -42,6 +43,7 @@ import org.apache.hc.core5.http.HttpResp
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.message.MessageSupport;
import org.apache.hc.core5.util.Args;
/**
@@ -86,13 +88,29 @@ public class ResponseConnControl impleme
} else {
final HttpCoreContext coreContext = HttpCoreContext.adapt(context);
final HttpRequest request = coreContext.getRequest();
- // Drop connection if requested by the client or request was <= 1.0
+ boolean closeRequested = false;
+ boolean keepAliveRequested = false;
if (request != null) {
- final Header header = request.getFirstHeader(HttpHeaders.CONNECTION);
- if (header != null) {
- response.setHeader(HttpHeaders.CONNECTION, header.getValue());
- } else if (ver.lessEquals(HttpVersion.HTTP_1_0)) {
- response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+ final Iterator<HeaderElement> it = MessageSupport.iterate(request, HttpHeaders.CONNECTION);
+ while (it.hasNext()) {
+ final HeaderElement he = it.next();
+ if (he.getName().equalsIgnoreCase(HeaderElements.CLOSE)) {
+ closeRequested = true;
+ break;
+ } else if (he.getName().equalsIgnoreCase(HeaderElements.KEEP_ALIVE)) {
+ keepAliveRequested = true;
+ }
+ }
+ }
+ if (closeRequested) {
+ response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+ } else {
+ if (response.containsHeader(HttpHeaders.UPGRADE)) {
+ response.addHeader(HttpHeaders.CONNECTION, HeaderElements.UPGRADE);
+ } else {
+ if (keepAliveRequested || ver.lessEquals(HttpVersion.HTTP_1_0)) {
+ response.addHeader(HttpHeaders.CONNECTION, HeaderElements.KEEP_ALIVE);
+ }
}
}
}
Modified: httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java?rev=1774084&r1=1774083&r2=1774084&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestStandardInterceptors.java Tue Dec 13 19:27:53 2016
@@ -88,6 +88,18 @@ public class TestStandardInterceptors {
}
@Test
+ public void testRequestConnControlUpgrade() throws Exception {
+ final HttpContext context = new BasicHttpContext(null);
+ final BasicClassicHttpRequest request = new BasicClassicHttpRequest("GET", "/");
+ request.addHeader(HttpHeaders.UPGRADE, "HTTP/2");
+ final RequestConnControl interceptor = new RequestConnControl();
+ interceptor.process(request, request.getEntity(), context);
+ final Header header = request.getFirstHeader(HttpHeaders.CONNECTION);
+ Assert.assertNotNull(header);
+ Assert.assertEquals("upgrade", header.getValue());
+ }
+
+ @Test
public void testRequestConnControlInvalidInput() throws Exception {
final RequestConnControl interceptor = new RequestConnControl();
try {
@@ -656,7 +668,7 @@ public class TestStandardInterceptors {
interceptor.process(response, response.getEntity(), context);
final Header header = response.getFirstHeader(HttpHeaders.CONNECTION);
Assert.assertNotNull(header);
- Assert.assertEquals("close", header.getValue());
+ Assert.assertEquals("keep-alive", header.getValue());
}
@Test
@@ -705,6 +717,36 @@ public class TestStandardInterceptors {
}
@Test
+ public void testResponseConnControlClientRequestMixUp() throws Exception {
+ final HttpContext context = new BasicHttpContext(null);
+ final BasicClassicHttpRequest request = new BasicClassicHttpRequest("GET", "/");
+ request.addHeader(new BasicHeader(HttpHeaders.CONNECTION, "blah, keep-alive, close"));
+ context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
+
+ final ResponseConnControl interceptor = new ResponseConnControl();
+
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ interceptor.process(response, response.getEntity(), context);
+ final Header header = response.getFirstHeader(HttpHeaders.CONNECTION);
+ Assert.assertNotNull(header);
+ Assert.assertEquals("close", header.getValue());
+ }
+
+ @Test
+ public void testResponseConnControlUpgrade() throws Exception {
+ final HttpContext context = new BasicHttpContext(null);
+
+ final ResponseConnControl interceptor = new ResponseConnControl();
+
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ response.addHeader(HttpHeaders.UPGRADE, "HTTP/2");
+ interceptor.process(response, response.getEntity(), context);
+ final Header header = response.getFirstHeader(HttpHeaders.CONNECTION);
+ Assert.assertNotNull(header);
+ Assert.assertEquals("upgrade", header.getValue());
+ }
+
+ @Test
public void testResponseConnControlHostInvalidInput() throws Exception {
final ResponseConnControl interceptor = new ResponseConnControl();
try {