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 2018/01/15 08:17:55 UTC

[1/4] httpcomponents-client git commit: Upgraded HttpCore dependency to version 5.0-beta2

Repository: httpcomponents-client
Updated Branches:
  refs/heads/master a7a70e8cd -> 1e5fe0e01


Upgraded HttpCore dependency to version 5.0-beta2


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/dee32207
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/dee32207
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/dee32207

Branch: refs/heads/master
Commit: dee32207e33106d6dca25adaf15a9e46ece370f3
Parents: a7a70e8
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Fri Jan 12 13:02:42 2018 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Jan 12 14:06:08 2018 +0100

----------------------------------------------------------------------
 .../http/impl/cache/HttpCacheEntryMatcher.java  |  16 +-
 httpclient5-testing/pom.xml                     |   6 -
 .../AbstractHttpAsyncFundamentalsTest.java      |  10 +
 .../client5/testing/async/TestHttp1Async.java   |  10 -
 .../sync/TestClientRequestExecution.java        |   4 +-
 .../AbstractMinimalHttpAsyncClientBase.java     |  20 +-
 .../Http2AsyncClientEventHandlerFactory.java    |   5 +-
 .../async/InternalAbstractHttpAsyncClient.java  |  10 +-
 .../InternalHttp2ClientProtocolNegotiator.java  | 230 -------------------
 pom.xml                                         |   8 +-
 10 files changed, 31 insertions(+), 288 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
index c0db981..9c4a52c 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java
@@ -28,12 +28,12 @@ package org.apache.hc.client5.http.impl.cache;
 
 import java.util.Arrays;
 import java.util.Date;
-import java.util.Objects;
 
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.Resource;
 import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.util.LangUtils;
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.Factory;
@@ -60,18 +60,26 @@ public class HttpCacheEntryMatcher extends BaseMatcher<HttpCacheEntry> {
                 }
                 final Date expectedRequestDate = expectedValue.getRequestDate();
                 final Date otherRequestDate = otherValue.getRequestDate();
-                if (!Objects.equals(expectedRequestDate, otherRequestDate)) {
+                if (!LangUtils.equals(expectedRequestDate, otherRequestDate)) {
                     return false;
                 }
                 final Date expectedResponseDate = expectedValue.getResponseDate();
                 final Date otherResponseDate = otherValue.getResponseDate();
-                if (!Objects.equals(expectedResponseDate, otherResponseDate)) {
+                if (!LangUtils.equals(expectedResponseDate, otherResponseDate)) {
                     return false;
                 }
                 final Header[] expectedHeaders = expectedValue.getAllHeaders();
                 final Header[] otherHeaders = otherValue.getAllHeaders();
-                if (!Arrays.deepEquals(expectedHeaders, otherHeaders)) {
+                if (expectedHeaders.length != otherHeaders.length) {
                     return false;
+                } else {
+                    for (int i = 0; i < expectedHeaders.length; i++) {
+                        final Header h1 = expectedHeaders[i];
+                        final Header h2 = otherHeaders[i];
+                        if (!h1.getName().equals(h2.getName()) || !LangUtils.equals(h1.getValue(), h2.getValue())) {
+                            return false;
+                        }
+                    }
                 }
                 final Resource expectedResource = expectedValue.getResource();
                 final byte[] expectedContent = expectedResource != null ? expectedResource.get() : null;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5-testing/pom.xml
----------------------------------------------------------------------
diff --git a/httpclient5-testing/pom.xml b/httpclient5-testing/pom.xml
index 35212ec..ad037f1 100644
--- a/httpclient5-testing/pom.xml
+++ b/httpclient5-testing/pom.xml
@@ -59,12 +59,6 @@
       <scope>compile</scope>
       <optional>true</optional>
     </dependency>
-    <!-- TODO remove after upgrade to HttpCore 5.0b2 -->
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-      <scope>compile</scope>
-    </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
index 6f36fd8..71eb25c 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
@@ -202,4 +202,14 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
         }
     }
 
+    @Test
+    public void testBadRequest() throws Exception {
+        final HttpHost target = start();
+        final Future<SimpleHttpResponse> future = httpclient.execute(
+                SimpleHttpRequest.get(target, "/random/boom"), null);
+        final SimpleHttpResponse response = future.get();
+        Assert.assertThat(response, CoreMatchers.notNullValue());
+        Assert.assertThat(response.getCode(), CoreMatchers.equalTo(400));
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java
index 5417292..4bab918 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1Async.java
@@ -184,14 +184,4 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
         Assert.assertThat(body3.length(), CoreMatchers.equalTo(2048));
     }
 
-    @Test
-    public void testBadRequest() throws Exception {
-        final HttpHost target = start();
-        final Future<SimpleHttpResponse> future = httpclient.execute(
-                SimpleHttpRequest.get(target, "/random/boom"), null);
-        final SimpleHttpResponse response = future.get();
-        Assert.assertThat(response, CoreMatchers.notNullValue());
-        Assert.assertThat(response.getCode(), CoreMatchers.equalTo(400));
-    }
-
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
index d0dd55d..a2a4fa8 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
@@ -200,7 +200,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
         final HttpHost target = start();
 
         final HttpClientContext context = HttpClientContext.create();
-        final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "blah.:.blah.:.");
+        final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "{{|boom|}}");
         final ClassicHttpResponse response = this.httpclient.execute(target, request, context);
         EntityUtils.consume(response.getEntity());
 
@@ -208,7 +208,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
 
         final HttpRequest reqWrapper = context.getRequest();
 
-        Assert.assertEquals("blah.:.blah.:.", reqWrapper.getRequestUri());
+        Assert.assertEquals("{{|boom|}}", reqWrapper.getRequestUri());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractMinimalHttpAsyncClientBase.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractMinimalHttpAsyncClientBase.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractMinimalHttpAsyncClientBase.java
index ceaf09f..bf9fa88 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractMinimalHttpAsyncClientBase.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractMinimalHttpAsyncClientBase.java
@@ -58,25 +58,7 @@ abstract class AbstractMinimalHttpAsyncClientBase extends AbstractHttpAsyncClien
         execute(new BasicClientExchangeHandler<>(
                         requestProducer,
                         responseConsumer,
-                        //TODO: eliminate this callback after upgrade to HttpCore 5.0b2
-                        new FutureCallback<T>() {
-
-                            @Override
-                            public void completed(final T result) {
-                                future.completed(result);
-                            }
-
-                            @Override
-                            public void failed(final Exception ex) {
-                                future.failed(ex);
-                            }
-
-                            @Override
-                            public void cancelled() {
-                                future.cancel();
-                            }
-
-                        }),
+                        callback),
                 context, future, new Supplier<T>() {
 
                     @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncClientEventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncClientEventHandlerFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncClientEventHandlerFactory.java
index 9c5cd87..3bbc9c8 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncClientEventHandlerFactory.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncClientEventHandlerFactory.java
@@ -43,6 +43,7 @@ import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.http2.frame.FramePrinter;
 import org.apache.hc.core5.http2.frame.RawFrame;
 import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexerFactory;
+import org.apache.hc.core5.http2.impl.nio.Http2OnlyClientProtocolNegotiator;
 import org.apache.hc.core5.http2.impl.nio.Http2StreamListener;
 import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
@@ -178,7 +179,7 @@ class Http2AsyncClientEventHandlerFactory implements IOEventHandlerFactory {
 
                     });
             final LoggingIOSession loggingIOSession = new LoggingIOSession(ioSession, id, sessionLog, wireLog);
-            return new InternalHttp2ClientProtocolNegotiator(loggingIOSession, http2StreamHandlerFactory);
+            return new Http2OnlyClientProtocolNegotiator(loggingIOSession, http2StreamHandlerFactory, false);
         } else {
             final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory = new ClientHttp2StreamMultiplexerFactory(
                     httpProcessor,
@@ -186,7 +187,7 @@ class Http2AsyncClientEventHandlerFactory implements IOEventHandlerFactory {
                     h2Config,
                     charCodingConfig,
                     null);
-            return new InternalHttp2ClientProtocolNegotiator(ioSession, http2StreamHandlerFactory);
+            return new Http2OnlyClientProtocolNegotiator(ioSession, http2StreamHandlerFactory, false);
         }
    }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
