Deprecated ConnectionSocketFactory, LayeredConnectionSocketFactory and their plain and SSL implementations in favor of DefaultClientTlsStrategy

This commit is contained in:
Oleg Kalnichevski 2024-01-22 09:33:59 +01:00
parent c7fa0b1dad
commit 9d75647eca
25 changed files with 350 additions and 335 deletions

View File

@ -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.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; 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.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
@ -76,7 +76,7 @@ public class CachingHttpClientCompatibilityTest {
final SSLContext sslContext = SSLContexts.custom() final SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build(); .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
this.connManager = PoolingHttpClientConnectionManagerBuilder.create() this.connManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext)) .setTlsSocketStrategy(new DefaultClientTlsStrategy(sslContext))
.build(); .build();
this.client = CachingHttpClients.custom() this.client = CachingHttpClients.custom()
.setCacheConfig(CacheConfig.custom() .setCacheConfig(CacheConfig.custom()

View File

@ -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.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext; 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.ClassicHttpResponse;
import org.apache.hc.core5.http.HeaderElements; import org.apache.hc.core5.http.HeaderElements;
import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpHeaders;
@ -102,7 +102,7 @@ public class HttpClientCompatibilityTest {
final SSLContext sslContext = SSLContexts.custom() final SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build(); .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
this.connManager = PoolingHttpClientConnectionManagerBuilder.create() this.connManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext)) .setTlsSocketStrategy(new DefaultClientTlsStrategy(sslContext))
.build(); .build();
this.client = HttpClients.custom() this.client = HttpClients.custom()
.setConnectionManager(this.connManager) .setConnectionManager(this.connManager)

View File

@ -30,12 +30,10 @@ package org.apache.hc.client5.testing.sync;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@ -43,9 +41,9 @@ import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket; 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.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.client5.testing.SSLTestContexts; import org.apache.hc.client5.testing.SSLTestContexts;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.impl.bootstrap.HttpServer; 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.io.CloseMode;
import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy; 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.hamcrest.CoreMatchers;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; 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; private HttpServer server;
@ -103,16 +99,14 @@ public class TestSSLSocketFactory {
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(
SSLTestContexts.createClientSSLContext(), hostVerifier); SSLTestContexts.createClientSSLContext(), hostVerifier);
try (final Socket socket = socketFactory.createSocket(context)) { final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); try (final SSLSocket sslSocket = tlsStrategy.upgrade(
try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(
TimeValue.ZERO_MILLISECONDS,
socket, socket,
target, target.getHostName(),
remoteAddress, target.getPort(),
null, null,
context)) { context)) {
final SSLSession sslsession = sslSocket.getSession(); 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 @Test
public void testBasicDefaultHostnameVerifier() throws Exception { public void testBasicDefaultHostnameVerifier() throws Exception {
// @formatter:off // @formatter:off
@ -171,17 +127,13 @@ public class TestSSLSocketFactory {
this.server.start(); this.server.start();
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
final SSLConnectionSocketFactory socketFactory = SSLConnectionSocketFactoryBuilder.create() final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext());
.setSslContext(SSLTestContexts.createClientSSLContext()) final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
.build(); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
try (final Socket socket = socketFactory.createSocket(context)) { try (final SSLSocket sslSocket = tlsStrategy.upgrade(
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, socket,
target, target.getHostName(),
remoteAddress, target.getPort(),
null, null,
context)) { context)) {
final SSLSession sslsession = sslSocket.getSession(); final SSLSession sslsession = sslSocket.getSession();
@ -202,16 +154,14 @@ public class TestSSLSocketFactory {
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(
SSLTestContexts.createClientSSLContext(), hostVerifier); SSLTestContexts.createClientSSLContext(), hostVerifier);
try (final Socket socket = socketFactory.createSocket(context)) { final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); try (final SSLSocket sslSocket = tlsStrategy.upgrade(
try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(
TimeValue.ZERO_MILLISECONDS,
socket, socket,
target, target.getHostName(),
remoteAddress, target.getPort(),
null, null,
context)) { context)) {
final SSLSession sslsession = sslSocket.getSession(); final SSLSession sslsession = sslSocket.getSession();
@ -234,16 +184,15 @@ public class TestSSLSocketFactory {
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier(); final TestX509HostnameVerifier hostVerifier = new TestX509HostnameVerifier();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(
SSLTestContexts.createClientSSLContext(), hostVerifier); SSLTestContexts.createClientSSLContext(), hostVerifier);
try (final Socket socket = socketFactory.createSocket(context)) { final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort());
Assertions.assertThrows(IOException.class, () -> { Assertions.assertThrows(IOException.class, () -> {
try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( try (final SSLSocket sslSocket = tlsStrategy.upgrade(
TimeValue.ZERO_MILLISECONDS, socket,
socket, target, target.getHostName(),
remoteAddress, target.getPort(),
null, null,
context)) { context)) {
final SSLSession sslsession = sslSocket.getSession(); final SSLSession sslsession = sslSocket.getSession();
@ -269,15 +218,14 @@ public class TestSSLSocketFactory {
// Use default SSL context // Use default SSL context
final SSLContext defaultSslContext = SSLContexts.createDefault(); final SSLContext defaultSslContext = SSLContexts.createDefault();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(defaultSslContext, final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(defaultSslContext,
NoopHostnameVerifier.INSTANCE); NoopHostnameVerifier.INSTANCE);
try (final Socket socket = socketFactory.createSocket(context)) { final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort());
Assertions.assertThrows(SSLException.class, () -> { Assertions.assertThrows(SSLException.class, () -> {
try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket( try (final SSLSocket sslSocket = tlsStrategy.upgrade(
TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, null, context)) { socket, target.getHostName(), target.getPort(), null, context)) {
// empty for now // empty for now
} }
}); });
@ -306,14 +254,17 @@ public class TestSSLSocketFactory {
.loadTrustMaterial(null, trustStrategy) .loadTrustMaterial(null, trustStrategy)
.build(); .build();
// @formatter:on // @formatter:on
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext,
NoopHostnameVerifier.INSTANCE); NoopHostnameVerifier.INSTANCE);
try (final Socket socket = socketFactory.createSocket(context)) { final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); try (final SSLSocket sslSocket = tlsStrategy.upgrade(
try (final SSLSocket sslSocket = (SSLSocket) socketFactory.connectSocket(TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, socket,
null, context)) { target.getHostName(),
target.getPort(),
null,
context)) {
// empty for now // empty for now
} }
} }
@ -330,14 +281,17 @@ public class TestSSLSocketFactory {
this.server.start(); this.server.start();
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(
SSLTestContexts.createClientSSLContext()); SSLTestContexts.createClientSSLContext());
try (final Socket socket = socketFactory.createSocket(context)) { final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort());
Assertions.assertThrows(IOException.class, () -> Assertions.assertThrows(IOException.class, () ->
socketFactory.connectSocket( tlsStrategy.upgrade(
TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, null, context)); socket,
target.getHostName(),
target.getPort(),
null,
context));
} }
} }
@ -379,12 +333,16 @@ public class TestSSLSocketFactory {
this.server.start(); this.server.start();
final HttpContext context = new BasicHttpContext(); final HttpContext context = new BasicHttpContext();
final SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(
SSLTestContexts.createClientSSLContext()); SSLTestContexts.createClientSSLContext());
try (final Socket socket = socketFactory.createSocket(context)) { final HttpHost target = new HttpHost("https", "localhost", server.getLocalPort());
final InetSocketAddress remoteAddress = new InetSocketAddress("localhost", this.server.getLocalPort()); try (final Socket socket = new Socket(target.getHostName(), target.getPort())) {
final HttpHost target = new HttpHost("https", "localhost", this.server.getLocalPort()); tlsStrategy.upgrade(
socketFactory.connectSocket(TimeValue.ZERO_MILLISECONDS, socket, target, remoteAddress, null, context); socket,
target.getHostName(),
target.getPort(),
null,
context);
} }
} }
} }

