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 2020/11/19 13:27:34 UTC

[httpcomponents-core] branch master updated (bb48439 -> 050c567)

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git.


 discard bb48439  Move decision if the i/o session is to be terminated immediately to the protocol handler; by default attempt to terminate the i/o session gracefully
 discard 7ad2073  Optimized request termination by the non-blocking HTTP/1.1 protocol handler in case of a premature response or `expect-continue` handshake failure
     new 5d08aea  Disable weak cipher test on JREs greater than 1.8 (the test started failing on travis-ci.com recently for no aparent reason)
     new 8669d2c  Optimized request termination by the non-blocking HTTP/1.1 protocol handler in case of a premature response or `expect-continue` handshake failure
     new 050c567  Move decision if the i/o session is to be terminated immediately to the protocol handler; by default attempt to terminate the i/o session gracefully

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (bb48439)
            \
             N -- N -- N   refs/heads/master (050c567)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java | 11 +++++++++++
 1 file changed, 11 insertions(+)


[httpcomponents-core] 02/03: Optimized request termination by the non-blocking HTTP/1.1 protocol handler in case of a premature response or `expect-continue` handshake failure

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 8669d2c3c5a9fee537183b18238e1dbb8d16f8fd
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Wed Nov 18 19:57:01 2020 +0100

    Optimized request termination by the non-blocking HTTP/1.1 protocol handler in case of a premature response or `expect-continue` handshake failure
---
 .../hc/core5/testing/nio/Http1IntegrationTest.java | 66 ++++++++++++++++++++++
 .../http/impl/nio/ClientHttp1StreamDuplexer.java   |  6 +-
 .../http/impl/nio/ClientHttp1StreamHandler.java    |  2 +-
 3 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 67859d6..8c9a20e 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -859,6 +859,72 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
     }
 
     @Test
