From 12e53da1c35b6c837a50f3c2823e3000431281d4 Mon Sep 17 00:00:00 2001 From: Richard Tippl Date: Sat, 16 Mar 2024 23:30:21 +0100 Subject: [PATCH] Callbacks for Connection initialization --- .../io/BasicHttpClientConnectionManager.java | 23 ++++++-- .../DefaultHttpClientConnectionOperator.java | 43 +++++++++++++-- .../PoolingHttpClientConnectionManager.java | 2 +- ...ingHttpClientConnectionManagerBuilder.java | 15 +++++- .../client5/http/io/ConnectionCallback.java | 52 +++++++++++++++++++ .../TestBasicHttpClientConnectionManager.java | 2 +- .../io/TestHttpClientConnectionOperator.java | 35 ++++++++++++- ...estPoolingHttpClientConnectionManager.java | 2 +- 8 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 httpclient5/src/main/java/org/apache/hc/client5/http/io/ConnectionCallback.java diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java index ef99e78725..9e350134d6 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java @@ -45,6 +45,7 @@ import org.apache.hc.client5.http.config.TlsConfig; import org.apache.hc.client5.http.impl.ConnPoolSupport; import org.apache.hc.client5.http.impl.ConnectionShutdownException; +import org.apache.hc.client5.http.io.ConnectionCallback; import org.apache.hc.client5.http.io.ConnectionEndpoint; import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.io.HttpClientConnectionOperator; @@ -137,6 +138,20 @@ public BasicHttpClientConnectionManager( this.lock = new ReentrantLock(); } + /** + * @since 5.4 + */ + public static BasicHttpClientConnectionManager create( + final SchemePortResolver schemePortResolver, + final DnsResolver dnsResolver, + final Lookup tlsSocketStrategyRegistry, + final HttpConnectionFactory connFactory, + final ConnectionCallback connectionCallback) { + return new BasicHttpClientConnectionManager( + new DefaultHttpClientConnectionOperator(schemePortResolver, dnsResolver, tlsSocketStrategyRegistry, connectionCallback), + connFactory); + } + /** * @since 5.4 */ @@ -146,7 +161,7 @@ public static BasicHttpClientConnectionManager create( final Lookup tlsSocketStrategyRegistry, final HttpConnectionFactory connFactory) { return new BasicHttpClientConnectionManager( - new DefaultHttpClientConnectionOperator(schemePortResolver, dnsResolver, tlsSocketStrategyRegistry), + new DefaultHttpClientConnectionOperator(schemePortResolver, dnsResolver, tlsSocketStrategyRegistry, null), connFactory); } @@ -157,7 +172,7 @@ public static BasicHttpClientConnectionManager create( final Lookup tlsSocketStrategyRegistry, final HttpConnectionFactory connFactory) { return new BasicHttpClientConnectionManager( - new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry), connFactory); + new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry, null), connFactory); } /** @@ -166,7 +181,7 @@ public static BasicHttpClientConnectionManager create( public static BasicHttpClientConnectionManager create( final Lookup tlsSocketStrategyRegistry) { return new BasicHttpClientConnectionManager( - new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry), null); + new DefaultHttpClientConnectionOperator(null, null, tlsSocketStrategyRegistry, null), null); } /** @@ -205,7 +220,7 @@ public BasicHttpClientConnectionManager() { this(new DefaultHttpClientConnectionOperator(null, null, RegistryBuilder.create() .register(URIScheme.HTTPS.id, DefaultClientTlsStrategy.createDefault()) - .build()), + .build(), null), null); } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java index c175ca3700..9232c4c3a1 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultHttpClientConnectionOperator.java @@ -44,6 +44,7 @@ import org.apache.hc.client5.http.UnsupportedSchemeException; import org.apache.hc.client5.http.impl.ConnPoolSupport; import org.apache.hc.client5.http.impl.DefaultSchemePortResolver; +import org.apache.hc.client5.http.io.ConnectionCallback; import org.apache.hc.client5.http.io.DetachedSocketFactory; import org.apache.hc.client5.http.io.HttpClientConnectionOperator; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; @@ -91,6 +92,7 @@ public Socket create(final Proxy socksProxy) throws IOException { private final Lookup tlsSocketStrategyLookup; private final SchemePortResolver schemePortResolver; private final DnsResolver dnsResolver; + private final ConnectionCallback connectionCallback; /** * @deprecated Provided for backward compatibility @@ -111,7 +113,8 @@ public DefaultHttpClientConnectionOperator( final DetachedSocketFactory detachedSocketFactory, final SchemePortResolver schemePortResolver, final DnsResolver dnsResolver, - final Lookup tlsSocketStrategyLookup) { + final Lookup tlsSocketStrategyLookup, + final ConnectionCallback connectionCallback) { super(); this.detachedSocketFactory = Args.notNull(detachedSocketFactory, "Plain socket factory"); this.tlsSocketStrategyLookup = Args.notNull(tlsSocketStrategyLookup, "Socket factory registry"); @@ -119,6 +122,7 @@ public DefaultHttpClientConnectionOperator( DefaultSchemePortResolver.INSTANCE; this.dnsResolver = dnsResolver != null ? dnsResolver : SystemDefaultDnsResolver.INSTANCE; + this.connectionCallback = connectionCallback; } /** @@ -129,14 +133,15 @@ public DefaultHttpClientConnectionOperator( final Lookup socketFactoryRegistry, final SchemePortResolver schemePortResolver, final DnsResolver dnsResolver) { - this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, adapt(socketFactoryRegistry)); + this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, adapt(socketFactoryRegistry), null); } public DefaultHttpClientConnectionOperator( final SchemePortResolver schemePortResolver, final DnsResolver dnsResolver, - final Lookup tlsSocketStrategyLookup) { - this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, tlsSocketStrategyLookup); + final Lookup tlsSocketStrategyLookup, + final ConnectionCallback connectionCallback) { + this(PLAIN_SOCKET_FACTORY, schemePortResolver, dnsResolver, tlsSocketStrategyLookup, connectionCallback); } @Override @@ -169,12 +174,18 @@ public void connect( if (endpointHost.getAddress() != null) { remoteAddresses = new InetAddress[] { endpointHost.getAddress() }; } else { + if (connectionCallback != null) { + connectionCallback.onBeforeDnsResolve(context); + } if (LOG.isDebugEnabled()) { LOG.debug("{} resolving remote address", endpointHost.getHostName()); } remoteAddresses = this.dnsResolver.resolve(endpointHost.getHostName()); + if (connectionCallback != null) { + connectionCallback.onAfterDnsResolve(context); + } if (LOG.isDebugEnabled()) { LOG.debug("{} resolved to {}", endpointHost.getHostName(), remoteAddresses == null ? "null" : Arrays.asList(remoteAddresses)); } @@ -192,6 +203,9 @@ public void connect( final InetAddress address = remoteAddresses[i]; final boolean last = i == remoteAddresses.length - 1; final InetSocketAddress remoteAddress = new InetSocketAddress(address, port); + if (connectionCallback != null) { + connectionCallback.onBeforeSocketConnect(context, endpointHost); + } if (LOG.isDebugEnabled()) { LOG.debug("{} connecting {}->{} ({})", endpointHost, localAddress, remoteAddress, connectTimeout); } @@ -221,6 +235,9 @@ public void connect( } socket.connect(remoteAddress, TimeValue.isPositive(connectTimeout) ? connectTimeout.toMillisecondsIntBound() : 0); conn.bind(socket); + if (connectionCallback != null) { + connectionCallback.onAfterSocketConnect(context, endpointHost); + } if (LOG.isDebugEnabled()) { LOG.debug("{} {} connected {}->{}", ConnPoolSupport.getId(conn), endpointHost, conn.getLocalAddress(), conn.getRemoteAddress()); @@ -229,11 +246,20 @@ public void connect( final TlsSocketStrategy tlsSocketStrategy = tlsSocketStrategyLookup != null ? tlsSocketStrategyLookup.lookup(endpointHost.getSchemeName()) : null; if (tlsSocketStrategy != null) { final NamedEndpoint tlsName = endpointName != null ? endpointName : endpointHost; + if (connectionCallback != null) { + connectionCallback.onBeforeTlsHandshake(context, endpointHost); + } if (LOG.isDebugEnabled()) { LOG.debug("{} {} upgrading to TLS", ConnPoolSupport.getId(conn), tlsName); } final Socket upgradedSocket = tlsSocketStrategy.upgrade(socket, tlsName.getHostName(), tlsName.getPort(), attachment, context); conn.bind(upgradedSocket); + if (connectionCallback != null) { + connectionCallback.onAfterTlsHandshake(context, endpointHost); + } + if (LOG.isDebugEnabled()) { + LOG.debug("{} {} upgraded to TLS", ConnPoolSupport.getId(conn), tlsName); + } } return; } catch (final RuntimeException ex) { @@ -278,11 +304,20 @@ public void upgrade( final TlsSocketStrategy tlsSocketStrategy = tlsSocketStrategyLookup != null ? tlsSocketStrategyLookup.lookup(newProtocol) : null; if (tlsSocketStrategy != null) { final NamedEndpoint tlsName = endpointName != null ? endpointName : endpointHost; + if (connectionCallback != null) { + connectionCallback.onBeforeTlsHandshake(context, endpointHost); + } if (LOG.isDebugEnabled()) { LOG.debug("{} upgrading to TLS {}:{}", ConnPoolSupport.getId(conn), tlsName.getHostName(), tlsName.getPort()); } final SSLSocket upgradedSocket = tlsSocketStrategy.upgrade(socket, tlsName.getHostName(), tlsName.getPort(), attachment, context); conn.bind(upgradedSocket); + if (connectionCallback != null) { + connectionCallback.onAfterTlsHandshake(context, endpointHost); + } + if (LOG.isDebugEnabled()) { + LOG.debug("{} upgraded to TLS {}:{}", ConnPoolSupport.getId(conn), tlsName.getHostName(), tlsName.getPort()); + } } else { throw new UnsupportedSchemeException(newProtocol + " protocol is not supported"); } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java index a60e9ebd61..bc16342be7 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java @@ -123,7 +123,7 @@ public PoolingHttpClientConnectionManager() { this(new DefaultHttpClientConnectionOperator(null, null, RegistryBuilder.create() .register(URIScheme.HTTPS.id, DefaultClientTlsStrategy.createDefault()) - .build()), + .build(), null), PoolConcurrencyPolicy.STRICT, PoolReusePolicy.LIFO, TimeValue.NEG_ONE_MILLISECOND, diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java index dd5c543e1d..81001ab06a 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java @@ -34,6 +34,7 @@ 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.ConnectionCallback; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; import org.apache.hc.client5.http.ssl.TlsSocketStrategy; @@ -84,6 +85,7 @@ public class PoolingHttpClientConnectionManagerBuilder { private Resolver socketConfigResolver; private Resolver connectionConfigResolver; private Resolver tlsConfigResolver; + private ConnectionCallback connectionCallback; private boolean systemProperties; @@ -237,6 +239,16 @@ public final PoolingHttpClientConnectionManagerBuilder setTlsConfigResolver( return this; } + /** + * Assigns {@link ConnectionCallback} instance. + * + * @since 5.4 + */ + public final PoolingHttpClientConnectionManagerBuilder setConnectionCallback(final ConnectionCallback connectionCallback) { + this.connectionCallback = connectionCallback; + return this; + } + /** * Sets maximum time to live for persistent connections * @@ -281,7 +293,8 @@ public PoolingHttpClientConnectionManager build() { (systemProperties ? DefaultClientTlsStrategy.createSystemDefault() : DefaultClientTlsStrategy.createDefault())) - .build()), + .build(), + connectionCallback), poolConcurrencyPolicy, poolReusePolicy, null, diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/io/ConnectionCallback.java b/httpclient5/src/main/java/org/apache/hc/client5/http/io/ConnectionCallback.java new file mode 100644 index 0000000000..c7ea58f5a5 --- /dev/null +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/io/ConnectionCallback.java @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.hc.client5.http.io; + +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.protocol.HttpContext; + +/** + * A callback interface that gets invoked upon different steps of connection initialization. + * Useful for measuring duration of initialization steps. + * + * @since 5.4 + */ +public interface ConnectionCallback { + + void onBeforeDnsResolve(HttpContext httpContext); + + void onAfterDnsResolve(HttpContext httpContext); + + void onBeforeSocketConnect(HttpContext httpContext, HttpHost endpointHost); + + void onAfterSocketConnect(HttpContext httpContext, HttpHost endpointHost); + + void onBeforeTlsHandshake(HttpContext httpContext, HttpHost endpointHost); + + void onAfterTlsHandshake(HttpContext httpContext, HttpHost endpointHost); + +} diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java index f8ac4dae59..5739ccb6d3 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestBasicHttpClientConnectionManager.java @@ -86,7 +86,7 @@ public class TestBasicHttpClientConnectionManager { public void setup() throws Exception { MockitoAnnotations.openMocks(this); mgr = new BasicHttpClientConnectionManager(new DefaultHttpClientConnectionOperator( - detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup), + detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup, null), connFactory); } diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java index 64aff2612b..9e70f57d0b 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestHttpClientConnectionOperator.java @@ -42,6 +42,7 @@ import org.apache.hc.client5.http.SchemePortResolver; import org.apache.hc.client5.http.UnsupportedSchemeException; import org.apache.hc.client5.http.config.TlsConfig; +import org.apache.hc.client5.http.io.ConnectionCallback; import org.apache.hc.client5.http.io.DetachedSocketFactory; import org.apache.hc.client5.http.io.ManagedHttpClientConnection; import org.apache.hc.client5.http.protocol.HttpClientContext; @@ -66,6 +67,7 @@ public class TestHttpClientConnectionOperator { private Lookup tlsSocketStrategyLookup; private SchemePortResolver schemePortResolver; private DnsResolver dnsResolver; + private ConnectionCallback connectionCallback; private DefaultHttpClientConnectionOperator connectionOperator; @BeforeEach @@ -77,8 +79,9 @@ public void setup() throws Exception { tlsSocketStrategyLookup = Mockito.mock(Lookup.class); schemePortResolver = Mockito.mock(SchemePortResolver.class); dnsResolver = Mockito.mock(DnsResolver.class); + connectionCallback = Mockito.mock(ConnectionCallback.class); connectionOperator = new DefaultHttpClientConnectionOperator( - detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup); + detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup, connectionCallback); } @Test @@ -112,6 +115,12 @@ public void testConnect() throws Exception { Mockito.verify(socket).connect(new InetSocketAddress(ip1, 80), 123); Mockito.verify(conn, Mockito.times(2)).bind(socket); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.never()).onBeforeTlsHandshake(context, host); + Mockito.verify(connectionCallback, Mockito.never()).onAfterTlsHandshake(context, host); } @Test @@ -148,6 +157,12 @@ public void testConnectWithTLSUpgrade() throws Exception { Mockito.verify(conn, Mockito.times(2)).bind(socket); Mockito.verify(tlsSocketStrategy).upgrade(socket, "somehost", -1, tlsConfig, context); Mockito.verify(conn, Mockito.times(1)).bind(upgradedSocket); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeTlsHandshake(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterTlsHandshake(context, host); } @Test @@ -208,6 +223,12 @@ public void testConnectFailover() throws Exception { Mockito.verify(socket, Mockito.times(2)).bind(localAddress); Mockito.verify(socket).connect(new InetSocketAddress(ip2, 80), 123); Mockito.verify(conn, Mockito.times(3)).bind(socket); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.times(2)).onBeforeSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.never()).onBeforeTlsHandshake(context, host); + Mockito.verify(connectionCallback, Mockito.never()).onAfterTlsHandshake(context, host); } @@ -231,6 +252,12 @@ public void testConnectExplicitAddress() throws Exception { Mockito.verify(socket).connect(new InetSocketAddress(ip, 80), 123); Mockito.verify(dnsResolver, Mockito.never()).resolve(Mockito.anyString()); Mockito.verify(conn, Mockito.times(2)).bind(socket); + Mockito.verify(connectionCallback, Mockito.never()).onBeforeDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.never()).onAfterDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.never()).onBeforeTlsHandshake(context, host); + Mockito.verify(connectionCallback, Mockito.never()).onAfterTlsHandshake(context, host); } @Test @@ -253,6 +280,12 @@ public void testUpgrade() throws Exception { connectionOperator.upgrade(conn, host, null, Timeout.ofMilliseconds(345), context); Mockito.verify(conn).bind(upgradedSocket); + Mockito.verify(connectionCallback, Mockito.never()).onBeforeDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.never()).onAfterDnsResolve(context); + Mockito.verify(connectionCallback, Mockito.never()).onBeforeSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.never()).onAfterSocketConnect(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onBeforeTlsHandshake(context, host); + Mockito.verify(connectionCallback, Mockito.times(1)).onAfterTlsHandshake(context, host); } @Test diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java index b70b722131..50713d5f5a 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/io/TestPoolingHttpClientConnectionManager.java @@ -95,7 +95,7 @@ public class TestPoolingHttpClientConnectionManager { public void setup() throws Exception { MockitoAnnotations.openMocks(this); mgr = new PoolingHttpClientConnectionManager(new DefaultHttpClientConnectionOperator( - detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup), pool, + detachedSocketFactory, schemePortResolver, dnsResolver, tlsSocketStrategyLookup, null), pool, null); }