View File

@ -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.classic.MinimalHttpClient;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; 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.client5.testing.SSLTestContexts;
import org.apache.hc.core5.function.Decorator; import org.apache.hc.core5.function.Decorator;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
@ -124,7 +124,7 @@ public class TestClientResources implements BeforeEachCallback, AfterEachCallbac
Assertions.assertNull(client); Assertions.assertNull(client);
final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create(); final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
connManagerBuilder.setSSLSocketFactory(new SSLConnectionSocketFactory(SSLTestContexts.createClientSSLContext())); connManagerBuilder.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom() connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom()
.setSoTimeout(timeout) .setSoTimeout(timeout)
.build()); .build());
@ -147,7 +147,7 @@ public class TestClientResources implements BeforeEachCallback, AfterEachCallbac
Assertions.assertNull(client); Assertions.assertNull(client);
final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create(); final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
connManagerBuilder.setSSLSocketFactory(new SSLConnectionSocketFactory(SSLTestContexts.createClientSSLContext())); connManagerBuilder.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom() connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom()
.setSoTimeout(timeout) .setSoTimeout(timeout)
.build()); .build());

View File

@ -843,9 +843,9 @@ public class H2AsyncClientBuilder {
TlsStrategy tlsStrategyCopy = this.tlsStrategy; TlsStrategy tlsStrategyCopy = this.tlsStrategy;
if (tlsStrategyCopy == null) { if (tlsStrategyCopy == null) {
if (systemProperties) { if (systemProperties) {
tlsStrategyCopy = DefaultClientTlsStrategy.getSystemDefault(); tlsStrategyCopy = DefaultClientTlsStrategy.createSystemDefault();
} else { } else {
tlsStrategyCopy = DefaultClientTlsStrategy.getDefault(); tlsStrategyCopy = DefaultClientTlsStrategy.createDefault();
} }
} }

View File

@ -314,7 +314,7 @@ public final class HttpAsyncClients {
public static MinimalH2AsyncClient createHttp2Minimal( public static MinimalH2AsyncClient createHttp2Minimal(
final H2Config h2Config, final H2Config h2Config,
final IOReactorConfig ioReactorConfig) { final IOReactorConfig ioReactorConfig) {
return createHttp2Minimal(h2Config, ioReactorConfig, DefaultClientTlsStrategy.getDefault()); return createHttp2Minimal(h2Config, ioReactorConfig, DefaultClientTlsStrategy.createDefault());
} }
/** /**

View File

@ -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.HttpClientConnectionOperator;
import org.apache.hc.client5.http.io.LeaseRequest; import org.apache.hc.client5.http.io.LeaseRequest;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest; 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.HttpHost;
import org.apache.hc.core5.http.URIScheme; import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.config.Lookup; 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.config.RegistryBuilder;
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor; import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
import org.apache.hc.core5.http.io.HttpConnectionFactory; import org.apache.hc.core5.http.io.HttpConnectionFactory;
@ -119,22 +117,6 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
private final AtomicBoolean closed; private final AtomicBoolean closed;
private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
return RegistryBuilder.<ConnectionSocketFactory>create()
.register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory())
.register(URIScheme.HTTPS.id, SSLConnectionSocketFactory.getSocketFactory())
.build();
}
public BasicHttpClientConnectionManager(
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver) {
this(new DefaultHttpClientConnectionOperator(
socketFactoryRegistry, schemePortResolver, dnsResolver), connFactory);
}
/** /**
* @since 4.4 * @since 4.4
*/ */
@ -153,19 +135,76 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
this.lock = new ReentrantLock(); this.lock = new ReentrantLock();
} }
/**
* @since 5.4
*/
public static BasicHttpClientConnectionManager create(
final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver,
final Lookup<TlsSocketStrategy> tlsSocketStrategyRegistry,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
return new BasicHttpClientConnectionManager(
new DefaultHttpClientConnectionOperator(schemePortResolver, dnsResolver, tlsSocketStrategyRegistry),
connFactory);
}
/**
* @since 5.4
*/
public static BasicHttpClientConnectionManager create(
final Lookup<TlsSocketStrategy> tlsSocketStrategyRegistry,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
return new BasicHttpClientConnectionManager(
new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry), connFactory);
}
/**
* @since 5.4
*/
public static BasicHttpClientConnectionManager create(
final Lookup<TlsSocketStrategy> tlsSocketStrategyRegistry) {
return new BasicHttpClientConnectionManager(
new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry), null);
}
/**
* @deprecated Use {@link #create(SchemePortResolver, DnsResolver, Lookup, HttpConnectionFactory)}
*/
@Deprecated
public BasicHttpClientConnectionManager( public BasicHttpClientConnectionManager(
final Lookup<ConnectionSocketFactory> socketFactoryRegistry, final Lookup<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final HttpConnectionFactory<ManagedHttpClientConnection> 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<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) { final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
this(socketFactoryRegistry, connFactory, null, null); this(socketFactoryRegistry, connFactory, null, null);
} }
/**
* @deprecated Use {@link #create(Lookup)}
*/
@Deprecated
public BasicHttpClientConnectionManager( public BasicHttpClientConnectionManager(
final Lookup<ConnectionSocketFactory> socketFactoryRegistry) { final Lookup<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry) {
this(socketFactoryRegistry, null, null, null); this(socketFactoryRegistry, null, null, null);
} }
public BasicHttpClientConnectionManager() { public BasicHttpClientConnectionManager() {
this(getDefaultRegistry(), null, null, null); this(new DefaultHttpClientConnectionOperator(null, null,
RegistryBuilder.<TlsSocketStrategy>create()
.register(URIScheme.HTTPS.id, DefaultClientTlsStrategy.createDefault())
.build()),
null);
} }
@Override @Override