index 7b6e279..916aec0 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
@@ -33,13 +33,11 @@ import java.util.Set;
 import java.util.concurrent.Future;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.async.AsyncExecCallback;
 import org.apache.hc.client5.http.async.AsyncExecChain;
 import org.apache.hc.client5.http.async.AsyncExecRuntime;
-import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
 import org.apache.hc.client5.http.auth.AuthSchemeProvider;
 import org.apache.hc.client5.http.auth.CredentialsProvider;
 import org.apache.hc.client5.http.config.Configurable;
@@ -168,7 +166,6 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
 
                     final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, future,
                             clientContext, execRuntime);
-                    final AtomicReference<T> resultRef = new AtomicReference<>(null);
                     final AtomicBoolean outputTerminated = new AtomicBoolean(false);
                     execChain.execute(
                             RequestCopier.INSTANCE.copy(request),
@@ -186,8 +183,7 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
 
                                 @Override
                                 public boolean isRepeatable() {
-                                    //TODO: use AsyncRequestProducer#isRepeatable once available
-                                    return requestProducer instanceof SimpleRequestProducer;
+                                    return requestProducer.isRepeatable();
                                 }
 
                                 @Override
@@ -242,12 +238,11 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
                                         requestProducer.releaseResources();
                                     }
                                     responseConsumer.consumeResponse(response, entityDetails,
-                                            //TODO: eliminate this callback after upgrade to HttpCore 5.0b2
                                             new FutureCallback<T>() {
 
                                                 @Override
                                                 public void completed(final T result) {
-                                                    resultRef.set(result);
+                                                    future.completed(result);
                                                 }
 
                                                 @Override
@@ -271,7 +266,6 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
                                     }
                                     try {
                                         execRuntime.releaseConnection();
-                                        future.completed(resultRef.getAndSet(null));
                                     } finally {
                                         responseConsumer.releaseResources();
                                         requestProducer.releaseResources();

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2ClientProtocolNegotiator.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2ClientProtocolNegotiator.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2ClientProtocolNegotiator.java
deleted file mode 100644
index b7f6b2e..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2ClientProtocolNegotiator.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http.impl.async;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.net.SocketTimeoutException;
-import java.nio.ByteBuffer;
-import java.nio.channels.ByteChannel;
-
-import javax.net.ssl.SSLSession;
-
-import org.apache.hc.core5.http.ConnectionClosedException;
-import org.apache.hc.core5.http.EndpointDetails;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.ProtocolVersion;
-import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
-import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
-import org.apache.hc.core5.http.nio.command.ExecutionCommand;
-import org.apache.hc.core5.http2.impl.nio.ClientHttp2IOEventHandler;
-import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexer;
-import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexerFactory;
-import org.apache.hc.core5.http2.ssl.ApplicationProtocols;
-import org.apache.hc.core5.io.ShutdownType;
-import org.apache.hc.core5.reactor.Command;
-import org.apache.hc.core5.reactor.IOEventHandler;
-import org.apache.hc.core5.reactor.IOSession;
-import org.apache.hc.core5.reactor.TlsCapableIOSession;
-import org.apache.hc.core5.reactor.ssl.TlsDetails;
-import org.apache.hc.core5.util.TextUtils;
-
-/**
- * TODO: replace with Http2OnlyClientProtocolNegotiator after HttpCore 5.0b2
- */
-final class InternalHttp2ClientProtocolNegotiator implements HttpConnectionEventHandler {
-
-    // PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
-    final static byte[] PREFACE = new byte[] {
-            0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54, 0x54, 0x50,
-            0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a, 0x0d, 0x0a, 0x53, 0x4d,
-            0x0d, 0x0a, 0x0d, 0x0a};
-
-    private final TlsCapableIOSession ioSession;
-    private final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory;
-
-    private final ByteBuffer preface;
-
-    public InternalHttp2ClientProtocolNegotiator(
-            final TlsCapableIOSession ioSession,
-            final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory) {
-        this.ioSession = ioSession;
-        this.http2StreamHandlerFactory = http2StreamHandlerFactory;
-        this.preface = ByteBuffer.wrap(PREFACE);
-    }
-
-    @Override
-    public void connected(final IOSession session) {
-        try {
-            final TlsDetails tlsDetails = ioSession.getTlsDetails();
-            if (tlsDetails != null) {
-                final String applicationProtocol = tlsDetails.getApplicationProtocol();
-                if (!TextUtils.isEmpty(applicationProtocol)) {
-                    if (!ApplicationProtocols.HTTP_2.id.equals(applicationProtocol)) {
-                        throw new HttpException("Unexpected application protocol: " + applicationProtocol);
-                    }
-                }
-            }
-            writePreface(session);
-        } catch (final Exception ex) {
-            session.shutdown(ShutdownType.IMMEDIATE);
-            exception(session, ex);
-        }
-    }
-
-    private void writePreface(final IOSession session) throws IOException  {
-        if (preface.hasRemaining()) {
-            final ByteChannel channel = session.channel();
-            channel.write(preface);
-        }
-        if (!preface.hasRemaining()) {
-            final ClientHttp2StreamMultiplexer streamMultiplexer = http2StreamHandlerFactory.create(ioSession);
-            final IOEventHandler newHandler = new ClientHttp2IOEventHandler(streamMultiplexer);
-            newHandler.connected(session);
-            session.setHandler(newHandler);
-        }
-    }
-
-    @Override
-    public void inputReady(final IOSession session) {
-        outputReady(session);
-    }
-
-    @Override
-    public void outputReady(final IOSession session) {
-        try {
-            if (preface != null) {
-                writePreface(session);
-            } else {
-                session.shutdown(ShutdownType.IMMEDIATE);
-            }
-        } catch (final IOException ex) {
-            session.shutdown(ShutdownType.IMMEDIATE);
-            exception(session, ex);
-        }
-    }
-
-    @Override
-    public void timeout(final IOSession session) {
-        exception(session, new SocketTimeoutException());
-    }
-
-    @Override
-    public void exception(final IOSession session, final Exception cause) {
-        try {
-            for (;;) {
-                final Command command = ioSession.getCommand();
-                if (command != null) {
-                    if (command instanceof ExecutionCommand) {
-                        final ExecutionCommand executionCommand = (ExecutionCommand) command;
-                        final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
-                        exchangeHandler.failed(cause);
-                        exchangeHandler.releaseResources();
-                    } else {
-                        command.cancel();
-                    }
-                } else {
-                    break;
-                }
-            }
-        } finally {
-            session.shutdown(ShutdownType.IMMEDIATE);
-        }
-    }
-
-    @Override
-    public void disconnected(final IOSession session) {
-        for (;;) {
-            final Command command = ioSession.getCommand();
-            if (command != null) {
-                if (command instanceof ExecutionCommand) {
-                    final ExecutionCommand executionCommand = (ExecutionCommand) command;
-                    final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
-                    exchangeHandler.failed(new ConnectionClosedException("Connection closed"));
-                    exchangeHandler.releaseResources();
-                } else {
-                    command.cancel();
-                }
-            } else {
-                break;
-            }
-        }
-    }
-
-    @Override
-    public SSLSession getSSLSession() {
-        final TlsDetails tlsDetails = ioSession.getTlsDetails();
-        return tlsDetails != null ? tlsDetails.getSSLSession() : null;
-    }
-
-    @Override
-    public EndpointDetails getEndpointDetails() {
-        return null;
-    }
-
-    @Override
-    public void setSocketTimeout(final int timeout) {
-        ioSession.setSocketTimeout(timeout);
-    }
-
-    @Override
-    public int getSocketTimeout() {
-        return ioSession.getSocketTimeout();
-    }
-
-    @Override
-    public ProtocolVersion getProtocolVersion() {
-        return null;
-    }
-
-    @Override
-    public SocketAddress getRemoteAddress() {
-        return ioSession.getRemoteAddress();
-    }
-
-    @Override
-    public SocketAddress getLocalAddress() {
-        return ioSession.getLocalAddress();
-    }
-
-    @Override
-    public boolean isOpen() {
-        return !ioSession.isClosed();
-    }
-
-    @Override
-    public void close() throws IOException {
-        ioSession.close();
-    }
-
-    @Override
-    public void shutdown(final ShutdownType shutdownType) {
-        ioSession.shutdown(shutdownType);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/dee32207/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2f3d0f0..b6e7f67 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,7 +68,7 @@
   <properties>
     <maven.compiler.source>1.7</maven.compiler.source>
     <maven.compiler.target>1.7</maven.compiler.target>
-    <httpcore.version>5.0-beta1</httpcore.version>
+    <httpcore.version>5.0-beta2</httpcore.version>
     <log4j.version>2.9.1</log4j.version>
     <commons-codec.version>1.10</commons-codec.version>
     <ehcache.version>3.4.0</ehcache.version>
@@ -105,12 +105,6 @@
       </dependency>
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
-        <artifactId>log4j-api</artifactId>
-        <version>${log4j.version}</version>
-      </dependency>
-      <!-- TODO remove after upgrade to HttpCore 5.0b2 -->
-      <dependency>
-        <groupId>org.apache.logging.log4j</groupId>
         <artifactId>log4j-slf4j-impl</artifactId>
         <version>${log4j.version}</version>
       </dependency>


[2/4] httpcomponents-client git commit: Re-use concurrent primitives from HttpCore

Posted by ol...@apache.org.
Re-use concurrent primitives from HttpCore


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/695f353b
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/695f353b
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/695f353b

Branch: refs/heads/master
Commit: 695f353b433e761dbdf026b96f3fc2cb872a9a07
Parents: dee3220
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Fri Jan 12 14:07:41 2018 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Jan 12 14:20:10 2018 +0100

----------------------------------------------------------------------
 .../AbstractSerializingAsyncCacheStorage.java   |  1 +
 .../http/impl/cache/AsyncCachingExec.java       | 29 ++++----
 .../http/impl/cache/BasicHttpAsyncCache.java    |  1 +
 .../http/impl/cache/ComplexCancellable.java     | 74 --------------------
 .../apache/hc/client5/http/fluent/Request.java  |  2 +-
 .../testing/sync/TestConnectionReuse.java       |  2 +-
 .../http/examples/ClientAbortMethod.java        |  4 +-
 .../hc/client5/http/CancellableAware.java       | 48 -------------
 .../hc/client5/http/async/AsyncExecChain.java   |  9 ++-
 .../hc/client5/http/classic/ExecRuntime.java    |  4 +-
 .../classic/methods/HttpUriRequestBase.java     | 28 ++++----
 .../impl/DefaultHttpRequestRetryHandler.java    |  2 +-
 .../http/impl/async/AsyncConnectExec.java       | 12 ++--
 .../http/impl/async/AsyncRedirectExec.java      |  2 +-
 .../http/impl/classic/InternalExecRuntime.java  | 28 ++++----
 .../http/impl/classic/InternalHttpClient.java   |  4 +-
 .../http/impl/classic/MinimalHttpClient.java    |  4 +-
 .../TestDefaultHttpRequestRetryHandler.java     |  2 +-
 .../impl/classic/TestInternalExecRuntime.java   | 12 ++--
 19 files changed, 74 insertions(+), 194 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
index ce4ed7c..81c21fa 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
@@ -42,6 +42,7 @@ import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
 import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.client5.http.impl.Operations;
 import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.concurrent.ComplexCancellable;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.util.Args;
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
index 36620b7..f8860c7 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
@@ -55,6 +55,7 @@ import org.apache.hc.client5.http.schedule.SchedulingStrategy;
 import org.apache.hc.client5.http.utils.DateUtils;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.concurrent.ComplexFuture;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.ContentType;
@@ -201,7 +202,7 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
         Args.notNull(scope, "Scope");
 
         final HttpRoute route = scope.route;
-        final ComplexFuture<?> future = scope.future;
+        final CancellableDependency operation = scope.cancellableDependency;
         final HttpClientContext context = scope.clientContext;
         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
         context.setAttribute(HttpClientContext.HTTP_REQUEST, request);
@@ -231,7 +232,7 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
 
         if (!cacheableRequestPolicy.isServableFromCache(request)) {
             log.debug("Request is not servable from cache");
-            future.setDependency(responseCache.flushCacheEntriesInvalidatedByRequest(target, request, new FutureCallback<Boolean>() {
+            operation.setDependency(responseCache.flushCacheEntriesInvalidatedByRequest(target, request, new FutureCallback<Boolean>() {
 
                 @Override
                 public void completed(final Boolean result) {
@@ -250,7 +251,7 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
 
             }));
         } else {
-            future.setDependency(responseCache.getCacheEntry(target, request, new FutureCallback<HttpCacheEntry>() {
+            operation.setDependency(responseCache.getCacheEntry(target, request, new FutureCallback<HttpCacheEntry>() {
 
                 @Override
                 public void completed(final HttpCacheEntry entry) {
@@ -506,8 +507,8 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
         }
 
         void triggerNewCacheEntryResponse(final HttpResponse backendResponse, final Date responseDate, final ByteArrayBuffer buffer) {
-            final ComplexFuture<?> future = scope.future;
-            future.setDependency(responseCache.createCacheEntry(
+            final CancellableDependency operation = scope.cancellableDependency;
+            operation.setDependency(responseCache.createCacheEntry(
                     target,
                     request,
                     backendResponse,
@@ -548,8 +549,8 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
                 final ByteArrayBuffer buffer = cachingDataConsumer.bufferRef.getAndSet(null);
                 final HttpResponse backendResponse = cachingDataConsumer.backendResponse;
                 if (cacheConfig.isFreshnessCheckEnabled()) {
-                    final ComplexFuture<?> future = scope.future;
-                    future.setDependency(responseCache.getCacheEntry(target, request, new FutureCallback<HttpCacheEntry>() {
+                    final CancellableDependency operation = scope.cancellableDependency;
+                    operation.setDependency(responseCache.getCacheEntry(target, request, new FutureCallback<HttpCacheEntry>() {
 
                         @Override
                         public void completed(final HttpCacheEntry existingEntry) {
@@ -681,9 +682,9 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
             final AtomicReference<AsyncExecCallback> callbackRef = new AtomicReference<>();
 
             void triggerUpdatedCacheEntryResponse(final HttpResponse backendResponse, final Date responseDate) {
-                final ComplexFuture<?> future = scope.future;
+                final CancellableDependency operation = scope.cancellableDependency;
                 recordCacheUpdate(scope.clientContext);
-                future.setDependency(responseCache.updateCacheEntry(
+                operation.setDependency(responseCache.updateCacheEntry(
                         target,
                         request,
                         cacheEntry,
@@ -857,8 +858,8 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
         recordCacheMiss(target, request);
 
         if (mayCallBackend(request)) {
-            final ComplexFuture<?> future = scope.future;
-            future.setDependency(responseCache.getVariantCacheEntriesWithEtags(
+            final CancellableDependency operation = scope.cancellableDependency;
+            operation.setDependency(responseCache.getVariantCacheEntriesWithEtags(
                     target,
                     request,
                     new FutureCallback<Map<String, Variant>>() {
@@ -897,7 +898,7 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
             final AsyncExecChain chain,
             final AsyncExecCallback asyncExecCallback,
             final Map<String, Variant> variants) {
-        final ComplexFuture<?> future = scope.future;
+        final CancellableDependency operation = scope.cancellableDependency;
         final HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequestFromVariants(request, variants);
 
         final Date requestDate = getCurrentDate();
@@ -907,7 +908,7 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
 
             void updateVariantCacheEntry(final HttpResponse backendResponse, final Date responseDate, final Variant matchingVariant) {
                 recordCacheUpdate(scope.clientContext);
-                future.setDependency(responseCache.updateVariantCacheEntry(
+                operation.setDependency(responseCache.updateVariantCacheEntry(
                         target,
                         conditionalRequest,
                         backendResponse,
@@ -924,7 +925,7 @@ public class AsyncCachingExec extends CachingExecBase implements AsyncExecChainH
                                 } else {
                                     try {
                                         final SimpleHttpResponse cacheResponse = responseGenerator.generateResponse(request, responseEntry);
-                                        future.setDependency(responseCache.reuseVariantEntryFor(
+                                        operation.setDependency(responseCache.reuseVariantEntryFor(
                                                 target,
                                                 request,
                                                 matchingVariant,

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
index c2edfdf..a8bb75b 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
@@ -42,6 +42,7 @@ import org.apache.hc.client5.http.cache.ResourceFactory;
 import org.apache.hc.client5.http.cache.ResourceIOException;
 import org.apache.hc.client5.http.impl.Operations;
 import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.concurrent.ComplexCancellable;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpHost;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ComplexCancellable.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ComplexCancellable.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ComplexCancellable.java
deleted file mode 100644
index 55273ef..0000000
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ComplexCancellable.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-package org.apache.hc.client5.http.impl.cache;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.hc.core5.concurrent.Cancellable;
-import org.apache.hc.core5.util.Args;
-
-/**
- * TODO: replace with ComplexCancellable from HttpCore 5.0b2
- */
-final class ComplexCancellable implements Cancellable {
-
-    private final AtomicReference<Cancellable> dependencyRef;
-    private final AtomicBoolean cancelled;
-
-    public ComplexCancellable() {
-        this.dependencyRef = new AtomicReference<>(null);
-        this.cancelled = new AtomicBoolean(false);
-    }
-
-    public boolean isCancelled() {
-        return cancelled.get();
-    }
-
-    public void setDependency(final Cancellable dependency) {
-        Args.notNull(dependency, "dependency");
-        if (!cancelled.get()) {
-            dependencyRef.set(dependency);
-        } else {
-            dependency.cancel();
-        }
-    }
-
-    @Override
-    public boolean cancel() {
-        if (cancelled.compareAndSet(false, true)) {
-            final Cancellable dependency = dependencyRef.getAndSet(null);
-            if (dependency != null) {
-                dependency.cancel();
-            }
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
index 1c0076c..03eb29d 100644
--- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
+++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
@@ -186,7 +186,7 @@ public class Request {
     }
 
     public void abort() throws UnsupportedOperationException {
-        this.request.abort();
+        this.request.cancel();
     }
 
     //// HTTP header operations

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
index c2cd44c..c88a506 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
@@ -227,7 +227,7 @@ public class TestConnectionReuse extends LocalServerTestBase {
                             this.target,
                             httpget);
                     if (this.forceClose) {
-                        httpget.abort();
+                        httpget.cancel();
                     } else {
                         EntityUtils.consume(response.getEntity());
                     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientAbortMethod.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientAbortMethod.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientAbortMethod.java
index d1ca62f..9c07b16 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientAbortMethod.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientAbortMethod.java
@@ -46,8 +46,8 @@ public class ClientAbortMethod {
                 System.out.println("----------------------------------------");
                 System.out.println(response.getCode() + " " + response.getReasonPhrase());
                 // Do not feel like reading the response body
-                // Call abort on the request object
-                httpget.abort();
+                // Call cancel on the request object
+                httpget.cancel();
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/CancellableAware.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/CancellableAware.java b/httpclient5/src/main/java/org/apache/hc/client5/http/CancellableAware.java
deleted file mode 100644
index 137220a..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/CancellableAware.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.hc.client5.http;
-
-import org.apache.hc.core5.concurrent.Cancellable;
-
-/**
- * This interface represents an object that can be made aware of
- * long running, potentially blocking processes.
- *
- * TODO: replace with CancellableDependency from HttpCore 5.0b2
- */
-public interface CancellableAware {
-
-    /**
-     * Sets {@link Cancellable} for the ongoing operation.
-     */
-    void setCancellable(Cancellable cancellable);
-
-    boolean isCancelled();
-
-}
-

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChain.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChain.java b/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChain.java
index fa4f49b..201e12b 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChain.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChain.java
@@ -30,7 +30,7 @@ import java.io.IOException;
 
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.core5.concurrent.ComplexFuture;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
@@ -43,8 +43,7 @@ public interface AsyncExecChain {
         public final String exchangeId;
         public final HttpRoute route;
         public final HttpRequest originalRequest;
-        //TODO: replace with CancellableDependency from HttpCore
-        public final ComplexFuture<?> future;
+        public final CancellableDependency cancellableDependency;
         public final HttpClientContext clientContext;
         public final AsyncExecRuntime execRuntime;
 
@@ -52,13 +51,13 @@ public interface AsyncExecChain {
                 final String exchangeId,
                 final HttpRoute route,
                 final HttpRequest originalRequest,
-                final ComplexFuture<?> future,
+                final CancellableDependency cancellableDependency,
                 final HttpClientContext clientContext,
                 final AsyncExecRuntime execRuntime) {
             this.exchangeId = Args.notBlank(exchangeId, "Exchange id");
             this.route = Args.notNull(route, "Route");
             this.originalRequest = Args.notNull(originalRequest, "Original request");
-            this.future = Args.notNull(future, "Future");
+            this.cancellableDependency = Args.notNull(cancellableDependency, "Dependency");
             this.clientContext = clientContext != null ? clientContext : HttpClientContext.create();
             this.execRuntime = Args.notNull(execRuntime, "Exec runtime");
         }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecRuntime.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecRuntime.java b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecRuntime.java
index 6b1603d..f44ebb5 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecRuntime.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecRuntime.java
@@ -29,10 +29,10 @@ package org.apache.hc.client5.http.classic;
 
 import java.io.IOException;
 
-import org.apache.hc.client5.http.CancellableAware;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpException;
@@ -85,6 +85,6 @@ public interface ExecRuntime {
 
     void setConnectionValidFor(TimeValue duration);
 
-    ExecRuntime fork(CancellableAware cancellableAware);
+    ExecRuntime fork(CancellableDependency cancellableAware);
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/methods/HttpUriRequestBase.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/classic/methods/HttpUriRequestBase.java b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/methods/HttpUriRequestBase.java
index bcc8bfc..698a22e 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/classic/methods/HttpUriRequestBase.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/methods/HttpUriRequestBase.java
@@ -30,50 +30,50 @@ import java.net.URI;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.hc.client5.http.CancellableAware;
 import org.apache.hc.client5.http.config.Configurable;
 import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
 
-public class HttpUriRequestBase extends BasicClassicHttpRequest implements CancellableAware, Configurable {
+public class HttpUriRequestBase extends BasicClassicHttpRequest implements CancellableDependency, Configurable {
 
     private static final long serialVersionUID = 1L;
 
     private RequestConfig requestConfig;
-    private final AtomicBoolean aborted;
+    private final AtomicBoolean cancelled;
     private final AtomicReference<Cancellable> cancellableRef;
 
     public HttpUriRequestBase(final String method, final URI requestUri) {
         super(method, requestUri);
-        this.aborted = new AtomicBoolean(false);
+        this.cancelled = new AtomicBoolean(false);
         this.cancellableRef = new AtomicReference<>(null);
     }
 
-    public void abort() {
-        if (this.aborted.compareAndSet(false, true)) {
+    @Override
+    public boolean cancel() {
+        if (this.cancelled.compareAndSet(false, true)) {
             final Cancellable cancellable = this.cancellableRef.getAndSet(null);
             if (cancellable != null) {
                 cancellable.cancel();
             }
+            return true;
+        } else {
+            return false;
         }
     }
 
     @Override
     public boolean isCancelled() {
-        return isAborted();
-    }
-
-    public boolean isAborted() {
-        return this.aborted.get();
+        return cancelled.get();
     }
 
     /**
      * @since 4.2
      */
     @Override
-    public void setCancellable(final Cancellable cancellable) {
-        if (!this.aborted.get()) {
+    public void setDependency(final Cancellable cancellable) {
+        if (!this.cancelled.get()) {
             this.cancellableRef.set(cancellable);
         }
     }
@@ -88,7 +88,7 @@ public class HttpUriRequestBase extends BasicClassicHttpRequest implements Cance
         if (cancellable != null) {
             cancellable.cancel();
         }
-        this.aborted.set(false);
+        this.cancelled.set(false);
     }
 
     public void setConfig(final RequestConfig requestConfig) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultHttpRequestRetryHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultHttpRequestRetryHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultHttpRequestRetryHandler.java
index ca9cce0..06d522f 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultHttpRequestRetryHandler.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultHttpRequestRetryHandler.java
@@ -153,7 +153,7 @@ public class DefaultHttpRequestRetryHandler implements HttpRequestRetryHandler {
                 }
             }
         }
-        if (request instanceof HttpUriRequestBase && ((HttpUriRequestBase)request).isAborted()) {
+        if (request instanceof HttpUriRequestBase && ((HttpUriRequestBase)request).isCancelled()) {
             return false;
         }
         if (handleAsIdempotent(request)) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java
index e5a8e62..06ce3d6 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncConnectExec.java
@@ -47,7 +47,7 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.routing.HttpRouteDirector;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.concurrent.ComplexFuture;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.HttpException;
@@ -119,7 +119,7 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
 
         final String exchangeId = scope.exchangeId;
         final HttpRoute route = scope.route;
-        final ComplexFuture<?> future = scope.future;
+        final CancellableDependency cancellableDependency = scope.cancellableDependency;
         final HttpClientContext clientContext = scope.clientContext;
         final AsyncExecRuntime execRuntime = scope.execRuntime;
         final State state = new State(route);
@@ -149,7 +149,7 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
             if (log.isDebugEnabled()) {
                 log.debug(exchangeId + ": acquiring connection with route " + route);
             }
-            future.setDependency(execRuntime.acquireConnection(
+            cancellableDependency.setDependency(execRuntime.acquireConnection(
                     route, userToken, clientContext, new FutureCallback<AsyncExecRuntime>() {
 
                         @Override
@@ -184,7 +184,7 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
         final RouteTracker tracker = state.tracker;
         final AsyncExecRuntime execRuntime = scope.execRuntime;
         final HttpRoute route = scope.route;
-        final ComplexFuture<?> future = scope.future;
+        final CancellableDependency operation = scope.cancellableDependency;
         final HttpClientContext clientContext = scope.clientContext;
 
         int step;
@@ -193,7 +193,7 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
             step = routeDirector.nextStep(route, fact);
             switch (step) {
                 case HttpRouteDirector.CONNECT_TARGET:
-                    future.setDependency(execRuntime.connect(clientContext, new FutureCallback<AsyncExecRuntime>() {
+                    operation.setDependency(execRuntime.connect(clientContext, new FutureCallback<AsyncExecRuntime>() {
 
                         @Override
                         public void completed(final AsyncExecRuntime execRuntime) {
@@ -216,7 +216,7 @@ public final class AsyncConnectExec implements AsyncExecChainHandler {
                     return;
 
                 case HttpRouteDirector.CONNECT_PROXY:
-                    future.setDependency(execRuntime.connect(clientContext, new FutureCallback<AsyncExecRuntime>() {
+                    operation.setDependency(execRuntime.connect(clientContext, new FutureCallback<AsyncExecRuntime>() {
 
                         @Override
                         public void completed(final AsyncExecRuntime execRuntime) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncRedirectExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncRedirectExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncRedirectExec.java
index 3975813..56b4aaa 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncRedirectExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncRedirectExec.java
@@ -160,7 +160,7 @@ class AsyncRedirectExec implements AsyncExecChainHandler {
                                 }
                             }
                             state.currentScope = new AsyncExecChain.Scope(scope.exchangeId, newRoute,
-                                    scope.originalRequest, scope.future, clientContext, scope.execRuntime);
+                                    scope.originalRequest, scope.cancellableDependency, clientContext, scope.execRuntime);
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java
index 6398957..d93e80b 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java
@@ -32,7 +32,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.hc.client5.http.CancellableAware;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.classic.ExecRuntime;
 import org.apache.hc.client5.http.config.RequestConfig;
@@ -41,6 +40,7 @@ import org.apache.hc.client5.http.io.HttpClientConnectionManager;
 import org.apache.hc.client5.http.io.LeaseRequest;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
@@ -58,7 +58,7 @@ class InternalExecRuntime implements ExecRuntime, Cancellable {
 
     private final HttpClientConnectionManager manager;
     private final HttpRequestExecutor requestExecutor;
-    private final CancellableAware cancellableAware;
+    private final CancellableDependency cancellableDependency;
     private final AtomicReference<ConnectionEndpoint> endpointRef;
 
     private volatile boolean reusable;
@@ -69,19 +69,19 @@ class InternalExecRuntime implements ExecRuntime, Cancellable {
             final Logger log,
             final HttpClientConnectionManager manager,
             final HttpRequestExecutor requestExecutor,
-            final CancellableAware cancellableAware) {
+            final CancellableDependency cancellableDependency) {
         super();
         this.log = log;
         this.manager = manager;
         this.requestExecutor = requestExecutor;
-        this.cancellableAware = cancellableAware;
+        this.cancellableDependency = cancellableDependency;
         this.endpointRef = new AtomicReference<>(null);
         this.validDuration = TimeValue.NEG_ONE_MILLISECONDS;
     }
 
     @Override
     public boolean isExecutionAborted() {
-        return cancellableAware != null && cancellableAware.isCancelled();
+        return cancellableDependency != null && cancellableDependency.isCancelled();
     }
 
     @Override
@@ -97,19 +97,19 @@ class InternalExecRuntime implements ExecRuntime, Cancellable {
             final Timeout requestTimeout = requestConfig.getConnectionRequestTimeout();
             final LeaseRequest connRequest = manager.lease(route, requestTimeout, object);
             state = object;
-            if (cancellableAware != null) {
-                if (cancellableAware.isCancelled()) {
+            if (cancellableDependency != null) {
+                if (cancellableDependency.isCancelled()) {
                     connRequest.cancel();
                     throw new RequestFailedException("Request aborted");
                 }
-                cancellableAware.setCancellable(connRequest);
+                cancellableDependency.setDependency(connRequest);
             }
             try {
                 final ConnectionEndpoint connectionEndpoint = connRequest.get(requestTimeout.getDuration(), requestTimeout.getTimeUnit());
                 endpointRef.set(connectionEndpoint);
                 reusable = connectionEndpoint.isConnected();
-                if (cancellableAware != null) {
-                    cancellableAware.setCancellable(this);
+                if (cancellableDependency != null) {
+                    cancellableDependency.setDependency(this);
                 }
             } catch(final TimeoutException ex) {
                 throw new ConnectionRequestTimeoutException(ex.getMessage());
@@ -143,8 +143,8 @@ class InternalExecRuntime implements ExecRuntime, Cancellable {
     }
 
     private void connectEndpoint(final ConnectionEndpoint endpoint, final HttpClientContext context) throws IOException {
-        if (cancellableAware != null) {
-            if (cancellableAware.isCancelled()) {
+        if (cancellableDependency != null) {
+            if (cancellableDependency.isCancelled()) {
                 throw new RequestFailedException("Request aborted");
             }
         }
@@ -256,8 +256,8 @@ class InternalExecRuntime implements ExecRuntime, Cancellable {
     }
 
     @Override
-    public ExecRuntime fork(final CancellableAware cancellableAware) {
-        return new InternalExecRuntime(log, manager, requestExecutor, cancellableAware);
+    public ExecRuntime fork(final CancellableDependency cancellableDependency) {
+        return new InternalExecRuntime(log, manager, requestExecutor, cancellableDependency);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java
index e915677..2476856 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java
@@ -31,7 +31,6 @@ import java.io.Closeable;
 import java.io.IOException;
 import java.util.List;
 
-import org.apache.hc.client5.http.CancellableAware;
 import org.apache.hc.client5.http.ClientProtocolException;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.auth.AuthSchemeProvider;
@@ -49,6 +48,7 @@ import org.apache.hc.client5.http.routing.HttpRoutePlanner;
 import org.apache.hc.client5.http.routing.RoutingSupport;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpException;
@@ -160,7 +160,7 @@ class InternalHttpClient extends CloseableHttpClient implements Configurable {
             final HttpRoute route = determineRoute(target, request, localcontext);
             final String exchangeId = ExecSupport.getNextExchangeId();
             final ExecRuntime execRuntime = new InternalExecRuntime(log, connManager, requestExecutor,
-                    request instanceof CancellableAware ? (CancellableAware) request : null);
+                    request instanceof CancellableDependency ? (CancellableDependency) request : null);
             final ExecChain.Scope scope = new ExecChain.Scope(exchangeId, route, request, execRuntime, localcontext);
             final ClassicHttpResponse response = this.execChain.execute(ClassicRequestCopier.INSTANCE.copy(request), scope);
             return CloseableHttpResponse.adapt(response);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java
index 2ecb520..6800e33 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java
@@ -30,7 +30,6 @@ package org.apache.hc.client5.http.impl.classic;
 import java.io.IOException;
 import java.io.InterruptedIOException;
 
-import org.apache.hc.client5.http.CancellableAware;
 import org.apache.hc.client5.http.ClientProtocolException;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.SchemePortResolver;
@@ -45,6 +44,7 @@ import org.apache.hc.client5.http.protocol.RequestClientConnControl;
 import org.apache.hc.client5.http.routing.RoutingSupport;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
@@ -122,7 +122,7 @@ public class MinimalHttpClient extends CloseableHttpClient {
 
         final HttpRoute route = new HttpRoute(RoutingSupport.normalize(target, schemePortResolver));
         final ExecRuntime execRuntime = new InternalExecRuntime(log, connManager, requestExecutor,
-                request instanceof CancellableAware ? (CancellableAware) request : null);
+                request instanceof CancellableDependency ? (CancellableDependency) request : null);
         try {
             if (!execRuntime.isConnectionAcquired()) {
                 execRuntime.acquireConnection(route, null, clientContext);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java
index db823d0..3a77524 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java
@@ -60,7 +60,7 @@ public class TestDefaultHttpRequestRetryHandler {
     @Test
     public void noRetryOnAbortedRequests() throws Exception{
         final HttpGet request = new HttpGet("/");
-        request.abort();
+        request.cancel();
 
         final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/695f353b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java
index 783ba82..3be3b58 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java
@@ -30,7 +30,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import org.apache.hc.client5.http.CancellableAware;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.client5.http.io.ConnectionEndpoint;
@@ -38,6 +37,7 @@ import org.apache.hc.client5.http.io.HttpClientConnectionManager;
 import org.apache.hc.client5.http.io.LeaseRequest;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
@@ -64,7 +64,7 @@ public class TestInternalExecRuntime {
     @Mock
     private HttpRequestExecutor requestExecutor;
     @Mock
-    private CancellableAware cancellableAware;
+    private CancellableDependency cancellableDependency;
     @Mock
     private ConnectionEndpoint connectionEndpoint;
 
@@ -75,7 +75,7 @@ public class TestInternalExecRuntime {
     public void setup() {
         MockitoAnnotations.initMocks(this);
         route = new HttpRoute(new HttpHost("host", 80));
-        execRuntime = new InternalExecRuntime(log, mgr, requestExecutor, cancellableAware);
+        execRuntime = new InternalExecRuntime(log, mgr, requestExecutor, cancellableDependency);
     }
 
     @Test
@@ -100,9 +100,9 @@ public class TestInternalExecRuntime {
         Assert.assertFalse(execRuntime.isConnectionReusable());
 
         Mockito.verify(leaseRequest).get(345, TimeUnit.MILLISECONDS);
-        Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(leaseRequest);
-        Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(execRuntime);
-        Mockito.verify(cancellableAware, Mockito.times(2)).setCancellable(Mockito.<Cancellable>any());
+        Mockito.verify(cancellableDependency, Mockito.times(1)).setDependency(leaseRequest);
+        Mockito.verify(cancellableDependency, Mockito.times(1)).setDependency(execRuntime);
+        Mockito.verify(cancellableDependency, Mockito.times(2)).setDependency(Mockito.<Cancellable>any());
     }
 
     @Test(expected = IllegalStateException.class)


[3/4] httpcomponents-client git commit: HTTP/2 client implementations to support cancellation of ongoing message exchanges without terminating the underlying connections

Posted by ol...@apache.org.
HTTP/2 client implementations to support cancellation of ongoing message exchanges without terminating the underlying connections


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/10126c70
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/10126c70
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/10126c70

Branch: refs/heads/master
Commit: 10126c70ffafc22a2ee5b5df1f8e341eb95546b6
Parents: 695f353
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Fri Jan 12 14:40:32 2018 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Jan 12 14:40:32 2018 +0100

----------------------------------------------------------------------
 .../apache/hc/client5/http/async/AsyncExecRuntime.java   |  2 +-
 .../http/impl/async/Http2AsyncMainClientExec.java        | 11 +++++------
 .../client5/http/impl/async/HttpAsyncMainClientExec.java |  9 +++++----
 .../http/impl/async/InternalHttp2AsyncExecRuntime.java   | 10 ++++++----
 .../http/impl/async/InternalHttpAsyncExecRuntime.java    |  4 ++--
 .../client5/http/impl/async/MinimalHttp2AsyncClient.java |  4 ++--
 6 files changed, 21 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/10126c70/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecRuntime.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecRuntime.java b/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecRuntime.java
index 919457c..7c0b027 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecRuntime.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecRuntime.java
@@ -72,7 +72,7 @@ public interface AsyncExecRuntime {
     /**
      * Initiates a message exchange using the given handler.
      */
-    void execute(
+    Cancellable execute(
             AsyncClientExchangeHandler exchangeHandler,
             HttpClientContext context);
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/10126c70/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncMainClientExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncMainClientExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncMainClientExec.java
index 18c6892..802e405 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncMainClientExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/Http2AsyncMainClientExec.java
@@ -32,12 +32,12 @@ import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.async.AsyncExecCallback;
 import org.apache.hc.client5.http.async.AsyncExecChain;
 import org.apache.hc.client5.http.async.AsyncExecChainHandler;
 import org.apache.hc.client5.http.async.AsyncExecRuntime;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
@@ -65,7 +65,7 @@ class Http2AsyncMainClientExec implements AsyncExecChainHandler {
             final AsyncExecChain chain,
             final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
         final String exchangeId = scope.exchangeId;
-        final HttpRoute route = scope.route;
+        final CancellableDependency operation = scope.cancellableDependency;
         final HttpClientContext clientContext = scope.clientContext;
         final AsyncExecRuntime execRuntime = scope.execRuntime;
 
@@ -158,12 +158,11 @@ class Http2AsyncMainClientExec implements AsyncExecChainHandler {
         };
 
         if (log.isDebugEnabled()) {
-            execRuntime.execute(
+            operation.setDependency(execRuntime.execute(
                     new LoggingAsyncClientExchangeHandler(log, exchangeId, internalExchangeHandler),
-                    clientContext);
+                    clientContext));
         } else {
-            execRuntime.execute(
-                    internalExchangeHandler, clientContext);
+            operation.setDependency(execRuntime.execute( internalExchangeHandler, clientContext));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/10126c70/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java
index 301382c..1c8eabd 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncMainClientExec.java
@@ -41,6 +41,7 @@ import org.apache.hc.client5.http.async.AsyncExecChain;
 import org.apache.hc.client5.http.async.AsyncExecChainHandler;
 import org.apache.hc.client5.http.async.AsyncExecRuntime;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
@@ -79,6 +80,7 @@ class HttpAsyncMainClientExec implements AsyncExecChainHandler {
             final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
         final String exchangeId = scope.exchangeId;
         final HttpRoute route = scope.route;
+        final CancellableDependency operation = scope.cancellableDependency;
         final HttpClientContext clientContext = scope.clientContext;
         final AsyncExecRuntime execRuntime = scope.execRuntime;
 
@@ -217,12 +219,11 @@ class HttpAsyncMainClientExec implements AsyncExecChainHandler {
         };
 
         if (log.isDebugEnabled()) {
-            execRuntime.execute(
+            operation.setDependency(execRuntime.execute(
                     new LoggingAsyncClientExchangeHandler(log, exchangeId, internalExchangeHandler),
-                    clientContext);
+                    clientContext));
         } else {
-            execRuntime.execute(
-                    internalExchangeHandler, clientContext);
+            operation.setDependency(execRuntime.execute(internalExchangeHandler, clientContext));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/10126c70/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2AsyncExecRuntime.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2AsyncExecRuntime.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2AsyncExecRuntime.java
index be8ef7c..5708b39 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2AsyncExecRuntime.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttp2AsyncExecRuntime.java
@@ -37,6 +37,7 @@ import org.apache.hc.client5.http.impl.ConnPoolSupport;
 import org.apache.hc.client5.http.impl.Operations;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.concurrent.ComplexCancellable;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
@@ -190,14 +191,15 @@ class InternalHttp2AsyncExecRuntime implements AsyncExecRuntime {
     }
 
     @Override
-    public void execute(final AsyncClientExchangeHandler exchangeHandler, final HttpClientContext context) {
+    public Cancellable execute(final AsyncClientExchangeHandler exchangeHandler, final HttpClientContext context) {
+        final ComplexCancellable complexCancellable = new ComplexCancellable();
         final Endpoint endpoint = ensureValid();
         final IOSession session = endpoint.session;
         if (!session.isClosed()) {
             if (log.isDebugEnabled()) {
                 log.debug(ConnPoolSupport.getId(endpoint) + ": executing " + ConnPoolSupport.getId(exchangeHandler));
             }
-            session.addLast(new ExecutionCommand(exchangeHandler, context));
+            session.addLast(new ExecutionCommand(exchangeHandler, complexCancellable, context));
         } else {
             final HttpHost target = endpoint.target;
             final RequestConfig requestConfig = context.getRequestConfig();
@@ -210,7 +212,7 @@ class InternalHttp2AsyncExecRuntime implements AsyncExecRuntime {
                     if (log.isDebugEnabled()) {
                         log.debug(ConnPoolSupport.getId(endpoint) + ": executing " + ConnPoolSupport.getId(exchangeHandler));
                     }
-                    session.addLast(new ExecutionCommand(exchangeHandler, context));
+                    session.addLast(new ExecutionCommand(exchangeHandler, complexCancellable, context));
                 }
 
                 @Override
@@ -225,7 +227,7 @@ class InternalHttp2AsyncExecRuntime implements AsyncExecRuntime {
 
             });
         }
-
+        return complexCancellable;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/10126c70/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java
index dc91be1..e48b8dd 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java
@@ -230,7 +230,7 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
     }
 
     @Override
-    public void execute(final AsyncClientExchangeHandler exchangeHandler, final HttpClientContext context) {
+    public Cancellable execute(final AsyncClientExchangeHandler exchangeHandler, final HttpClientContext context) {
         final AsyncConnectionEndpoint endpoint = ensureValid();
         if (endpoint.isConnected()) {
             if (log.isDebugEnabled()) {
@@ -264,7 +264,7 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
 
             });
         }
-
+        return Operations.nonCancellable();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/10126c70/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttp2AsyncClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttp2AsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttp2AsyncClient.java
index 2ba4cbe..77be31b 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttp2AsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttp2AsyncClient.java
@@ -214,9 +214,9 @@ public final class MinimalHttp2AsyncClient extends AbstractMinimalHttpAsyncClien
                                 log.debug(ConnPoolSupport.getId(session) + ": executing message exchange " + exchangeId);
                                 session.addLast(new ExecutionCommand(
                                         new LoggingAsyncClientExchangeHandler(log, exchangeId, internalExchangeHandler),
-                                        clientContext));
+                                        resultFuture, clientContext));
                             } else {
-                                session.addLast(new ExecutionCommand(internalExchangeHandler, clientContext));
+                                session.addLast(new ExecutionCommand(internalExchangeHandler, resultFuture, clientContext));
                             }
                         }
 


[4/4] httpcomponents-client git commit: DefaultHostnameVerifier to use a custom distinguished name (DN) parser instead of LdapName; removed dependency on Java Naming extensions

Posted by ol...@apache.org.
DefaultHostnameVerifier to use a custom distinguished name (DN) parser instead of LdapName; removed dependency on Java Naming extensions


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/1e5fe0e0
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/1e5fe0e0
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/1e5fe0e0

Branch: refs/heads/master
Commit: 1e5fe0e01c3b0d7f61c99462538d4b2fdcdef512
Parents: 10126c7
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Fri Jan 12 18:47:56 2018 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Jan 12 18:47:56 2018 +0100

----------------------------------------------------------------------
 .../http/ssl/DefaultHostnameVerifier.java       |  37 ++---
 .../http/ssl/DistinguishedNameParser.java       | 134 ++++++++++++++++++
 .../http/ssl/TestDistinguishedNameParser.java   | 141 +++++++++++++++++++
 3 files changed, 285 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1e5fe0e0/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
index 6deb749..9d2e160 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultHostnameVerifier.java
@@ -37,14 +37,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
-import java.util.NoSuchElementException;
 
-import javax.naming.InvalidNameException;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
 import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSession;
@@ -54,7 +47,9 @@ import org.apache.hc.client5.http.psl.DomainType;
 import org.apache.hc.client5.http.psl.PublicSuffixMatcher;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.NameValuePair;
 import org.apache.hc.core5.net.InetAddressUtils;
+import org.apache.hc.core5.util.TextUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -255,28 +250,16 @@ public final class DefaultHostnameVerifier implements HttpClientHostnameVerifier
         if (subjectPrincipal == null) {
             return null;
         }
-        try {
-            final LdapName subjectDN = new LdapName(subjectPrincipal);
-            final List<Rdn> rdns = subjectDN.getRdns();
-            for (int i = rdns.size() - 1; i >= 0; i--) {
-                final Rdn rds = rdns.get(i);
-                final Attributes attributes = rds.toAttributes();
-                final Attribute cn = attributes.get("cn");
-                if (cn != null) {
-                    try {
-                        final Object value = cn.get();
-                        if (value != null) {
-                            return value.toString();
-                        }
-                    } catch (final NoSuchElementException | NamingException ignore) {
-                        // ignore exception
-                    }
-                }
+        final List<NameValuePair> attributes = DistinguishedNameParser.INSTANCE.parse(subjectPrincipal);
+        for (final NameValuePair attribute: attributes) {
+            if (TextUtils.isBlank(attribute.getName()) || attribute.getValue() == null) {
+                throw new SSLException(subjectPrincipal + " is not a valid X500 distinguished name");
+            }
+            if (attribute.getName().equalsIgnoreCase("cn")) {
+                return attribute.getValue();
             }
-            return null;
-        } catch (final InvalidNameException e) {
-            throw new SSLException(subjectPrincipal + " is not a valid X500 distinguished name");
         }
+        return null;
     }
 
     static HostNameType determineHostFormat(final String host) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1e5fe0e0/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DistinguishedNameParser.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DistinguishedNameParser.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DistinguishedNameParser.java
new file mode 100644
index 0000000..2d030ec
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DistinguishedNameParser.java
@@ -0,0 +1,134 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.client5.http.ssl;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.NameValuePair;
+import org.apache.hc.core5.http.message.BasicNameValuePair;
+import org.apache.hc.core5.http.message.ParserCursor;
+import org.apache.hc.core5.http.message.TokenParser;
+import org.apache.hc.core5.util.CharArrayBuffer;
+
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+final class DistinguishedNameParser {
+
+    public final static DistinguishedNameParser INSTANCE = new DistinguishedNameParser();
+
+    private static final BitSet EQUAL_OR_COMMA_OR_PLUS      = TokenParser.INIT_BITSET('=', ',', '+');
+    private static final BitSet COMMA_OR_PLUS               = TokenParser.INIT_BITSET(',', '+');
+
+    private final TokenParser tokenParser;
+
+    DistinguishedNameParser() {
+        this.tokenParser = new InternalTokenParser();
+    }
+
+    private String parseToken(final CharArrayBuffer buf, final ParserCursor cursor, final BitSet delimiters) {
+        return tokenParser.parseToken(buf, cursor, delimiters);
+    }
+
+    private String parseValue(final CharArrayBuffer buf, final ParserCursor cursor, final BitSet delimiters) {
+        return tokenParser.parseValue(buf, cursor, delimiters);
+    }
+
+    private NameValuePair parseParameter(final CharArrayBuffer buf, final ParserCursor cursor) {
+        final String name = parseToken(buf, cursor, EQUAL_OR_COMMA_OR_PLUS);
+        if (cursor.atEnd()) {
+            return new BasicNameValuePair(name, null);
+        }
+        final int delim = buf.charAt(cursor.getPos());
+        cursor.updatePos(cursor.getPos() + 1);
+        if (delim == ',') {
+            return new BasicNameValuePair(name, null);
+        }
+        final String value = parseValue(buf, cursor, COMMA_OR_PLUS);
+        if (!cursor.atEnd()) {
+            cursor.updatePos(cursor.getPos() + 1);
+        }
+        return new BasicNameValuePair(name, value);
+    }
+
+    List<NameValuePair> parse(final CharArrayBuffer buf, final ParserCursor cursor) {
+        final List<NameValuePair> params = new ArrayList<>();
+        tokenParser.skipWhiteSpace(buf, cursor);
+        while (!cursor.atEnd()) {
+            final NameValuePair param = parseParameter(buf, cursor);
+            params.add(param);
+        }
+        return params;
+    }
+
+    List<NameValuePair> parse(final String s) {
+        if (s == null) {
+            return null;
+        }
+        final CharArrayBuffer buffer = new CharArrayBuffer(s.length());
+        buffer.append(s);
+        final ParserCursor cursor = new ParserCursor(0, s.length());
+        return parse(buffer, cursor);
+    }
+
+    static class InternalTokenParser extends TokenParser {
+
+        @Override
+        public void copyUnquotedContent(
+                final CharSequence buf,
+                final ParserCursor cursor,
+                final BitSet delimiters,
+                final StringBuilder dst) {
+            int pos = cursor.getPos();
+            final int indexFrom = cursor.getPos();
+            final int indexTo = cursor.getUpperBound();
+            boolean escaped = false;
+            for (int i = indexFrom; i < indexTo; i++, pos++) {
+                final char current = buf.charAt(i);
+                if (escaped) {
+                    dst.append(current);
+                    escaped = false;
+                } else {
+                    if ((delimiters != null && delimiters.get(current))
+                            || TokenParser.isWhitespace(current) || current == '\"') {
+                        break;
+                    } else if (current == '\\') {
+                        escaped = true;
+                    } else {
+                        dst.append(current);
+                    }
+                }
+            }
+            cursor.updatePos(pos);
+        }
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1e5fe0e0/httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestDistinguishedNameParser.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestDistinguishedNameParser.java b/httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestDistinguishedNameParser.java
new file mode 100644
index 0000000..b350885
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestDistinguishedNameParser.java
@@ -0,0 +1,141 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.client5.http.ssl;
+
+import java.util.Arrays;
+
+import org.apache.hc.core5.http.NameValuePair;
+import org.apache.hc.core5.http.message.BasicNameValuePair;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link DistinguishedNameParser}.
+ */
+public class TestDistinguishedNameParser {
+
+    private DistinguishedNameParser impl;
+
+    @Before
+    public void setup() {
+        impl = new DistinguishedNameParser();
+    }
+
+    @Test
+    public void testParseBasic() throws Exception {
+        Assert.assertThat(impl.parse("cn=blah, ou=yada, o=booh"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("cn", "blah"),
+                        new BasicNameValuePair("ou", "yada"),
+                        new BasicNameValuePair("o", "booh"))));
+    }
+
+    @Test
+    public void testParseRepeatedElements() throws Exception {
+        Assert.assertThat(impl.parse("cn=blah, cn=yada, cn=booh"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("cn", "blah"),
+                        new BasicNameValuePair("cn", "yada"),
+                        new BasicNameValuePair("cn", "booh"))));
+    }
+
+    @Test
+    public void testParseBlanks() throws Exception {
+        Assert.assertThat(impl.parse("c = pampa ,  cn  =    blah    , ou = blah , o = blah"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("c", "pampa"),
+                        new BasicNameValuePair("cn", "blah"),
+                        new BasicNameValuePair("ou", "blah"),
+                        new BasicNameValuePair("o", "blah"))));
+    }
+
+    @Test
+    public void testParseQuotes() throws Exception {
+        Assert.assertThat(impl.parse("cn=\"blah\", ou=yada, o=booh"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("cn", "blah"),
+                        new BasicNameValuePair("ou", "yada"),
+                        new BasicNameValuePair("o", "booh"))));
+    }
+
+    @Test
+    public void testParseQuotes2() throws Exception {
+        Assert.assertThat(impl.parse("cn=\"blah  blah\", ou=yada, o=booh"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("cn", "blah  blah"),
+                        new BasicNameValuePair("ou", "yada"),
+                        new BasicNameValuePair("o", "booh"))));
+    }
+
+    @Test
+    public void testParseQuotes3() throws Exception {
+        Assert.assertThat(impl.parse("cn=\"blah, blah\", ou=yada, o=booh"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("cn", "blah, blah"),
+                        new BasicNameValuePair("ou", "yada"),
+                        new BasicNameValuePair("o", "booh"))));
+    }
+
+    @Test
+    public void testParseEscape() throws Exception {
+        Assert.assertThat(impl.parse("cn=blah\\, blah, ou=yada, o=booh"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("cn", "blah, blah"),
+                        new BasicNameValuePair("ou", "yada"),
+                        new BasicNameValuePair("o", "booh"))));
+    }
+
+    @Test
+    public void testParseUnescapedEqual() throws Exception {
+        Assert.assertThat(impl.parse("c = cn=uuh, cn=blah, ou=yada, o=booh"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("c", "cn=uuh"),
+                        new BasicNameValuePair("cn", "blah"),
+                        new BasicNameValuePair("ou", "yada"),
+                        new BasicNameValuePair("o", "booh"))));
+    }
+
+    @Test
+    public void testParseInvalid() throws Exception {
+        Assert.assertThat(impl.parse("blah,blah"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("blah", null),
+                        new BasicNameValuePair("blah", null))));
+    }
+
+    @Test
+    public void testParseInvalid2() throws Exception {
+        Assert.assertThat(impl.parse("cn,o=blah"),
+                CoreMatchers.equalTo(Arrays.<NameValuePair>asList(
+                        new BasicNameValuePair("cn", null),
+                        new BasicNameValuePair("o", "blah"))));
+    }
+
+}