From 9d75647eca3c41a8da2475cd65e2521431a9f9b1 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Mon, 22 Jan 2024 09:33:59 +0100 Subject: [PATCH] Deprecated ConnectionSocketFactory, LayeredConnectionSocketFactory and their plain and SSL implementations in favor of DefaultClientTlsStrategy --- .../CachingHttpClientCompatibilityTest.java | 4 +- .../external/HttpClientCompatibilityTest.java | 4 +- ...java => TestDefaultClientTlsStrategy.java} | 164 +++++++----------- .../sync/extension/TestClientResources.java | 6 +- .../http/impl/async/H2AsyncClientBuilder.java | 4 +- .../http/impl/async/HttpAsyncClients.java | 2 +- .../io/BasicHttpClientConnectionManager.java | 85 ++++++--- .../DefaultHttpClientConnectionOperator.java | 73 +++++--- .../PoolingHttpClientConnectionManager.java | 53 ++++-- ...ingHttpClientConnectionManagerBuilder.java | 46 +++-- .../PoolingAsyncClientConnectionManager.java | 2 +- ...ngAsyncClientConnectionManagerBuilder.java | 4 +- .../http/socket/ConnectionSocketFactory.java | 3 +- .../LayeredConnectionSocketFactory.java | 3 +- .../socket/PlainConnectionSocketFactory.java | 7 +- .../http/ssl/DefaultClientTlsStrategy.java | 26 ++- .../http/ssl/SSLConnectionSocketFactory.java | 6 +- .../SSLConnectionSocketFactoryBuilder.java | 3 +- .../http/examples/ClientConfiguration.java | 7 +- .../ClientCustomPublicSuffixList.java | 7 +- .../http/examples/ClientCustomSSL.java | 10 +- .../TestBasicHttpClientConnectionManager.java | 27 +-- .../io/TestHttpClientConnectionOperator.java | 34 ++-- ...estPoolingHttpClientConnectionManager.java | 28 +-- .../http/ssl/TestSSLSocketFactory.java | 77 -------- 25 files changed, 350 insertions(+), 335 deletions(-) rename httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/{TestSSLSocketFactory.java => TestDefaultClientTlsStrategy.java} (60%) delete mode 100644 httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestSSLSocketFactory.java diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java index 2c0eba70e..59a7e8af8 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java @@ -40,7 +40,7 @@ import org.apache.hc.client5.http.impl.cache.HeapResourceFactory; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpHost; @@ -76,7 +76,7 @@ public class CachingHttpClientCompatibilityTest { final SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build(); this.connManager = PoolingHttpClientConnectionManagerBuilder.create() - .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext)) + .setTlsSocketStrategy(new DefaultClientTlsStrategy(sslContext)) .build(); this.client = CachingHttpClients.custom() .setCacheConfig(CacheConfig.custom() diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpClientCompatibilityTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpClientCompatibilityTest.java index d8fd4f760..bd8c7f4a6 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpClientCompatibilityTest.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpClientCompatibilityTest.java @@ -42,7 +42,7 @@ import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.protocol.HttpClientContext; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.HeaderElements; import org.apache.hc.core5.http.HttpHeaders; @@ -102,7 +102,7 @@ public class HttpClientCompatibilityTest { final SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build(); this.connManager = PoolingHttpClientConnectionManagerBuilder.create() - .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext)) + .setTlsSocketStrategy(new DefaultClientTlsStrategy(sslContext)) .build(); this.client = HttpClients.custom() .setConnectionManager(this.connManager) diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestDefaultClientTlsStrategy.java similarity index 60% rename from httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java rename to httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestDefaultClientTlsStrategy.java index 0a83b6ab5..01d80a275 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestDefaultClientTlsStrategy.java @@ -30,12 +30,10 @@ package org.apache.hc.client5.testing.sync; import static org.hamcrest.MatcherAssert.assertThat; import java.io.IOException; -import java.net.InetSocketAddress; import java.net.Socket; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; -import java.util.concurrent.atomic.AtomicBoolean; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; @@ -43,9 +41,9 @@ import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.client5.testing.SSLTestContexts; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.impl.bootstrap.HttpServer; @@ -55,17 +53,15 @@ import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.io.CloseMode; import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.TrustStrategy; -import org.apache.hc.core5.util.TimeValue; -import org.apache.hc.core5.util.Timeout; import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; /** - * Unit tests for {@link SSLConnectionSocketFactory}. + * Unit tests for {@link DefaultClientTlsStrategy}. */ -public class TestSSLSocketFactory { +public class TestDefaultClientTlsStrategy { private HttpServer server; @@ -103,16 +99,14 @@ public class TestSSLSocketFactory { final HttpContext context = new BasicHttpContext(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy( SSLTestContexts.createClientSSLContext(), hostVerifier); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); - try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( - TimeValue.ZERO_MILLISECONDS, + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { + try (final SSLSocket sslSocket = tlsStrategy.upgrade( socket, - target, - remoteAddress, + target.getHostName(), + target.getPort(), null, context)) { final SSLSession sslsession = sslSocket.getSession(); @@ -123,44 +117,6 @@ public class TestSSLSocketFactory { } } - @Test - public void testBasicSslConnectOverride() throws Exception { - this.server = ServerBootstrap.bootstrap() - .setSslContext(SSLTestContexts.createServerSSLContext()) - .create(); - this.server.start(); - - final HttpContext context = new BasicHttpContext(); - final AtomicBoolean connectCalled = new AtomicBoolean(); - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( - SSLTestContexts.createClientSSLContext()) { - @Override - protected void connectSocket( - final Socket sock, - final InetSocketAddress remoteAddress, - final Timeout connectTimeout, - final HttpContext context) throws IOException { - connectCalled.set(true); - super.connectSocket(sock, remoteAddress, connectTimeout, context); - } - }; - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); - try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( - TimeValue.ZERO_MILLISECONDS, - socket, - target, - remoteAddress, - null, - context)) { - final SSLSession sslsession = sslSocket.getSession(); - Assertions.assertNotNull(sslsession); - Assertions.assertTrue(connectCalled.get()); - } - } - } - @Test public void testBasicDefaultHostnameVerifier() throws Exception { // @formatter:off @@ -171,17 +127,13 @@ public class TestSSLSocketFactory { this.server.start(); final HttpContext context = new BasicHttpContext(); - final SSLConnectionSocketFactory socketFactory = SSLConnectionSocketFactoryBuilder.create() - .setSslContext(SSLTestContexts.createClientSSLContext()) - .build(); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); - try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( - TimeValue.ZERO_MILLISECONDS, + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()); + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { + try (final SSLSocket sslSocket = tlsStrategy.upgrade( socket, - target, - remoteAddress, + target.getHostName(), + target.getPort(), null, context)) { final SSLSession sslsession = sslSocket.getSession(); @@ -202,16 +154,14 @@ public class TestSSLSocketFactory { final HttpContext context = new BasicHttpContext(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy( SSLTestContexts.createClientSSLContext(), hostVerifier); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); - try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( - TimeValue.ZERO_MILLISECONDS, + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { + try (final SSLSocket sslSocket = tlsStrategy.upgrade( socket, - target, - remoteAddress, + target.getHostName(), + target.getPort(), null, context)) { final SSLSession sslsession = sslSocket.getSession(); @@ -234,16 +184,15 @@ public class TestSSLSocketFactory { final HttpContext context = new BasicHttpContext(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy( SSLTestContexts.createClientSSLContext(), hostVerifier); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { Assertions.assertThrows(IOException.class, () -> { - try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( - TimeValue.ZERO_MILLISECONDS, - socket, target, - remoteAddress, + try (final SSLSocket sslSocket = tlsStrategy.upgrade( + socket, + target.getHostName(), + target.getPort(), null, context)) { final SSLSession sslsession = sslSocket.getSession(); @@ -269,15 +218,14 @@ public class TestSSLSocketFactory { // Use default SSL context final SSLContext defaultSslContext = SSLContexts.createDefault(); - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(defaultSslContext, + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(defaultSslContext, NoopHostnameVerifier.INSTANCE); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { Assertions.assertThrows(SSLException.class, () -> { - try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( - TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, null, context)) { + try (final SSLSocket sslSocket = tlsStrategy.upgrade( + socket, target.getHostName(), target.getPort(), null, context)) { // empty for now } }); @@ -306,14 +254,17 @@ public class TestSSLSocketFactory { .loadTrustMaterial(null, trustStrategy) .build(); // @formatter:on - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); - try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, - null, context)) { + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { + try (final SSLSocket sslSocket = tlsStrategy.upgrade( + socket, + target.getHostName(), + target.getPort(), + null, + context)) { // empty for now } } @@ -330,14 +281,17 @@ public class TestSSLSocketFactory { this.server.start(); final HttpContext context = new BasicHttpContext(); - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy( SSLTestContexts.createClientSSLContext()); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { Assertions.assertThrows(IOException.class, () -> - socketFactory.connectSocket( - TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, null, context)); + tlsStrategy.upgrade( + socket, + target.getHostName(), + target.getPort(), + null, + context)); } } @@ -379,12 +333,16 @@ public class TestSSLSocketFactory { this.server.start(); final HttpContext context = new BasicHttpContext(); - final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy( SSLTestContexts.createClientSSLContext()); - try (final Socket socket = socketFactory.createSocket(context)) { - final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); - final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); - socketFactory.connectSocket(TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, null, context); + final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort()); + try (final Socket socket = new Socket(target.getHostName(), target.getPort())) { + tlsStrategy.upgrade( + socket, + target.getHostName(), + target.getPort(), + null, + context); } } } diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/extension/TestClientResources.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/extension/TestClientResources.java index fd79bed3e..fd8f0000a 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/extension/TestClientResources.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/extension/TestClientResources.java @@ -37,7 +37,7 @@ import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.classic.MinimalHttpClient; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.client5.testing.SSLTestContexts; import org.apache.hc.core5.function.Decorator; import org.apache.hc.core5.http.HttpHost; @@ -124,7 +124,7 @@ public class TestClientResources implements BeforeEachCallback, AfterEachCallbac Assertions.assertNull(client); final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create(); - connManagerBuilder.setSSLSocketFactory(new SSLConnectionSocketFactory(SSLTestContexts.createClientSSLContext())); + connManagerBuilder.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext())); connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom() .setSoTimeout(timeout) .build()); @@ -147,7 +147,7 @@ public class TestClientResources implements BeforeEachCallback, AfterEachCallbac Assertions.assertNull(client); final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create(); - connManagerBuilder.setSSLSocketFactory(new SSLConnectionSocketFactory(SSLTestContexts.createClientSSLContext())); + connManagerBuilder.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext())); connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom() .setSoTimeout(timeout) .build()); diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java index 5b0e7e956..56f2265d2 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java @@ -843,9 +843,9 @@ public class H2AsyncClientBuilder { TlsStrategy tlsStrategyCopy = this.tlsStrategy; if (tlsStrategyCopy == null) { if (systemProperties) { - tlsStrategyCopy = DefaultClientTlsStrategy.getSystemDefault(); + tlsStrategyCopy = DefaultClientTlsStrategy.createSystemDefault(); } else { - tlsStrategyCopy = DefaultClientTlsStrategy.getDefault(); + tlsStrategyCopy = DefaultClientTlsStrategy.createDefault(); } } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java index cfe292dd1..84b7b5536 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java @@ -314,7 +314,7 @@ public final class HttpAsyncClients { public static MinimalH2AsyncClient createHttp2Minimal( final H2Config h2Config, final IOReactorConfig ioReactorConfig) { - return createHttp2Minimal(h2Config, ioReactorConfig, DefaultClientTlsStrategy.getDefault()); + return createHttp2Minimal(h2Config, ioReactorConfig, DefaultClientTlsStrategy.createDefault()); } /** diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java index c2adfb767..52155a429 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java @@ -49,9 +49,8 @@ import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.io.HttpClientConnectionOperator; import org.apache.hc.client5.http.io.LeaseRequest; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; -import org.apache.hc.client5.http.socket.ConnectionSocketFactory; -import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.http.ClassicHttpRequest; @@ -60,7 +59,6 @@ import org.apache.hc.core5.http.HttpException; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.URIScheme; import org.apache.hc.core5.http.config.Lookup; -import org.apache.hc.core5.http.config.Registry; import org.apache.hc.core5.http.config.RegistryBuilder; import org.apache.hc.core5.http.impl.io.HttpRequestExecutor; import org.apache.hc.core5.http.io.HttpConnectionFactory; @@ -119,22 +117,6 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan private final AtomicBoolean closed; - private static Registry getDefaultRegistry() { - return RegistryBuilder.create() - .register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory()) - .register(URIScheme.HTTPS.id, SSLConnectionSocketFactory.getSocketFactory()) - .build(); - } - - public BasicHttpClientConnectionManager( - final Lookup socketFactoryRegistry, - final HttpConnectionFactory connFactory, - final SchemePortResolver schemePortResolver, - final DnsResolver dnsResolver) { - this(new DefaultHttpClientConnectionOperator( - socketFactoryRegistry, schemePortResolver, dnsResolver), connFactory); - } - /** * @since 4.4 */ @@ -153,19 +135,76 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan this.lock = new ReentrantLock(); } + /** + * @since 5.4 + */ + public static BasicHttpClientConnectionManager create( + final SchemePortResolver schemePortResolver, + final DnsResolver dnsResolver, + final Lookup tlsSocketStrategyRegistry, + final HttpConnectionFactory connFactory) { + return new BasicHttpClientConnectionManager( + new DefaultHttpClientConnectionOperator(schemePortResolver, dnsResolver, tlsSocketStrategyRegistry), + connFactory); + } + + /** + * @since 5.4 + */ + public static BasicHttpClientConnectionManager create( + final Lookup tlsSocketStrategyRegistry, + final HttpConnectionFactory connFactory) { + return new BasicHttpClientConnectionManager( + new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry), connFactory); + } + + /** + * @since 5.4 + */ + public static BasicHttpClientConnectionManager create( + final Lookup tlsSocketStrategyRegistry) { + return new BasicHttpClientConnectionManager( + new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry), null); + } + + /** + * @deprecated Use {@link #create(SchemePortResolver, DnsResolver, Lookup, HttpConnectionFactory)} + */ + @Deprecated public BasicHttpClientConnectionManager( - final Lookup socketFactoryRegistry, + final Lookup socketFactoryRegistry, + final HttpConnectionFactory connFactory, + final SchemePortResolver schemePortResolver, + final DnsResolver dnsResolver) { + this(new DefaultHttpClientConnectionOperator( + socketFactoryRegistry, schemePortResolver, dnsResolver), connFactory); + } + + /** + * @deprecated Use {@link #create(Lookup, HttpConnectionFactory)} + */ + @Deprecated + public BasicHttpClientConnectionManager( + final Lookup socketFactoryRegistry, final HttpConnectionFactory connFactory) { this(socketFactoryRegistry, connFactory, null, null); } + /** + * @deprecated Use {@link #create(Lookup)} + */ + @Deprecated public BasicHttpClientConnectionManager( - final Lookup socketFactoryRegistry) { + final Lookup socketFactoryRegistry) { this(socketFactoryRegistry, null, null, null); } public BasicHttpClientConnectionManager() { - this(getDefaultRegistry(), null, null, null); + this(new DefaultHttpClientConnectionOperator(null, null, + RegistryBuilder.create() + .register(URIScheme.HTTPS.id, DefaultClientTlsStrategy.createDefault()) + .build()), + null); } @Override diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java index 95b549e7d..e2189d64d 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java @@ -35,6 +35,8 @@ import java.net.SocketAddress; import java.net.UnknownHostException; import java.util.Arrays; +import javax.net.ssl.SSLSocket; + import org.apache.hc.client5.http.ConnectExceptionSupport; import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.SchemePortResolver; @@ -45,8 +47,7 @@ import org.apache.hc.client5.http.impl.DefaultSchemePortResolver; import org.apache.hc.client5.http.io.DetachedSocketFactory; import org.apache.hc.client5.http.io.HttpClientConnectionOperator; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; -import org.apache.hc.client5.http.socket.ConnectionSocketFactory; -import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.annotation.ThreadingBehavior; @@ -86,29 +87,55 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection }; private final DetachedSocketFactory detachedSocketFactory; - private final Lookup socketFactoryRegistry; + private final Lookup tlsSocketStrategyLookup; private final SchemePortResolver schemePortResolver; private final DnsResolver dnsResolver; + /** + * @deprecated Provided for backward compatibility + */ + @Deprecated + static Lookup adapt(final Lookup lookup) { + + return name -> { + final org.apache.hc.client5.http.socket.ConnectionSocketFactory sf = lookup.lookup(name); + return sf instanceof org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory ? (socket, target, port, attachment, context) -> + (SSLSocket) ((org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory) sf).createLayeredSocket(socket, target, port, attachment, context) : null; + }; + + } + + public DefaultHttpClientConnectionOperator( final DetachedSocketFactory detachedSocketFactory, - final Lookup socketFactoryRegistry, final SchemePortResolver schemePortResolver, - final DnsResolver dnsResolver) { + final DnsResolver dnsResolver, + final Lookup tlsSocketStrategyLookup) { super(); this.detachedSocketFactory = Args.notNull(detachedSocketFactory, "Plain socket factory"); - this.socketFactoryRegistry = Args.notNull(socketFactoryRegistry, "Socket factory registry"); + this.tlsSocketStrategyLookup = Args.notNull(tlsSocketStrategyLookup, "Socket factory registry"); this.schemePortResolver = schemePortResolver != null ? schemePortResolver : - DefaultSchemePortResolver.INSTANCE; + DefaultSchemePortResolver.INSTANCE; this.dnsResolver = dnsResolver != null ? dnsResolver : - SystemDefaultDnsResolver.INSTANCE; + SystemDefaultDnsResolver.INSTANCE; + } + + /** + * @deprecated Do not use. + */ + @Deprecated + public DefaultHttpClientConnectionOperator( + final Lookup socketFactoryRegistry, + final SchemePortResolver schemePortResolver, + final DnsResolver dnsResolver) { + this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, adapt(socketFactoryRegistry)); } public DefaultHttpClientConnectionOperator( - final Lookup socketFactoryRegistry, final SchemePortResolver schemePortResolver, - final DnsResolver dnsResolver) { - this(PLAIN_SOCKET_FACTORY, socketFactoryRegistry, schemePortResolver, dnsResolver); + final DnsResolver dnsResolver, + final Lookup tlsSocketStrategyLookup) { + this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, tlsSocketStrategyLookup); } @Override @@ -198,10 +225,9 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection LOG.debug("{}:{} connected {}->{} as {}", host.getHostName(), host.getPort(), localAddress, remoteAddress, ConnPoolSupport.getId(conn)); } - final ConnectionSocketFactory connectionSocketFactory = socketFactoryRegistry != null ? socketFactoryRegistry.lookup(host.getSchemeName()) : null; - if (connectionSocketFactory instanceof LayeredConnectionSocketFactory && URIScheme.HTTPS.same(host.getSchemeName())) { - final LayeredConnectionSocketFactory lsf = (LayeredConnectionSocketFactory) connectionSocketFactory; - final Socket upgradedSocket = lsf.createLayeredSocket(socket, host.getHostName(), port, attachment, context); + final TlsSocketStrategy tlsSocketStrategy = tlsSocketStrategyLookup != null ? tlsSocketStrategyLookup.lookup(host.getSchemeName()) : null; + if (tlsSocketStrategy != null && URIScheme.HTTPS.same(host.getSchemeName())) { + final Socket upgradedSocket = tlsSocketStrategy.upgrade(socket, host.getHostName(), port, attachment, context); conn.bind(upgradedSocket); } return; @@ -240,23 +266,18 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection final HttpHost host, final Object attachment, final HttpContext context) throws IOException { - final ConnectionSocketFactory sf = socketFactoryRegistry.lookup(host.getSchemeName()); - if (sf == null) { + final TlsSocketStrategy tlsSocketStrategy = tlsSocketStrategyLookup != null ? tlsSocketStrategyLookup.lookup(host.getSchemeName()) : null; + if (tlsSocketStrategy == null) { throw new UnsupportedSchemeException(host.getSchemeName() + " protocol is not supported"); } - if (!(sf instanceof LayeredConnectionSocketFactory)) { - throw new UnsupportedSchemeException(host.getSchemeName() + - " protocol does not support connection upgrade"); - } - final LayeredConnectionSocketFactory lsf = (LayeredConnectionSocketFactory) sf; - Socket sock = conn.getSocket(); - if (sock == null) { + final Socket socket = conn.getSocket(); + if (socket == null) { throw new ConnectionClosedException("Connection is closed"); } final int port = this.schemePortResolver.resolve(host); - sock = lsf.createLayeredSocket(sock, host.getHostName(), port, attachment, context); - conn.bind(sock); + final SSLSocket upgradedSocket = tlsSocketStrategy.upgrade(socket, host.getHostName(), port, attachment, context); + conn.bind(upgradedSocket); } } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java index 93b07cf35..8630559c7 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java @@ -48,9 +48,8 @@ import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.io.HttpClientConnectionOperator; import org.apache.hc.client5.http.io.LeaseRequest; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; -import org.apache.hc.client5.http.socket.ConnectionSocketFactory; -import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.annotation.ThreadingBehavior; @@ -120,41 +119,65 @@ public class PoolingHttpClientConnectionManager private volatile Resolver tlsConfigResolver; public PoolingHttpClientConnectionManager() { - this(RegistryBuilder.create() - .register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory()) - .register(URIScheme.HTTPS.id, SSLConnectionSocketFactory.getSocketFactory()) - .build()); + this(new DefaultHttpClientConnectionOperator(null, null, + RegistryBuilder.create() + .register(URIScheme.HTTPS.id, DefaultClientTlsStrategy.createDefault()) + .build()), + PoolConcurrencyPolicy.STRICT, + PoolReusePolicy.LIFO, + TimeValue.NEG_ONE_MILLISECOND, + null); } + /** + * @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder} + */ + @Deprecated public PoolingHttpClientConnectionManager( - final Registry socketFactoryRegistry) { + final Registry socketFactoryRegistry) { this(socketFactoryRegistry, null); } + /** + * @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder} + */ + @Deprecated public PoolingHttpClientConnectionManager( - final Registry socketFactoryRegistry, + final Registry socketFactoryRegistry, final HttpConnectionFactory connFactory) { this(socketFactoryRegistry, PoolConcurrencyPolicy.STRICT, TimeValue.NEG_ONE_MILLISECOND, connFactory); } + /** + * @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder} + */ + @Deprecated public PoolingHttpClientConnectionManager( - final Registry socketFactoryRegistry, + final Registry socketFactoryRegistry, final PoolConcurrencyPolicy poolConcurrencyPolicy, final TimeValue timeToLive, final HttpConnectionFactory connFactory) { this(socketFactoryRegistry, poolConcurrencyPolicy, PoolReusePolicy.LIFO, timeToLive, connFactory); } + /** + * @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder} + */ + @Deprecated public PoolingHttpClientConnectionManager( - final Registry socketFactoryRegistry, + final Registry socketFactoryRegistry, final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolReusePolicy poolReusePolicy, final TimeValue timeToLive) { this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null); } + /** + * @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder} + */ + @Deprecated public PoolingHttpClientConnectionManager( - final Registry socketFactoryRegistry, + final Registry socketFactoryRegistry, final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolReusePolicy poolReusePolicy, final TimeValue timeToLive, @@ -162,8 +185,12 @@ public class PoolingHttpClientConnectionManager this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null, null, connFactory); } + /** + * @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder} + */ + @Deprecated public PoolingHttpClientConnectionManager( - final Registry socketFactoryRegistry, + final Registry socketFactoryRegistry, final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolReusePolicy poolReusePolicy, final TimeValue timeToLive, diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java index 799c6ba86..dd5c543e1 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java @@ -27,16 +27,16 @@ package org.apache.hc.client5.http.impl.io; +import javax.net.ssl.SSLSocket; + import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.TlsConfig; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; -import org.apache.hc.client5.http.socket.ConnectionSocketFactory; -import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; -import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.function.Resolver; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.URIScheme; @@ -76,7 +76,7 @@ import org.apache.hc.core5.util.TimeValue; public class PoolingHttpClientConnectionManagerBuilder { private HttpConnectionFactory connectionFactory; - private LayeredConnectionSocketFactory sslSocketFactory; + private TlsSocketStrategy tlsSocketStrategy; private SchemePortResolver schemePortResolver; private DnsResolver dnsResolver; private PoolConcurrencyPolicy poolConcurrencyPolicy; @@ -108,11 +108,23 @@ public class PoolingHttpClientConnectionManagerBuilder { } /** - * Assigns {@link LayeredConnectionSocketFactory} instance. + * Assigns {@link org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory} instance. + * + * @deprecated Use {@link #setTlsSocketStrategy(TlsSocketStrategy)} */ + @Deprecated public final PoolingHttpClientConnectionManagerBuilder setSSLSocketFactory( - final LayeredConnectionSocketFactory sslSocketFactory) { - this.sslSocketFactory = sslSocketFactory; + final org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory sslSocketFactory) { + this.tlsSocketStrategy = (socket, target, port, attachment, context) -> + (SSLSocket) sslSocketFactory.createLayeredSocket(socket, target, port, context); + return this; + } + + /** + * Assigns {@link TlsSocketStrategy} instance. + */ + public final PoolingHttpClientConnectionManagerBuilder setTlsSocketStrategy(final TlsSocketStrategy tlsSocketStrategy) { + this.tlsSocketStrategy = tlsSocketStrategy; return this; } @@ -262,19 +274,17 @@ public class PoolingHttpClientConnectionManagerBuilder { } public PoolingHttpClientConnectionManager build() { - @SuppressWarnings("resource") final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager( - RegistryBuilder.create() - .register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory()) - .register(URIScheme.HTTPS.id, sslSocketFactory != null ? sslSocketFactory : - (systemProperties ? - SSLConnectionSocketFactory.getSystemSocketFactory() : - SSLConnectionSocketFactory.getSocketFactory())) - .build(), + final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager( + new DefaultHttpClientConnectionOperator(schemePortResolver, dnsResolver, + RegistryBuilder.create() + .register(URIScheme.HTTPS.id, tlsSocketStrategy != null ? tlsSocketStrategy : + (systemProperties ? + DefaultClientTlsStrategy.createSystemDefault() : + DefaultClientTlsStrategy.createDefault())) + .build()), poolConcurrencyPolicy, poolReusePolicy, null, - schemePortResolver, - dnsResolver, connectionFactory); poolingmgr.setSocketConfigResolver(socketConfigResolver); poolingmgr.setConnectionConfigResolver(connectionConfigResolver); diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java index 6ebaf2129..3aa5c4618 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java @@ -129,7 +129,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio public PoolingAsyncClientConnectionManager() { this(RegistryBuilder.create() - .register(URIScheme.HTTPS.getId(), DefaultClientTlsStrategy.getDefault()) + .register(URIScheme.HTTPS.getId(), DefaultClientTlsStrategy.createDefault()) .build()); } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java index 6f72c6bb0..16feeaf7b 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java @@ -242,9 +242,9 @@ public class PoolingAsyncClientConnectionManagerBuilder { } } else { if (systemProperties) { - tlsStrategyCopy = DefaultClientTlsStrategy.getSystemDefault(); + tlsStrategyCopy = DefaultClientTlsStrategy.createSystemDefault(); } else { - tlsStrategyCopy = DefaultClientTlsStrategy.getDefault(); + tlsStrategyCopy = DefaultClientTlsStrategy.createDefault(); } } } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/ConnectionSocketFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/ConnectionSocketFactory.java index 9b0c7b72c..bffa96661 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/ConnectionSocketFactory.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/ConnectionSocketFactory.java @@ -43,9 +43,10 @@ import org.apache.hc.core5.util.Timeout; /** * A factory for creating and connecting connection sockets. * - * @since 4.3 + * @deprecated Do not use. */ @Contract(threading = ThreadingBehavior.STATELESS) +@Deprecated public interface ConnectionSocketFactory { /** diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/LayeredConnectionSocketFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/LayeredConnectionSocketFactory.java index 36dfa80f8..99624a449 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/LayeredConnectionSocketFactory.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/LayeredConnectionSocketFactory.java @@ -37,8 +37,9 @@ import org.apache.hc.core5.http.protocol.HttpContext; /** * Extended {@link ConnectionSocketFactory} interface for layered sockets such as SSL/TLS. * - * @since 4.3 + * @deprecated Use {@link org.apache.hc.client5.http.ssl.TlsSocketStrategy}. */ +@Deprecated @Contract(threading = ThreadingBehavior.STATELESS) public interface LayeredConnectionSocketFactory extends ConnectionSocketFactory { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java index ce2d8fb40..3396bcaa0 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java @@ -46,8 +46,13 @@ import org.apache.hc.core5.util.TimeValue; /** * The default class for creating plain (unencrypted) sockets. * - * @since 4.3 + * @deprecated Use {@link org.apache.hc.client5.http.io.DetachedSocketFactory}. + * Please note this interface is considered internal. + * + * @see org.apache.hc.client5.http.impl.io.DefaultHttpClientConnectionOperator + * @see org.apache.hc.client5.http.io.DetachedSocketFactory */ +@Deprecated @Contract(threading = ThreadingBehavior.STATELESS) public class PlainConnectionSocketFactory implements ConnectionSocketFactory { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java index 1267071a8..861b4c5f9 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java @@ -48,13 +48,19 @@ import org.apache.hc.core5.ssl.SSLContexts; @Contract(threading = ThreadingBehavior.STATELESS) public class DefaultClientTlsStrategy extends AbstractClientTlsStrategy { - public static TlsStrategy getDefault() { + /** + * @since 5.4 + */ + public static DefaultClientTlsStrategy createDefault() { return new DefaultClientTlsStrategy( SSLContexts.createDefault(), HttpsSupport.getDefaultHostnameVerifier()); } - public static TlsStrategy getSystemDefault() { + /** + * @since 5.4 + */ + public static DefaultClientTlsStrategy createSystemDefault() { return new DefaultClientTlsStrategy( SSLContexts.createSystemDefault(), HttpsSupport.getSystemProtocols(), @@ -63,6 +69,22 @@ public class DefaultClientTlsStrategy extends AbstractClientTlsStrategy { HttpsSupport.getDefaultHostnameVerifier()); } + /** + * @deprecated Use {@link #createDefault()}. + */ + @Deprecated + public static TlsStrategy getDefault() { + return createDefault(); + } + + /** + * @deprecated Use {@link #createSystemDefault()}. + */ + @Deprecated + public static TlsStrategy getSystemDefault() { + return createSystemDefault(); + } + /** * @deprecated To be removed. */ diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java index b8cbde45c..3ffe908e3 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java @@ -56,7 +56,6 @@ import javax.net.ssl.SSLSocket; import javax.security.auth.x500.X500Principal; import org.apache.hc.client5.http.config.TlsConfig; -import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.http.HttpHost; @@ -79,10 +78,11 @@ import org.slf4j.LoggerFactory; * SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of * trusted certificates and to authenticate to the HTTPS server using a private key. * - * @since 4.3 + * @deprecated Use {@link DefaultClientTlsStrategy}. */ +@Deprecated @Contract(threading = ThreadingBehavior.STATELESS) -public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactory { +public class SSLConnectionSocketFactory implements org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory { private static final String WEAK_KEY_EXCHANGES = "^(TLS|SSL)_(NULL|ECDH_anon|DH_anon|DH_anon_EXPORT|DHE_RSA_EXPORT|DHE_DSS_EXPORT|" diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactoryBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactoryBuilder.java index 0926dce4c..f91122758 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactoryBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactoryBuilder.java @@ -57,8 +57,9 @@ import org.apache.hc.core5.ssl.SSLContexts; *
  • https.cipherSuites
  • * * - * @since 5.0 + * @deprecated Use {@link DefaultClientTlsStrategy} */ +@Deprecated public class SSLConnectionSocketFactoryBuilder { public static SSLConnectionSocketFactoryBuilder create() { diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientConfiguration.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientConfiguration.java index bb2074766..35246ff02 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientConfiguration.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientConfiguration.java @@ -57,7 +57,8 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.protocol.HttpClientContext; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.http.ClassicHttpRequest; import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.Header; @@ -150,7 +151,7 @@ public class ClientConfiguration { // Create a registry of custom connection socket factories for supported // protocol schemes. - final SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext); + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext); // Use custom DNS resolver to override the system DNS resolution. final DnsResolver dnsResolver = new SystemDefaultDnsResolver() { @@ -168,7 +169,7 @@ public class ClientConfiguration { // Create a connection manager with custom configuration. final PoolingHttpClientConnectionManager connManager = PoolingHttpClientConnectionManagerBuilder.create() - .setSSLSocketFactory(sslConnectionSocketFactory) + .setTlsSocketStrategy(tlsStrategy) .setConnectionFactory(connFactory) .setDnsResolver(dnsResolver) .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT) diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomPublicSuffixList.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomPublicSuffixList.java index 37be07369..3007490f6 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomPublicSuffixList.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomPublicSuffixList.java @@ -38,8 +38,9 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuil import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.psl.PublicSuffixMatcher; import org.apache.hc.client5.http.psl.PublicSuffixMatcherLoader; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.client5.http.ssl.DefaultHostnameVerifier; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.http.config.Lookup; import org.apache.hc.core5.http.config.RegistryBuilder; import org.apache.hc.core5.http.io.entity.EntityUtils; @@ -66,11 +67,11 @@ public class ClientCustomPublicSuffixList { .register(StandardCookieSpec.RELAXED, cookieSpecFactory) .register(StandardCookieSpec.STRICT, cookieSpecFactory) .build(); - final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy( SSLContexts.createDefault(), new DefaultHostnameVerifier(publicSuffixMatcher)); final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() - .setSSLSocketFactory(sslsf) + .setTlsSocketStrategy(tlsStrategy) .build(); try (final CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(cm) diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java index d7b625203..a130b6848 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java @@ -38,8 +38,8 @@ import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.protocol.HttpClientContext; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; +import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.message.StatusLine; import org.apache.hc.core5.http.ssl.TLS; @@ -67,12 +67,10 @@ public class ClientCustomSSL { return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName()); }) .build(); - final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create() - .setSslContext(sslContext) - .build(); + final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext); // Allow TLSv1.3 protocol only final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() - .setSSLSocketFactory(sslSocketFactory) + .setTlsSocketStrategy(tlsStrategy) .setDefaultTlsConfig(TlsConfig.custom() .setHandshakeTimeout(Timeout.ofSeconds(30)) .setSupportedProtocols(TLS.V_1_3) diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java index c567e09bc..94fd2d38c 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java @@ -32,6 +32,8 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLSocket; + import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.SchemePortResolver; @@ -42,8 +44,7 @@ import org.apache.hc.client5.http.io.DetachedSocketFactory; import org.apache.hc.client5.http.io.LeaseRequest; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.protocol.HttpClientContext; -import org.apache.hc.client5.http.socket.ConnectionSocketFactory; -import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.config.Lookup; import org.apache.hc.core5.http.io.HttpConnectionFactory; @@ -65,14 +66,16 @@ public class TestBasicHttpClientConnectionManager { @Mock private HttpConnectionFactory connFactory; @Mock - private Lookup socketFactoryRegistry; + private Lookup tlsSocketStrategyLookup; @Mock private DetachedSocketFactory detachedSocketFactory; @Mock - private LayeredConnectionSocketFactory sslSocketFactory; + private TlsSocketStrategy tlsSocketStrategy; @Mock private Socket socket; @Mock + private SSLSocket upgradedSocket; + @Mock private SchemePortResolver schemePortResolver; @Mock private DnsResolver dnsResolver; @@ -83,7 +86,7 @@ public class TestBasicHttpClientConnectionManager { public void setup() throws Exception { MockitoAnnotations.openMocks(this); mgr = new BasicHttpClientConnectionManager(new DefaultHttpClientConnectionOperator( - detachedSocketFactory, socketFactoryRegistry, schemePortResolver, dnsResolver), + detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup), connFactory); } @@ -385,13 +388,13 @@ public class TestBasicHttpClientConnectionManager { Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); - Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); - Mockito.when(sslSocketFactory.createLayeredSocket( + Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy); + Mockito.when(tlsSocketStrategy.upgrade( Mockito.same(socket), Mockito.eq("somehost"), Mockito.eq(8443), Mockito.any(), - Mockito.any())).thenReturn(socket); + Mockito.any())).thenReturn(upgradedSocket); mgr.connect(endpoint1, null, context); @@ -399,7 +402,7 @@ public class TestBasicHttpClientConnectionManager { Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(detachedSocketFactory, Mockito.times(1)).create(null); Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 234); - Mockito.verify(sslSocketFactory).createLayeredSocket(socket, "somehost", 8443, tlsConfig, context); + Mockito.verify(tlsSocketStrategy).upgrade(socket, "somehost", 8443, tlsConfig, context); mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context); @@ -407,7 +410,7 @@ public class TestBasicHttpClientConnectionManager { Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target); Mockito.verify(detachedSocketFactory, Mockito.times(2)).create(null); Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 123); - Mockito.verify(sslSocketFactory, Mockito.times(2)).createLayeredSocket(socket, "somehost", 8443, tlsConfig, context); + Mockito.verify(tlsSocketStrategy, Mockito.times(2)).upgrade(socket, "somehost", 8443, tlsConfig, context); } @Test @@ -441,7 +444,7 @@ public class TestBasicHttpClientConnectionManager { Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote}); Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); - Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); + Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); mgr.connect(endpoint1, null, context); @@ -456,7 +459,7 @@ public class TestBasicHttpClientConnectionManager { mgr.upgrade(endpoint1, context); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); - Mockito.verify(sslSocketFactory, Mockito.times(1)).createLayeredSocket( + Mockito.verify(tlsSocketStrategy, Mockito.times(1)).upgrade( socket, "somehost", 8443, tlsConfig, context); } diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java index 5d2050100..fd5f1e600 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java @@ -34,6 +34,8 @@ import java.net.Socket; import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLSocket; + import org.apache.hc.client5.http.ConnectTimeoutException; import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.HttpHostConnectException; @@ -42,8 +44,7 @@ import org.apache.hc.client5.http.UnsupportedSchemeException; import org.apache.hc.client5.http.config.TlsConfig; import org.apache.hc.client5.http.io.DetachedSocketFactory; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; -import org.apache.hc.client5.http.socket.ConnectionSocketFactory; -import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.config.Lookup; import org.apache.hc.core5.http.io.SocketConfig; @@ -62,8 +63,8 @@ public class TestHttpClientConnectionOperator { private ManagedHttpClientConnection conn; private Socket socket; private DetachedSocketFactory detachedSocketFactory; - private LayeredConnectionSocketFactory sslSocketFactory; - private Lookup socketFactoryRegistry; + private TlsSocketStrategy tlsSocketStrategy; + private Lookup tlsSocketStrategyLookup; private SchemePortResolver schemePortResolver; private DnsResolver dnsResolver; private DefaultHttpClientConnectionOperator connectionOperator; @@ -73,12 +74,12 @@ public class TestHttpClientConnectionOperator { conn = Mockito.mock(ManagedHttpClientConnection.class); socket = Mockito.mock(Socket.class); detachedSocketFactory = Mockito.mock(DetachedSocketFactory.class); - sslSocketFactory = Mockito.mock(LayeredConnectionSocketFactory.class); - socketFactoryRegistry = Mockito.mock(Lookup.class); + tlsSocketStrategy = Mockito.mock(TlsSocketStrategy.class); + tlsSocketStrategyLookup = Mockito.mock(Lookup.class); schemePortResolver = Mockito.mock(SchemePortResolver.class); dnsResolver = Mockito.mock(DnsResolver.class); connectionOperator = new DefaultHttpClientConnectionOperator( - detachedSocketFactory, socketFactoryRegistry, schemePortResolver, dnsResolver); + detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup); } @Test @@ -131,9 +132,9 @@ public class TestHttpClientConnectionOperator { Mockito.when(schemePortResolver.resolve(host)).thenReturn(443); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); - Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); - final Socket upgradedSocket = Mockito.mock(Socket.class); - Mockito.when(sslSocketFactory.createLayeredSocket( + Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy); + final SSLSocket upgradedSocket = Mockito.mock(SSLSocket.class); + Mockito.when(tlsSocketStrategy.upgrade( Mockito.same(socket), Mockito.eq("somehost"), Mockito.eq(443), @@ -146,7 +147,7 @@ public class TestHttpClientConnectionOperator { Mockito.verify(socket).connect(new InetSocketAddress(ip1, 443), 123); Mockito.verify(conn, Mockito.times(2)).bind(socket); - Mockito.verify(sslSocketFactory).createLayeredSocket(socket, "somehost", 443, tlsConfig, context); + Mockito.verify(tlsSocketStrategy).upgrade(socket, "somehost", 443, tlsConfig, context); Mockito.verify(conn, Mockito.times(1)).bind(upgradedSocket); } @@ -240,19 +241,20 @@ public class TestHttpClientConnectionOperator { Mockito.when(conn.isOpen()).thenReturn(true); Mockito.when(conn.getSocket()).thenReturn(socket); - Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); + Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy); Mockito.when(schemePortResolver.resolve(host)).thenReturn(443); - Mockito.when(sslSocketFactory.createSocket(Mockito.any())).thenReturn(socket); - Mockito.when(sslSocketFactory.createLayeredSocket( + + final SSLSocket upgradedSocket = Mockito.mock(SSLSocket.class); + Mockito.when(tlsSocketStrategy.upgrade( Mockito.any(), Mockito.eq("somehost"), Mockito.eq(443), Mockito.eq(Timeout.ofMilliseconds(345)), - Mockito.any())).thenReturn(socket); + Mockito.any())).thenReturn(upgradedSocket); connectionOperator.upgrade(conn, host, Timeout.ofMilliseconds(345), context); - Mockito.verify(conn).bind(socket); + Mockito.verify(conn).bind(upgradedSocket); } @Test diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java index 4f43ce0c1..8496a8c69 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java @@ -34,6 +34,8 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import javax.net.ssl.SSLSocket; + import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.SchemePortResolver; @@ -44,8 +46,7 @@ import org.apache.hc.client5.http.io.DetachedSocketFactory; import org.apache.hc.client5.http.io.LeaseRequest; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.protocol.HttpClientContext; -import org.apache.hc.client5.http.socket.ConnectionSocketFactory; -import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.config.Lookup; import org.apache.hc.core5.http.io.SocketConfig; @@ -68,14 +69,16 @@ public class TestPoolingHttpClientConnectionManager { @Mock private ManagedHttpClientConnection conn; @Mock - private Lookup socketFactoryRegistry; + private Lookup tlsSocketStrategyLookup; @Mock private DetachedSocketFactory detachedSocketFactory; @Mock - private LayeredConnectionSocketFactory sslSocketFactory; + private TlsSocketStrategy tlsSocketStrategy; @Mock private Socket socket; @Mock + private SSLSocket upgradedSocket; + @Mock private SchemePortResolver schemePortResolver; @Mock private DnsResolver dnsResolver; @@ -90,7 +93,7 @@ public class TestPoolingHttpClientConnectionManager { public void setup() throws Exception { MockitoAnnotations.openMocks(this); mgr = new PoolingHttpClientConnectionManager(new DefaultHttpClientConnectionOperator( - detachedSocketFactory, socketFactoryRegistry, schemePortResolver, dnsResolver), pool, + detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup), pool, null); } @@ -263,13 +266,13 @@ public class TestPoolingHttpClientConnectionManager { Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); - Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); - Mockito.when(sslSocketFactory.createLayeredSocket( + Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy); + Mockito.when(tlsSocketStrategy.upgrade( Mockito.same(socket), Mockito.eq("somehost"), Mockito.eq(8443), Mockito.any(), - Mockito.any())).thenReturn(socket); + Mockito.any())).thenReturn(upgradedSocket); mgr.connect(endpoint1, null, context); @@ -277,7 +280,7 @@ public class TestPoolingHttpClientConnectionManager { Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(detachedSocketFactory, Mockito.times(1)).create(null); Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 234); - Mockito.verify(sslSocketFactory).createLayeredSocket(socket, "somehost", 8443, tlsConfig, context); + Mockito.verify(tlsSocketStrategy).upgrade(socket, "somehost", 8443, tlsConfig, context); mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context); @@ -285,7 +288,7 @@ public class TestPoolingHttpClientConnectionManager { Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target); Mockito.verify(detachedSocketFactory, Mockito.times(2)).create(null); Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 123); - Mockito.verify(sslSocketFactory, Mockito.times(2)).createLayeredSocket(socket, "somehost", 8443, tlsConfig, context); + Mockito.verify(tlsSocketStrategy, Mockito.times(2)).upgrade(socket, "somehost", 8443, tlsConfig, context); } @Test @@ -312,7 +315,6 @@ public class TestPoolingHttpClientConnectionManager { final ConnectionEndpoint endpoint1 = connRequest1.get(Timeout.ofSeconds(1)); Assertions.assertNotNull(endpoint1); - final LayeredConnectionSocketFactory sslsf = Mockito.mock(LayeredConnectionSocketFactory.class); final HttpClientContext context = HttpClientContext.create(); final SocketConfig sconfig = SocketConfig.custom().build(); @@ -330,7 +332,7 @@ public class TestPoolingHttpClientConnectionManager { Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote}); Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); - Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslsf); + Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); mgr.connect(endpoint1, null, context); @@ -346,7 +348,7 @@ public class TestPoolingHttpClientConnectionManager { mgr.upgrade(endpoint1, context); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); - Mockito.verify(sslsf, Mockito.times(1)).createLayeredSocket( + Mockito.verify(tlsSocketStrategy, Mockito.times(1)).upgrade( socket, "somehost", 8443, tlsConfig, context); } diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestSSLSocketFactory.java b/httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestSSLSocketFactory.java deleted file mode 100644 index a798d7ff9..000000000 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/ssl/TestSSLSocketFactory.java +++ /dev/null @@ -1,77 +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 - * . - * - */ - -package org.apache.hc.client5.http.ssl; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -/** - * Unit tests for {@link SSLConnectionSocketFactory}. - */ -public class TestSSLSocketFactory { - - @Test - public void testStrongCipherSuites() { - final String[] strongCipherSuites = { - "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", - "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_256_GCM_SHA384" - }; - for (final String cipherSuite : strongCipherSuites) { - Assertions.assertFalse(SSLConnectionSocketFactory.isWeakCipherSuite(cipherSuite)); - } - } - - @Test - public void testWeakCiphersDisabledByDefault() { - final String[] weakCiphersSuites = { - "SSL_RSA_WITH_RC4_128_SHA", - "SSL_RSA_WITH_3DES_EDE_CBC_SHA", - "TLS_DH_anon_WITH_AES_128_CBC_SHA", - "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", - "SSL_RSA_WITH_NULL_SHA", - "SSL_RSA_WITH_3DES_EDE_CBC_SHA", - "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", - "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", - "TLS_DH_anon_WITH_AES_256_GCM_SHA384", - "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_NULL_SHA256", - "SSL_RSA_EXPORT_WITH_RC4_40_MD5", - "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", - "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", - "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5" - }; - for (final String cipherSuite : weakCiphersSuites) { - Assertions.assertTrue(SSLConnectionSocketFactory.isWeakCipherSuite(cipherSuite)); - } - } - -}