View File

@ -35,6 +35,8 @@ import java.net.SocketAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import javax.net.ssl.SSLSocket;
import org.apache.hc.client5.http.ConnectExceptionSupport; import org.apache.hc.client5.http.ConnectExceptionSupport;
import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.DnsResolver;
import org.apache.hc.client5.http.SchemePortResolver; 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.DetachedSocketFactory;
import org.apache.hc.client5.http.io.HttpClientConnectionOperator; import org.apache.hc.client5.http.io.HttpClientConnectionOperator;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
@ -86,29 +87,55 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
}; };
private final DetachedSocketFactory detachedSocketFactory; private final DetachedSocketFactory detachedSocketFactory;
private final Lookup<ConnectionSocketFactory> socketFactoryRegistry; private final Lookup<TlsSocketStrategy> tlsSocketStrategyLookup;
private final SchemePortResolver schemePortResolver; private final SchemePortResolver schemePortResolver;
private final DnsResolver dnsResolver; private final DnsResolver dnsResolver;
/**
* @deprecated Provided for backward compatibility
*/
@Deprecated
static Lookup<TlsSocketStrategy> adapt(final Lookup<org.apache.hc.client5.http.socket.ConnectionSocketFactory> 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( public DefaultHttpClientConnectionOperator(
final DetachedSocketFactory detachedSocketFactory, final DetachedSocketFactory detachedSocketFactory,
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
final SchemePortResolver schemePortResolver, final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver) { final DnsResolver dnsResolver,
final Lookup<TlsSocketStrategy> tlsSocketStrategyLookup) {
super(); super();
this.detachedSocketFactory = Args.notNull(detachedSocketFactory, "Plain socket factory"); 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 : this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
DefaultSchemePortResolver.INSTANCE; DefaultSchemePortResolver.INSTANCE;
this.dnsResolver = dnsResolver != null ? dnsResolver : this.dnsResolver = dnsResolver != null ? dnsResolver :
SystemDefaultDnsResolver.INSTANCE; SystemDefaultDnsResolver.INSTANCE;
}
/**
* @deprecated Do not use.
*/
@Deprecated
public DefaultHttpClientConnectionOperator(
final Lookup<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver) {
this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, adapt(socketFactoryRegistry));
} }
public DefaultHttpClientConnectionOperator( public DefaultHttpClientConnectionOperator(
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
final SchemePortResolver schemePortResolver, final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver) { final DnsResolver dnsResolver,
this(PLAIN_SOCKET_FACTORY, socketFactoryRegistry, schemePortResolver, dnsResolver); final Lookup<TlsSocketStrategy> tlsSocketStrategyLookup) {
this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, tlsSocketStrategyLookup);
} }
@Override @Override
@ -198,10 +225,9 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
LOG.debug("{}:{} connected {}->{} as {}", LOG.debug("{}:{} connected {}->{} as {}",
host.getHostName(), host.getPort(), localAddress, remoteAddress, ConnPoolSupport.getId(conn)); host.getHostName(), host.getPort(), localAddress, remoteAddress, ConnPoolSupport.getId(conn));
} }
final ConnectionSocketFactory connectionSocketFactory = socketFactoryRegistry != null ? socketFactoryRegistry.lookup(host.getSchemeName()) : null; final TlsSocketStrategy tlsSocketStrategy = tlsSocketStrategyLookup != null ? tlsSocketStrategyLookup.lookup(host.getSchemeName()) : null;
if (connectionSocketFactory instanceof LayeredConnectionSocketFactory && URIScheme.HTTPS.same(host.getSchemeName())) { if (tlsSocketStrategy != null && URIScheme.HTTPS.same(host.getSchemeName())) {
final LayeredConnectionSocketFactory lsf = (LayeredConnectionSocketFactory) connectionSocketFactory; final Socket upgradedSocket = tlsSocketStrategy.upgrade(socket, host.getHostName(), port, attachment, context);
final Socket upgradedSocket = lsf.createLayeredSocket(socket, host.getHostName(), port, attachment, context);
conn.bind(upgradedSocket); conn.bind(upgradedSocket);
} }
return; return;
@ -240,23 +266,18 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
final HttpHost host, final HttpHost host,
final Object attachment, final Object attachment,
final HttpContext context) throws IOException { final HttpContext context) throws IOException {
final ConnectionSocketFactory sf = socketFactoryRegistry.lookup(host.getSchemeName()); final TlsSocketStrategy tlsSocketStrategy = tlsSocketStrategyLookup != null ? tlsSocketStrategyLookup.lookup(host.getSchemeName()) : null;
if (sf == null) { if (tlsSocketStrategy == null) {
throw new UnsupportedSchemeException(host.getSchemeName() + throw new UnsupportedSchemeException(host.getSchemeName() +
" protocol is not supported"); " protocol is not supported");
} }
if (!(sf instanceof LayeredConnectionSocketFactory)) { final Socket socket = conn.getSocket();
throw new UnsupportedSchemeException(host.getSchemeName() + if (socket == null) {
" protocol does not support connection upgrade");
}
final LayeredConnectionSocketFactory lsf = (LayeredConnectionSocketFactory) sf;
Socket sock = conn.getSocket();
if (sock == null) {
throw new ConnectionClosedException("Connection is closed"); throw new ConnectionClosedException("Connection is closed");
} }
final int port = this.schemePortResolver.resolve(host); final int port = this.schemePortResolver.resolve(host);
sock = lsf.createLayeredSocket(sock, host.getHostName(), port, attachment, context); final SSLSocket upgradedSocket = tlsSocketStrategy.upgrade(socket, host.getHostName(), port, attachment, context);
conn.bind(sock); conn.bind(upgradedSocket);
} }
} }

