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.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()

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.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)

View File

@ -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);
}
}
}

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.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());

View File

@ -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();
}
}

View File

@ -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());
}
/**

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.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<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
*/
@ -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<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(
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) {
this(socketFactoryRegistry, connFactory, null, null);
}
/**
* @deprecated Use {@link #create(Lookup)}
*/
@Deprecated
public BasicHttpClientConnectionManager(
final Lookup<ConnectionSocketFactory> socketFactoryRegistry) {
final Lookup<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry) {
this(socketFactoryRegistry, null, null, null);
}
public BasicHttpClientConnectionManager() {
this(getDefaultRegistry(), null, null, null);
this(new DefaultHttpClientConnectionOperator(null, null,
RegistryBuilder.<TlsSocketStrategy>create()
.register(URIScheme.HTTPS.id, DefaultClientTlsStrategy.createDefault())
.build()),
null);
}
@Override

View File

@ -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<ConnectionSocketFactory> socketFactoryRegistry;
private final Lookup<TlsSocketStrategy> tlsSocketStrategyLookup;
private final SchemePortResolver schemePortResolver;
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(
final DetachedSocketFactory detachedSocketFactory,
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver) {
final DnsResolver dnsResolver,
final Lookup<TlsSocketStrategy> 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<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver) {
this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, adapt(socketFactoryRegistry));
}
public DefaultHttpClientConnectionOperator(
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
final SchemePortResolver schemePortResolver,
final DnsResolver dnsResolver) {
this(PLAIN_SOCKET_FACTORY, socketFactoryRegistry, schemePortResolver, dnsResolver);
final DnsResolver dnsResolver,
final Lookup<TlsSocketStrategy> 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);
}
}

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.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<HttpHost, TlsConfig> tlsConfigResolver;
public PoolingHttpClientConnectionManager() {
this(RegistryBuilder.<ConnectionSocketFactory>create()
.register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory())
.register(URIScheme.HTTPS.id, SSLConnectionSocketFactory.getSocketFactory())
.build());
this(new DefaultHttpClientConnectionOperator(null, null,
RegistryBuilder.<TlsSocketStrategy>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<ConnectionSocketFactory> socketFactoryRegistry) {
final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry) {
this(socketFactoryRegistry, null);
}
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
this(socketFactoryRegistry, PoolConcurrencyPolicy.STRICT, TimeValue.NEG_ONE_MILLISECOND, connFactory);
}
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final PoolConcurrencyPolicy poolConcurrencyPolicy,
final TimeValue timeToLive,
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
this(socketFactoryRegistry, poolConcurrencyPolicy, PoolReusePolicy.LIFO, timeToLive, connFactory);
}
/**
* @deprecated Use {@link PoolingHttpClientConnectionManagerBuilder}
*/
@Deprecated
public PoolingHttpClientConnectionManager(
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> 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<ConnectionSocketFactory> socketFactoryRegistry,
final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> 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<ConnectionSocketFactory> socketFactoryRegistry,
final Registry<org.apache.hc.client5.http.socket.ConnectionSocketFactory> socketFactoryRegistry,
final PoolConcurrencyPolicy poolConcurrencyPolicy,
final PoolReusePolicy poolReusePolicy,
final TimeValue timeToLive,

View File

@ -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<ManagedHttpClientConnection> 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.<ConnectionSocketFactory>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.<TlsSocketStrategy>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);

View File

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

View File

@ -242,9 +242,9 @@ public class PoolingAsyncClientConnectionManagerBuilder {
}
} else {
if (systemProperties) {
tlsStrategyCopy = DefaultClientTlsStrategy.getSystemDefault();
tlsStrategyCopy = DefaultClientTlsStrategy.createSystemDefault();
} 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.
*
* @since 4.3
* @deprecated Do not use.
*/
@Contract(threading = ThreadingBehavior.STATELESS)
@Deprecated
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.
*
* @since 4.3
* @deprecated Use {@link org.apache.hc.client5.http.ssl.TlsSocketStrategy}.
*/
@Deprecated
@Contract(threading = ThreadingBehavior.STATELESS)
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.
*
* @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 {

View File

@ -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.
*/

View File

@ -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|"

View File

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

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.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)

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.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)

View File

@ -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<ManagedHttpClientConnection> connFactory;
@Mock
private Lookup<ConnectionSocketFactory> socketFactoryRegistry;
private Lookup<TlsSocketStrategy> 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);
}

View File

@ -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<ConnectionSocketFactory> socketFactoryRegistry;
private TlsSocketStrategy tlsSocketStrategy;
private Lookup<TlsSocketStrategy> 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

View File

@ -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<ConnectionSocketFactory> socketFactoryRegistry;
private Lookup<TlsSocketStrategy> 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);
}

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));
}
}
}