+    public void testExpectationFailedCloseConnection() throws Exception {
+        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
+
+                    @Override
+                    protected void handle(
+                            final Message<HttpRequest, String> request,
+                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                            final HttpContext context) throws IOException, HttpException {
+                        responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"), context);
+
+                    }
+                };
+            }
+
+        });
+        final InetSocketAddress serverEndpoint = server.start(null, new Decorator<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
+
+                return new BasicAsyncServerExpectationDecorator(handler) {
+
+                    @Override
+                    protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
+                        final Header h = request.getFirstHeader("password");
+                        if (h != null && "secret".equals(h.getValue())) {
+                            return null;
+                        } else {
+                            final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
+                            response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+                            return new BasicResponseProducer(response, "You shall not pass");
+                        }
+                    }
+                };
+
+            }
+        }, Http1Config.DEFAULT);
+
+        client.start();
+        final Future<IOSession> sessionFuture = client.requestSession(
+                new HttpHost("localhost", serverEndpoint.getPort()), TIMEOUT, null);
+        final IOSession ioSession = sessionFuture.get();
+        final ClientSessionEndpoint streamEndpoint = new ClientSessionEndpoint(ioSession);
+
+        final HttpRequest request1 = new BasicHttpRequest(Method.POST, createRequestURI(serverEndpoint, "/echo"));
+        final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
+                new BasicRequestProducer(request1, new MultiBinEntityProducer(
+                        new byte[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'},
+                        100000,
+                        ContentType.TEXT_PLAIN)),
+                new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+        final Message<HttpResponse, String> result1 = future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
+        Assert.assertNotNull(result1);
+        final HttpResponse response1 = result1.getHead();
+        Assert.assertNotNull(response1);
+        Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response1.getCode());
+        Assert.assertNotNull("You shall not pass", result1.getBody());
+
+        Assert.assertFalse(streamEndpoint.isOpen());
+    }
+
+    @Test
     public void testDelayedExpectationVerification() throws Exception {
         server.register("*", new Supplier<AsyncServerExchangeHandler>() {
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
index ca6c9a2..3cc6758 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
@@ -186,11 +186,7 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
             @Override
             public boolean abortGracefully() throws IOException {
                 final MessageDelineation messageDelineation = endOutputStream(null);
-                if (messageDelineation == MessageDelineation.MESSAGE_HEAD) {
-                    requestShutdown(CloseMode.GRACEFUL);
-                    return false;
-                }
-                return true;
+                return messageDelineation != MessageDelineation.MESSAGE_HEAD;
             }
 
             @Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
index e508852..1721b04 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
@@ -234,7 +234,7 @@ class ClientHttp1StreamHandler implements ResourceHolder {
             return;
         }
         if (requestState == MessageState.BODY) {
-            if (keepAlive && status >= HttpStatus.SC_CLIENT_ERROR) {
+            if (status >= HttpStatus.SC_CLIENT_ERROR) {
                 requestState = MessageState.COMPLETE;
                 if (!outputChannel.abortGracefully()) {
                     keepAlive = false;


[httpcomponents-core] 03/03: Move decision if the i/o session is to be terminated immediately to the protocol handler; by default attempt to terminate the i/o session gracefully

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 050c567d2e058b3e95c94c2a8fc7c6b6f3057eb5
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Thu Nov 19 12:29:22 2020 +0100

    Move decision if the i/o session is to be terminated immediately to the protocol handler; by default attempt to terminate the i/o session gracefully
---
 .../core5/http2/impl/nio/AbstractH2StreamMultiplexer.java  | 10 +++++++++-
 .../core5/http/impl/nio/AbstractHttp1StreamDuplexer.java   | 14 +++++++++++---
 .../java/org/apache/hc/core5/reactor/InternalChannel.java  |  4 ++--
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
index 1c756fd..7524dea 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
@@ -689,7 +689,15 @@ abstract class AbstractH2StreamMultiplexer implements Identifiable, HttpConnecti
             connState = ConnectionHandshake.SHUTDOWN;
         } catch (final IOException ignore) {
         } finally {
-            ioSession.close(cause instanceof IOException ? CloseMode.IMMEDIATE : CloseMode.GRACEFUL);
+            final CloseMode closeMode;
+            if (cause instanceof ConnectionClosedException) {
+                closeMode = CloseMode.GRACEFUL;
+            } else if (cause instanceof IOException) {
+                closeMode = CloseMode.IMMEDIATE;
+            } else {
+                closeMode = CloseMode.GRACEFUL;
+            }
+            ioSession.close(closeMode);
         }
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
index c5e63d4..bf4d268 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
@@ -157,12 +157,20 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
         }
     }
 
-    void shutdownSession(final Exception exception) {
+    void shutdownSession(final Exception cause) {
         connState = ConnectionState.SHUTDOWN;
         try {
-            terminate(exception);
+            terminate(cause);
         } finally {
-            ioSession.close();
+            final CloseMode closeMode;
+            if (cause instanceof ConnectionClosedException) {
+                closeMode = CloseMode.GRACEFUL;
+            } else if (cause instanceof IOException) {
+                closeMode = CloseMode.IMMEDIATE;
+            } else {
+                closeMode = CloseMode.GRACEFUL;
+            }
+            ioSession.close(closeMode);
         }
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalChannel.java
index fce58bd..acf8c8a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalChannel.java
@@ -53,7 +53,7 @@ abstract class InternalChannel implements ModalCloseable {
             close(CloseMode.GRACEFUL);
         } catch (final Exception ex) {
             onException(ex);
-            close(CloseMode.IMMEDIATE);
+            close(CloseMode.GRACEFUL);
         }
     }
 
@@ -69,7 +69,7 @@ abstract class InternalChannel implements ModalCloseable {
                     close(CloseMode.GRACEFUL);
                 } catch (final Exception ex) {
                     onException(ex);
-                    close(CloseMode.IMMEDIATE);
+                    close(CloseMode.GRACEFUL);
                 }
                 return false;
             }


[httpcomponents-core] 01/03: Disable weak cipher test on JREs greater than 1.8 (the test started failing on travis-ci.com recently for no aparent reason)

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 5d08aeaf28c18b80444b09e0915f365a22cd24f9
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Thu Nov 19 14:05:29 2020 +0100

    Disable weak cipher test on JREs greater than 1.8 (the test started failing on travis-ci.com recently for no aparent reason)
---
 .../org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java
index 0833c57..5dcc7f8 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java
@@ -70,9 +70,12 @@ import org.apache.hc.core5.reactor.ssl.TlsDetails;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.testing.SSLTestContexts;
 import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
+import org.apache.hc.core5.util.ReflectionUtils;
 import org.apache.hc.core5.util.Timeout;
 import org.hamcrest.CoreMatchers;
 import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExternalResource;
@@ -115,6 +118,13 @@ public class H2TLSIntegrationTest {
 
     };
 
+    private static int javaVersion;
+
+    @BeforeClass
+    public static void determineJavaVersion() {
+        javaVersion = ReflectionUtils.determineJRELevel();
+    }
+
     @Test
     public void testTLSSuccess() throws Exception {
         server = AsyncServerBootstrap.bootstrap()
@@ -377,6 +387,7 @@ public class H2TLSIntegrationTest {
 
     @Test
     public void testWeakCiphersDisabledByDefault() throws Exception {
+        Assume.assumeTrue("Java version must be 1.8 or lesser",  javaVersion <= 8);
         requester = H2RequesterBootstrap.bootstrap()
                 .setIOReactorConfig(IOReactorConfig.custom()
                         .setSoTimeout(TIMEOUT)