View File

@ -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.HttpClientConnectionOperator;
import org.apache.hc.client5.http.io.LeaseRequest; import org.apache.hc.client5.http.io.LeaseRequest;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.Internal; import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
@ -120,41 +119,65 @@ public class PoolingHttpClientConnectionManager
private volatile Resolver<HttpHost, TlsConfig> tlsConfigResolver; private volatile Resolver<HttpHost, TlsConfig> tlsConfigResolver;
public PoolingHttpClientConnectionManager() { public PoolingHttpClientConnectionManager() {
this(RegistryBuilder.<ConnectionSocketFactory>create() this(new DefaultHttpClientConnectionOperator(null, null,
.register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory()) RegistryBuilder.<TlsSocketStrategy>create()
.register(URIScheme.HTTPS.id, SSLConnectionSocketFactory.getSocketFactory()) .register(URIScheme.HTTPS.id, DefaultClientTlsStrategy.createDefault())
.build()); .build()),
PoolConcurrencyPolicy.STRICT,
PoolReusePolicy.LIFO,
TimeValue.NEG_ONE_MILLISECOND,
null);
} }
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager( public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry) { final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry) {
this(socketFactoryRegistry, null); this(socketFactoryRegistry, null);
} }
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager( public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry, final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) { final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
this(socketFactoryRegistry, PoolConcurrencyPolicy.STRICT, TimeValue.NEG_ONE_MILLISECOND, connFactory); this(socketFactoryRegistry, PoolConcurrencyPolicy.STRICT, TimeValue.NEG_ONE_MILLISECOND, connFactory);
} }
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager( public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry, final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolConcurrencyPolicy poolConcurrencyPolicy,
final TimeValue timeToLive, final TimeValue timeToLive,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) { final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
this(socketFactoryRegistry, poolConcurrencyPolicy, PoolReusePolicy.LIFO, timeToLive, connFactory); this(socketFactoryRegistry, poolConcurrencyPolicy, PoolReusePolicy.LIFO, timeToLive, connFactory);
} }
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager( public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry, final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolConcurrencyPolicy poolConcurrencyPolicy,
final PoolReusePolicy poolReusePolicy, final PoolReusePolicy poolReusePolicy,
final TimeValue timeToLive) { final TimeValue timeToLive) {
this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null); this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null);
} }
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager( public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry, final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolConcurrencyPolicy poolConcurrencyPolicy,
final PoolReusePolicy poolReusePolicy, final PoolReusePolicy poolReusePolicy,
final TimeValue timeToLive, final TimeValue timeToLive,
@ -162,8 +185,12 @@ public class PoolingHttpClientConnectionManager
this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null, null, connFactory); this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null, null, connFactory);
} }
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager( public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry, final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final PoolConcurrencyPolicy poolConcurrencyPolicy, final PoolConcurrencyPolicy poolConcurrencyPolicy,
final PoolReusePolicy poolReusePolicy, final PoolReusePolicy poolReusePolicy,
final TimeValue timeToLive, final TimeValue timeToLive,

View File

@ -27,16 +27,16 @@
package org.apache.hc.client5.http.impl.io; 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.DnsResolver;
import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.SchemePortResolver;
import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.TlsConfig; import org.apache.hc.client5.http.config.TlsConfig;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.function.Resolver; import org.apache.hc.core5.function.Resolver;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.URIScheme; import org.apache.hc.core5.http.URIScheme;
@ -76,7 +76,7 @@ import org.apache.hc.core5.util.TimeValue;
public class PoolingHttpClientConnectionManagerBuilder { public class PoolingHttpClientConnectionManagerBuilder {
private HttpConnectionFactory<ManagedHttpClientConnection> connectionFactory; private HttpConnectionFactory<ManagedHttpClientConnection> connectionFactory;
private LayeredConnectionSocketFactory sslSocketFactory; private TlsSocketStrategy tlsSocketStrategy;
private SchemePortResolver schemePortResolver; private SchemePortResolver schemePortResolver;
private DnsResolver dnsResolver; private DnsResolver dnsResolver;
private PoolConcurrencyPolicy poolConcurrencyPolicy; 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( public final PoolingHttpClientConnectionManagerBuilder setSSLSocketFactory(
final LayeredConnectionSocketFactory sslSocketFactory) { final org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory sslSocketFactory) {
this.sslSocketFactory = 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; return this;
} }
@ -262,19 +274,17 @@ public class PoolingHttpClientConnectionManagerBuilder {
} }
public PoolingHttpClientConnectionManager build() { public PoolingHttpClientConnectionManager build() {
@SuppressWarnings("resource") final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager( final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create() new DefaultHttpClientConnectionOperator(schemePortResolver, dnsResolver,
.register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory()) RegistryBuilder.<TlsSocketStrategy>create()
.register(URIScheme.HTTPS.id, sslSocketFactory != null ? sslSocketFactory : .register(URIScheme.HTTPS.id, tlsSocketStrategy != null ? tlsSocketStrategy :
(systemProperties ? (systemProperties ?
SSLConnectionSocketFactory.getSystemSocketFactory() : DefaultClientTlsStrategy.createSystemDefault() :
SSLConnectionSocketFactory.getSocketFactory())) DefaultClientTlsStrategy.createDefault()))
.build(), .build()),
poolConcurrencyPolicy, poolConcurrencyPolicy,
poolReusePolicy, poolReusePolicy,
null, null,
schemePortResolver,
dnsResolver,
connectionFactory); connectionFactory);
poolingmgr.setSocketConfigResolver(socketConfigResolver); poolingmgr.setSocketConfigResolver(socketConfigResolver);
poolingmgr.setConnectionConfigResolver(connectionConfigResolver); poolingmgr.setConnectionConfigResolver(connectionConfigResolver);

View File

@ -129,7 +129,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
public PoolingAsyncClientConnectionManager() { public PoolingAsyncClientConnectionManager() {
this(RegistryBuilder.<TlsStrategy>create() this(RegistryBuilder.<TlsStrategy>create()
.register(URIScheme.HTTPS.getId(), DefaultClientTlsStrategy.getDefault()) .register(URIScheme.HTTPS.getId(), DefaultClientTlsStrategy.createDefault())
.build()); .build());
} }

View File

@ -242,9 +242,9 @@ public class PoolingAsyncClientConnectionManagerBuilder {
} }
} else { } else {
if (systemProperties) { if (systemProperties) {
tlsStrategyCopy = DefaultClientTlsStrategy.getSystemDefault(); tlsStrategyCopy = DefaultClientTlsStrategy.createSystemDefault();
} else { } else {
tlsStrategyCopy = DefaultClientTlsStrategy.getDefault(); tlsStrategyCopy = DefaultClientTlsStrategy.createDefault();
} }
} }
} }

View File

@ -43,9 +43,10 @@ import org.apache.hc.core5.util.Timeout;
/** /**
* A factory for creating and connecting connection sockets. * A factory for creating and connecting connection sockets.
* *
* @since 4.3 * @deprecated Do not use.
*/ */
@Contract(threading = ThreadingBehavior.STATELESS) @Contract(threading = ThreadingBehavior.STATELESS)
@Deprecated
public interface ConnectionSocketFactory { public interface ConnectionSocketFactory {
/** /**

View File

@ -37,8 +37,9 @@ import org.apache.hc.core5.http.protocol.HttpContext;
/** /**
* Extended {@link ConnectionSocketFactory} interface for layered sockets such as SSL/TLS. * 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) @Contract(threading = ThreadingBehavior.STATELESS)
public interface LayeredConnectionSocketFactory extends ConnectionSocketFactory { public interface LayeredConnectionSocketFactory extends ConnectionSocketFactory {

View File

@ -46,8 +46,13 @@ import org.apache.hc.core5.util.TimeValue;
/** /**
* The default class for creating plain (unencrypted) sockets. * 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) @Contract(threading = ThreadingBehavior.STATELESS)
public class PlainConnectionSocketFactory implements ConnectionSocketFactory { public class PlainConnectionSocketFactory implements ConnectionSocketFactory {

View File

@ -48,13 +48,19 @@ import org.apache.hc.core5.ssl.SSLContexts;
@Contract(threading = ThreadingBehavior.STATELESS) @Contract(threading = ThreadingBehavior.STATELESS)
public class DefaultClientTlsStrategy extends AbstractClientTlsStrategy { public class DefaultClientTlsStrategy extends AbstractClientTlsStrategy {
public static TlsStrategy getDefault() { /**
* @since 5.4
*/
public static DefaultClientTlsStrategy createDefault() {
return new DefaultClientTlsStrategy( return new DefaultClientTlsStrategy(
SSLContexts.createDefault(), SSLContexts.createDefault(),
HttpsSupport.getDefaultHostnameVerifier()); HttpsSupport.getDefaultHostnameVerifier());
} }
public static TlsStrategy getSystemDefault() { /**
* @since 5.4
*/
public static DefaultClientTlsStrategy createSystemDefault() {
return new DefaultClientTlsStrategy( return new DefaultClientTlsStrategy(
SSLContexts.createSystemDefault(), SSLContexts.createSystemDefault(),
HttpsSupport.getSystemProtocols(), HttpsSupport.getSystemProtocols(),
@ -63,6 +69,22 @@ public class DefaultClientTlsStrategy extends AbstractClientTlsStrategy {
HttpsSupport.getDefaultHostnameVerifier()); 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. * @deprecated To be removed.
*/ */

View File

@ -56,7 +56,6 @@ import javax.net.ssl.SSLSocket;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import org.apache.hc.client5.http.config.TlsConfig; 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.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost; 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 * 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. * 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) @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 private static final String WEAK_KEY_EXCHANGES
= "^(TLS|SSL)_(NULL|ECDH_anon|DH_anon|DH_anon_EXPORT|DHE_RSA_EXPORT|DHE_DSS_EXPORT|" = "^(TLS|SSL)_(NULL|ECDH_anon|DH_anon|DH_anon_EXPORT|DHE_RSA_EXPORT|DHE_DSS_EXPORT|"

View File

@ -57,8 +57,9 @@ import org.apache.hc.core5.ssl.SSLContexts;
* <li>https.cipherSuites</li> * <li>https.cipherSuites</li>
* </ul> * </ul>
* *
* @since 5.0 * @deprecated Use {@link DefaultClientTlsStrategy}
*/ */
@Deprecated
public class SSLConnectionSocketFactoryBuilder { public class SSLConnectionSocketFactoryBuilder {
public static SSLConnectionSocketFactoryBuilder create() { public static SSLConnectionSocketFactoryBuilder create() {

View File

@ -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.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.protocol.HttpClientContext; 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.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.Header;
@ -150,7 +151,7 @@ public class ClientConfiguration {
// Create a registry of custom connection socket factories for supported // Create a registry of custom connection socket factories for supported
// protocol schemes. // protocol schemes.
final SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext); final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext);
// Use custom DNS resolver to override the system DNS resolution. // Use custom DNS resolver to override the system DNS resolution.
final DnsResolver dnsResolver = new SystemDefaultDnsResolver() { final DnsResolver dnsResolver = new SystemDefaultDnsResolver() {
@ -168,7 +169,7 @@ public class ClientConfiguration {
// Create a connection manager with custom configuration. // Create a connection manager with custom configuration.
final PoolingHttpClientConnectionManager connManager = PoolingHttpClientConnectionManagerBuilder.create() final PoolingHttpClientConnectionManager connManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(sslConnectionSocketFactory) .setTlsSocketStrategy(tlsStrategy)
.setConnectionFactory(connFactory) .setConnectionFactory(connFactory)
.setDnsResolver(dnsResolver) .setDnsResolver(dnsResolver)
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT) .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)

View File

@ -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.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.psl.PublicSuffixMatcher; import org.apache.hc.client5.http.psl.PublicSuffixMatcher;
import org.apache.hc.client5.http.psl.PublicSuffixMatcherLoader; 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.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.Lookup;
import org.apache.hc.core5.http.config.RegistryBuilder; import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.EntityUtils;
@ -66,11 +67,11 @@ public class ClientCustomPublicSuffixList {
.register(StandardCookieSpec.RELAXED, cookieSpecFactory) .register(StandardCookieSpec.RELAXED, cookieSpecFactory)
.register(StandardCookieSpec.STRICT, cookieSpecFactory) .register(StandardCookieSpec.STRICT, cookieSpecFactory)
.build(); .build();
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(
SSLContexts.createDefault(), SSLContexts.createDefault(),
new DefaultHostnameVerifier(publicSuffixMatcher)); new DefaultHostnameVerifier(publicSuffixMatcher));
final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(sslsf) .setTlsSocketStrategy(tlsStrategy)
.build(); .build();
try (final CloseableHttpClient httpclient = HttpClients.custom() try (final CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm) .setConnectionManager(cm)

View File

@ -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.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.HttpClientContext; 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.SSLConnectionSocketFactoryBuilder; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.message.StatusLine; import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.http.ssl.TLS; import org.apache.hc.core5.http.ssl.TLS;
@ -67,12 +67,10 @@ public class ClientCustomSSL {
return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName()); return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
}) })
.build(); .build();
final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create() final TlsSocketStrategy tlsStrategy = new DefaultClientTlsStrategy(sslContext);
.setSslContext(sslContext)
.build();
// Allow TLSv1.3 protocol only // Allow TLSv1.3 protocol only
final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(sslSocketFactory) .setTlsSocketStrategy(tlsStrategy)
.setDefaultTlsConfig(TlsConfig.custom() .setDefaultTlsConfig(TlsConfig.custom()
.setHandshakeTimeout(Timeout.ofSeconds(30)) .setHandshakeTimeout(Timeout.ofSeconds(30))
.setSupportedProtocols(TLS.V_1_3) .setSupportedProtocols(TLS.V_1_3)

View File

@ -32,6 +32,8 @@ import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLSocket;
import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.DnsResolver;
import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver; 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.LeaseRequest;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.config.Lookup; import org.apache.hc.core5.http.config.Lookup;
import org.apache.hc.core5.http.io.HttpConnectionFactory; import org.apache.hc.core5.http.io.HttpConnectionFactory;
@ -65,14 +66,16 @@ public class TestBasicHttpClientConnectionManager {
@Mock @Mock
private HttpConnectionFactory<ManagedHttpClientConnection> connFactory; private HttpConnectionFactory<ManagedHttpClientConnection> connFactory;
@Mock @Mock
private Lookup<ConnectionSocketFactory> socketFactoryRegistry; private Lookup<TlsSocketStrategy> tlsSocketStrategyLookup;
@Mock @Mock
private DetachedSocketFactory detachedSocketFactory; private DetachedSocketFactory detachedSocketFactory;
@Mock @Mock
private LayeredConnectionSocketFactory sslSocketFactory; private TlsSocketStrategy tlsSocketStrategy;
@Mock @Mock
private Socket socket; private Socket socket;
@Mock @Mock
private SSLSocket upgradedSocket;
@Mock
private SchemePortResolver schemePortResolver; private SchemePortResolver schemePortResolver;
@Mock @Mock
private DnsResolver dnsResolver; private DnsResolver dnsResolver;
@ -83,7 +86,7 @@ public class TestBasicHttpClientConnectionManager {
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.openMocks(this); MockitoAnnotations.openMocks(this);
mgr = new BasicHttpClientConnectionManager(new DefaultHttpClientConnectionOperator( mgr = new BasicHttpClientConnectionManager(new DefaultHttpClientConnectionOperator(
detachedSocketFactory, socketFactoryRegistry, schemePortResolver, dnsResolver), detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup),
connFactory); connFactory);
} }
@ -385,13 +388,13 @@ public class TestBasicHttpClientConnectionManager {
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443);
Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket);
Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy);
Mockito.when(sslSocketFactory.createLayeredSocket( Mockito.when(tlsSocketStrategy.upgrade(
Mockito.same(socket), Mockito.same(socket),
Mockito.eq("somehost"), Mockito.eq("somehost"),
Mockito.eq(8443), Mockito.eq(8443),
Mockito.any(), Mockito.any(),
Mockito.any())).thenReturn(socket); Mockito.any())).thenReturn(upgradedSocket);
mgr.connect(endpoint1, null, context); mgr.connect(endpoint1, null, context);
@ -399,7 +402,7 @@ public class TestBasicHttpClientConnectionManager {
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target);
Mockito.verify(detachedSocketFactory, Mockito.times(1)).create(null); Mockito.verify(detachedSocketFactory, Mockito.times(1)).create(null);
Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 234); 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); mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
@ -407,7 +410,7 @@ public class TestBasicHttpClientConnectionManager {
Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target); Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target);
Mockito.verify(detachedSocketFactory, Mockito.times(2)).create(null); Mockito.verify(detachedSocketFactory, Mockito.times(2)).create(null);
Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 123); 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 @Test
@ -441,7 +444,7 @@ public class TestBasicHttpClientConnectionManager {
Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote}); Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote});
Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080); Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080);
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); 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); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket);
mgr.connect(endpoint1, null, context); mgr.connect(endpoint1, null, context);
@ -456,7 +459,7 @@ public class TestBasicHttpClientConnectionManager {
mgr.upgrade(endpoint1, context); mgr.upgrade(endpoint1, context);
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); 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); socket, "somehost", 8443, tlsConfig, context);
} }

View File

@ -34,6 +34,8 @@ import java.net.Socket;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLSocket;
import org.apache.hc.client5.http.ConnectTimeoutException; import org.apache.hc.client5.http.ConnectTimeoutException;
import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.DnsResolver;
import org.apache.hc.client5.http.HttpHostConnectException; 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.config.TlsConfig;
import org.apache.hc.client5.http.io.DetachedSocketFactory; import org.apache.hc.client5.http.io.DetachedSocketFactory;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.config.Lookup; import org.apache.hc.core5.http.config.Lookup;
import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.http.io.SocketConfig;
@ -62,8 +63,8 @@ public class TestHttpClientConnectionOperator {
private ManagedHttpClientConnection conn; private ManagedHttpClientConnection conn;
private Socket socket; private Socket socket;
private DetachedSocketFactory detachedSocketFactory; private DetachedSocketFactory detachedSocketFactory;
private LayeredConnectionSocketFactory sslSocketFactory; private TlsSocketStrategy tlsSocketStrategy;
private Lookup<ConnectionSocketFactory> socketFactoryRegistry; private Lookup<TlsSocketStrategy> tlsSocketStrategyLookup;
private SchemePortResolver schemePortResolver; private SchemePortResolver schemePortResolver;
private DnsResolver dnsResolver; private DnsResolver dnsResolver;
private DefaultHttpClientConnectionOperator connectionOperator; private DefaultHttpClientConnectionOperator connectionOperator;
@ -73,12 +74,12 @@ public class TestHttpClientConnectionOperator {
conn = Mockito.mock(ManagedHttpClientConnection.class); conn = Mockito.mock(ManagedHttpClientConnection.class);
socket = Mockito.mock(Socket.class); socket = Mockito.mock(Socket.class);
detachedSocketFactory = Mockito.mock(DetachedSocketFactory.class); detachedSocketFactory = Mockito.mock(DetachedSocketFactory.class);
sslSocketFactory = Mockito.mock(LayeredConnectionSocketFactory.class); tlsSocketStrategy = Mockito.mock(TlsSocketStrategy.class);
socketFactoryRegistry = Mockito.mock(Lookup.class); tlsSocketStrategyLookup = Mockito.mock(Lookup.class);
schemePortResolver = Mockito.mock(SchemePortResolver.class); schemePortResolver = Mockito.mock(SchemePortResolver.class);
dnsResolver = Mockito.mock(DnsResolver.class); dnsResolver = Mockito.mock(DnsResolver.class);
connectionOperator = new DefaultHttpClientConnectionOperator( connectionOperator = new DefaultHttpClientConnectionOperator(
detachedSocketFactory, socketFactoryRegistry, schemePortResolver, dnsResolver); detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup);
} }
@Test @Test
@ -131,9 +132,9 @@ public class TestHttpClientConnectionOperator {
Mockito.when(schemePortResolver.resolve(host)).thenReturn(443); Mockito.when(schemePortResolver.resolve(host)).thenReturn(443);
Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket);
Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy);
final Socket upgradedSocket = Mockito.mock(Socket.class); final SSLSocket upgradedSocket = Mockito.mock(SSLSocket.class);
Mockito.when(sslSocketFactory.createLayeredSocket( Mockito.when(tlsSocketStrategy.upgrade(
Mockito.same(socket), Mockito.same(socket),
Mockito.eq("somehost"), Mockito.eq("somehost"),
Mockito.eq(443), Mockito.eq(443),
@ -146,7 +147,7 @@ public class TestHttpClientConnectionOperator {
Mockito.verify(socket).connect(new InetSocketAddress(ip1, 443), 123); Mockito.verify(socket).connect(new InetSocketAddress(ip1, 443), 123);
Mockito.verify(conn, Mockito.times(2)).bind(socket); 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); Mockito.verify(conn, Mockito.times(1)).bind(upgradedSocket);
} }
@ -240,19 +241,20 @@ public class TestHttpClientConnectionOperator {
Mockito.when(conn.isOpen()).thenReturn(true); Mockito.when(conn.isOpen()).thenReturn(true);
Mockito.when(conn.getSocket()).thenReturn(socket); 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(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.any(),
Mockito.eq("somehost"), Mockito.eq("somehost"),
Mockito.eq(443), Mockito.eq(443),
Mockito.eq(Timeout.ofMilliseconds(345)), Mockito.eq(Timeout.ofMilliseconds(345)),
Mockito.any())).thenReturn(socket); Mockito.any())).thenReturn(upgradedSocket);
connectionOperator.upgrade(conn, host, Timeout.ofMilliseconds(345), context); connectionOperator.upgrade(conn, host, Timeout.ofMilliseconds(345), context);
Mockito.verify(conn).bind(socket); Mockito.verify(conn).bind(upgradedSocket);
} }
@Test @Test

View File

@ -34,6 +34,8 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import javax.net.ssl.SSLSocket;
import org.apache.hc.client5.http.DnsResolver; import org.apache.hc.client5.http.DnsResolver;
import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.SchemePortResolver; 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.LeaseRequest;
import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.config.Lookup; import org.apache.hc.core5.http.config.Lookup;
import org.apache.hc.core5.http.io.SocketConfig; import org.apache.hc.core5.http.io.SocketConfig;
@ -68,14 +69,16 @@ public class TestPoolingHttpClientConnectionManager {
@Mock @Mock
private ManagedHttpClientConnection conn; private ManagedHttpClientConnection conn;
@Mock @Mock
private Lookup<ConnectionSocketFactory> socketFactoryRegistry; private Lookup<TlsSocketStrategy> tlsSocketStrategyLookup;
@Mock @Mock
private DetachedSocketFactory detachedSocketFactory; private DetachedSocketFactory detachedSocketFactory;
@Mock @Mock
private LayeredConnectionSocketFactory sslSocketFactory; private TlsSocketStrategy tlsSocketStrategy;
@Mock @Mock
private Socket socket; private Socket socket;
@Mock @Mock
private SSLSocket upgradedSocket;
@Mock
private SchemePortResolver schemePortResolver; private SchemePortResolver schemePortResolver;
@Mock @Mock
private DnsResolver dnsResolver; private DnsResolver dnsResolver;
@ -90,7 +93,7 @@ public class TestPoolingHttpClientConnectionManager {
public void setup() throws Exception { public void setup() throws Exception {
MockitoAnnotations.openMocks(this); MockitoAnnotations.openMocks(this);
mgr = new PoolingHttpClientConnectionManager(new DefaultHttpClientConnectionOperator( mgr = new PoolingHttpClientConnectionManager(new DefaultHttpClientConnectionOperator(
detachedSocketFactory, socketFactoryRegistry, schemePortResolver, dnsResolver), pool, detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup), pool,
null); null);
} }
@ -263,13 +266,13 @@ public class TestPoolingHttpClientConnectionManager {
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443);
Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket);
Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory); Mockito.when(tlsSocketStrategyLookup.lookup("https")).thenReturn(tlsSocketStrategy);
Mockito.when(sslSocketFactory.createLayeredSocket( Mockito.when(tlsSocketStrategy.upgrade(
Mockito.same(socket), Mockito.same(socket),
Mockito.eq("somehost"), Mockito.eq("somehost"),
Mockito.eq(8443), Mockito.eq(8443),
Mockito.any(), Mockito.any(),
Mockito.any())).thenReturn(socket); Mockito.any())).thenReturn(upgradedSocket);
mgr.connect(endpoint1, null, context); mgr.connect(endpoint1, null, context);
@ -277,7 +280,7 @@ public class TestPoolingHttpClientConnectionManager {
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target);
Mockito.verify(detachedSocketFactory, Mockito.times(1)).create(null); Mockito.verify(detachedSocketFactory, Mockito.times(1)).create(null);
Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 234); 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); mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
@ -285,7 +288,7 @@ public class TestPoolingHttpClientConnectionManager {
Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target); Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target);
Mockito.verify(detachedSocketFactory, Mockito.times(2)).create(null); Mockito.verify(detachedSocketFactory, Mockito.times(2)).create(null);
Mockito.verify(socket, Mockito.times(1)).connect(new InetSocketAddress(remote, 8443), 123); 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 @Test
@ -312,7 +315,6 @@ public class TestPoolingHttpClientConnectionManager {
final ConnectionEndpoint endpoint1 = connRequest1.get(Timeout.ofSeconds(1)); final ConnectionEndpoint endpoint1 = connRequest1.get(Timeout.ofSeconds(1));
Assertions.assertNotNull(endpoint1); Assertions.assertNotNull(endpoint1);
final LayeredConnectionSocketFactory sslsf = Mockito.mock(LayeredConnectionSocketFactory.class);
final HttpClientContext context = HttpClientContext.create(); final HttpClientContext context = HttpClientContext.create();
final SocketConfig sconfig = SocketConfig.custom().build(); final SocketConfig sconfig = SocketConfig.custom().build();
@ -330,7 +332,7 @@ public class TestPoolingHttpClientConnectionManager {
Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote}); Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote});
Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080); Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080);
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443); 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); Mockito.when(detachedSocketFactory.create(Mockito.any())).thenReturn(socket);
mgr.connect(endpoint1, null, context); mgr.connect(endpoint1, null, context);
@ -346,7 +348,7 @@ public class TestPoolingHttpClientConnectionManager {
mgr.upgrade(endpoint1, context); mgr.upgrade(endpoint1, context);
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target); 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); socket, "somehost", 8443, tlsConfig, context);
} }

View File

@ -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
* <http://www.apache.org/>.
*
*/
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));
}
}
}