HTTPCLIENT-2135: TLS configuration on a per-host basis
This commit is contained in:
parent
4b7551a466
commit
b10d43f2bb
|
@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
|
||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
||||
|
@ -102,12 +103,14 @@ public class TestHttp1RequestReExecution extends AbstractIntegrationTestBase<Clo
|
|||
|
||||
@Override
|
||||
protected void before() throws Throwable {
|
||||
connManager.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2) ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
||||
.build());
|
||||
clientBuilder = HttpAsyncClientBuilder.create()
|
||||
.setDefaultRequestConfig(RequestConfig.custom()
|
||||
.setConnectionRequestTimeout(TIMEOUT)
|
||||
.build())
|
||||
.setConnectionManager(connManager)
|
||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2) ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1);
|
||||
.setConnectionManager(connManager);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -34,9 +34,9 @@ import java.util.Random;
|
|||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||
|
@ -85,19 +85,19 @@ public class TestHttpAsyncMinimal extends AbstractHttpAsyncFundamentalsTest<Mini
|
|||
|
||||
@Override
|
||||
protected MinimalHttpAsyncClient createClient() throws Exception {
|
||||
final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||
.build();
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TIMEOUT)
|
||||
.build();
|
||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
||||
return HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, Http1Config.DEFAULT, ioReactorConfig, connectionManager);
|
||||
} else {
|
||||
return HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.FORCE_HTTP_1, H2Config.DEFAULT, Http1Config.DEFAULT, ioReactorConfig, connectionManager);
|
||||
}
|
||||
return HttpAsyncClients.createMinimal(
|
||||
H2Config.DEFAULT,
|
||||
Http1Config.DEFAULT,
|
||||
IOReactorConfig.custom()
|
||||
.setSoTimeout(TIMEOUT)
|
||||
.build(),
|
||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2)
|
||||
? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,9 +34,9 @@ import java.util.Random;
|
|||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||
|
@ -85,19 +85,19 @@ public class TestHttpMinimalReactive extends AbstractHttpReactiveFundamentalsTes
|
|||
|
||||
@Override
|
||||
protected MinimalHttpAsyncClient createClient() throws Exception {
|
||||
final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||
.build();
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TIMEOUT)
|
||||
.build();
|
||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
||||
return HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, Http1Config.DEFAULT, ioReactorConfig, connectionManager);
|
||||
} else {
|
||||
return HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.FORCE_HTTP_1, H2Config.DEFAULT, Http1Config.DEFAULT, ioReactorConfig, connectionManager);
|
||||
}
|
||||
return HttpAsyncClients.createMinimal(
|
||||
H2Config.DEFAULT,
|
||||
Http1Config.DEFAULT,
|
||||
IOReactorConfig.custom()
|
||||
.setSoTimeout(TIMEOUT)
|
||||
.build(),
|
||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2)
|
||||
? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
||||
.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -35,13 +35,12 @@ import java.util.concurrent.TimeoutException;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||
import org.apache.hc.client5.http.cache.CacheResponseStatus;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheContext;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.cache.CacheConfig;
|
||||
import org.apache.hc.client5.http.impl.cache.CachingHttpAsyncClients;
|
||||
|
@ -88,17 +87,20 @@ public class CachingHttpAsyncClientCompatibilityTest {
|
|||
CachingHttpAsyncClientCompatibilityTest(final HttpVersion protocolVersion, final HttpHost target) throws Exception {
|
||||
this.protocolVersion = protocolVersion;
|
||||
this.target = target;
|
||||
final SSLContext sslContext = SSLContexts.custom()
|
||||
.loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
|
||||
this.connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setTlsStrategy(new DefaultClientTlsStrategy(sslContext))
|
||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLContexts.custom()
|
||||
.loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray())
|
||||
.build()))
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(this.protocolVersion == HttpVersion.HTTP_2 ?
|
||||
HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
||||
.build())
|
||||
.build();
|
||||
this.client = CachingHttpAsyncClients.custom()
|
||||
.setCacheConfig(CacheConfig.custom()
|
||||
.setMaxObjectSize(20480)
|
||||
.build())
|
||||
.setResourceFactory(HeapResourceFactory.INSTANCE)
|
||||
.setVersionPolicy(this.protocolVersion == HttpVersion.HTTP_2 ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
||||
.setConnectionManager(this.connManager)
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.hc.client5.http.auth.AuthScope;
|
|||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
|
||||
|
@ -139,9 +140,11 @@ public class HttpAsyncClientCompatibilityTest {
|
|||
.loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
|
||||
this.connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setTlsStrategy(new DefaultClientTlsStrategy(sslContext))
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(versionPolicy)
|
||||
.build())
|
||||
.build();
|
||||
this.client = HttpAsyncClients.custom()
|
||||
.setVersionPolicy(this.versionPolicy)
|
||||
.setConnectionManager(this.connManager)
|
||||
.setProxy(this.proxy)
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
|
|
|
@ -82,7 +82,7 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||
|
||||
this.connManager.connect(endpoint1, TimeValue.NEG_ONE_MILLISECOND, context);
|
||||
this.connManager.connect(endpoint1, null, context);
|
||||
|
||||
final HttpProcessor httpProcessor = new DefaultHttpProcessor(
|
||||
new RequestTargetHost(), new RequestContent(), new RequestConnControl());
|
||||
|
@ -104,7 +104,7 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
final ConnectionEndpoint endpoint2 = leaseRequest3.get(Timeout.ZERO_MILLISECONDS);
|
||||
Assert.assertFalse(endpoint2.isConnected());
|
||||
|
||||
this.connManager.connect(endpoint2, TimeValue.NEG_ONE_MILLISECOND, context);
|
||||
this.connManager.connect(endpoint2, null, context);
|
||||
|
||||
try (final ClassicHttpResponse response2 = endpoint2.execute("id2", request, exec, context)) {
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
||||
|
@ -145,7 +145,7 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
|
||||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||
this.connManager.connect(endpoint1, TimeValue.NEG_ONE_MILLISECOND, context);
|
||||
this.connManager.connect(endpoint1, null, context);
|
||||
|
||||
final HttpProcessor httpProcessor = new DefaultHttpProcessor(
|
||||
new RequestTargetHost(), new RequestContent(), new RequestConnControl());
|
||||
|
@ -168,7 +168,7 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
final ConnectionEndpoint endpoint2 = leaseRequest3.get(Timeout.ZERO_MILLISECONDS);
|
||||
Assert.assertFalse(endpoint2.isConnected());
|
||||
|
||||
this.connManager.connect(endpoint2, TimeValue.NEG_ONE_MILLISECOND, context);
|
||||
this.connManager.connect(endpoint2, null, context);
|
||||
|
||||
try (final ClassicHttpResponse response2 = endpoint2.execute("id2", request, exec, context)) {
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
||||
|
@ -193,7 +193,7 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
Assert.assertFalse(endpoint4.isConnected());
|
||||
|
||||
// repeat the communication, no need to prepare the request again
|
||||
this.connManager.connect(endpoint4, TimeValue.NEG_ONE_MILLISECOND, context);
|
||||
this.connManager.connect(endpoint4, null, context);
|
||||
|
||||
try (final ClassicHttpResponse response4 = endpoint4.execute("id4", request, exec, context)) {
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response4.getCode());
|
||||
|
@ -213,7 +213,7 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
|
||||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||
this.connManager.connect(endpoint1, TimeValue.NEG_ONE_MILLISECOND, context);
|
||||
this.connManager.connect(endpoint1, null, context);
|
||||
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getLeased());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getLeased());
|
||||
|
@ -262,7 +262,7 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
|
||||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||
this.connManager.connect(endpoint1, TimeValue.NEG_ONE_MILLISECOND, context);
|
||||
this.connManager.connect(endpoint1, null, context);
|
||||
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getLeased());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getLeased());
|
||||
|
|
|
@ -126,7 +126,6 @@ public class ConnectionConfig implements Cloneable {
|
|||
this.connectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see #setSocketTimeout(Timeout)
|
||||
*/
|
||||
|
@ -138,7 +137,7 @@ public class ConnectionConfig implements Cloneable {
|
|||
/**
|
||||
* Determines the default socket timeout value for I/O operations.
|
||||
* <p>
|
||||
* Default: {@code null}
|
||||
* Default: {@code null} (undefined)
|
||||
* </p>
|
||||
*
|
||||
* @return the default socket timeout value for I/O operations.
|
||||
|
@ -150,8 +149,6 @@ public class ConnectionConfig implements Cloneable {
|
|||
|
||||
/**
|
||||
* Determines the timeout until a new connection is fully established.
|
||||
* This may also include transport security negotiation exchanges
|
||||
* such as {@code SSL} or {@code TLS} protocol negotiation).
|
||||
* <p>
|
||||
* A timeout value of zero is interpreted as an infinite timeout.
|
||||
* </p>
|
||||
|
@ -177,7 +174,7 @@ public class ConnectionConfig implements Cloneable {
|
|||
* be re-validated prior to being leased to the consumer. Negative values passed
|
||||
* to this method disable connection validation.
|
||||
* <p>
|
||||
* Default: {@code null}
|
||||
* Default: {@code null} (undefined)
|
||||
* </p>
|
||||
*/
|
||||
public Builder setValidateAfterInactivity(final TimeValue validateAfterInactivity) {
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Immutable class encapsulating TLS protocol settings.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
@Contract(threading = ThreadingBehavior.IMMUTABLE)
|
||||
public class TlsConfig implements Cloneable {
|
||||
|
||||
public static final TlsConfig DEFAULT = new Builder().build();
|
||||
|
||||
private final Timeout handshakeTimeout;
|
||||
private final String[] supportedProtocols;
|
||||
private final String[] supportedCipherSuites;
|
||||
private final HttpVersionPolicy httpVersionPolicy;
|
||||
|
||||
/**
|
||||
* Intended for CDI compatibility
|
||||
*/
|
||||
protected TlsConfig() {
|
||||
this(null, null, null, null);
|
||||
}
|
||||
|
||||
TlsConfig(
|
||||
final Timeout handshakeTimeout,
|
||||
final String[] supportedProtocols,
|
||||
final String[] supportedCipherSuites,
|
||||
final HttpVersionPolicy httpVersionPolicy) {
|
||||
super();
|
||||
this.handshakeTimeout = handshakeTimeout;
|
||||
this.supportedProtocols = supportedProtocols;
|
||||
this.supportedCipherSuites = supportedCipherSuites;
|
||||
this.httpVersionPolicy = httpVersionPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Builder#setHandshakeTimeout(Timeout)
|
||||
*/
|
||||
public Timeout getHandshakeTimeout() {
|
||||
return handshakeTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Builder#setSupportedProtocols(String...)
|
||||
*/
|
||||
public String[] getSupportedProtocols() {
|
||||
return supportedProtocols != null ? supportedProtocols.clone() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Builder#setSupportedCipherSuites(String...)
|
||||
*/
|
||||
public String[] getSupportedCipherSuites() {
|
||||
return supportedCipherSuites != null ? supportedCipherSuites.clone() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Builder#setVersionPolicy(HttpVersionPolicy)
|
||||
*/
|
||||
public HttpVersionPolicy getHttpVersionPolicy() {
|
||||
return httpVersionPolicy;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TlsConfig clone() throws CloneNotSupportedException {
|
||||
return (TlsConfig) super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("[");
|
||||
builder.append("handshakeTimeout=").append(handshakeTimeout);
|
||||
builder.append(", supportedProtocols=").append(Arrays.asList(supportedProtocols));
|
||||
builder.append(", supportedCipherSuites=").append(Arrays.asList(supportedCipherSuites));
|
||||
builder.append(", httpVersionPolicy=").append(httpVersionPolicy);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static TlsConfig.Builder custom() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static TlsConfig.Builder copy(final TlsConfig config) {
|
||||
return new Builder()
|
||||
.setHandshakeTimeout(config.getHandshakeTimeout())
|
||||
.setSupportedProtocols(config.getSupportedProtocols())
|
||||
.setSupportedCipherSuites(config.getSupportedCipherSuites())
|
||||
.setVersionPolicy(config.getHttpVersionPolicy());
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private Timeout handshakeTimeout;
|
||||
private String[] supportedProtocols;
|
||||
private String[] supportedCipherSuites;
|
||||
private HttpVersionPolicy versionPolicy;
|
||||
|
||||
/**
|
||||
* Determines the timeout used by TLS session negotiation exchanges (session handshake).
|
||||
* <p>
|
||||
* A timeout value of zero is interpreted as an infinite timeout.
|
||||
* </p>
|
||||
* <p>
|
||||
* Default: {@code null} (undefined)
|
||||
* </p>
|
||||
*/
|
||||
public Builder setHandshakeTimeout(final Timeout handshakeTimeout) {
|
||||
this.handshakeTimeout = handshakeTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #setHandshakeTimeout(Timeout)
|
||||
*/
|
||||
public Builder setHandshakeTimeout(final long handshakeTimeout, final TimeUnit timeUnit) {
|
||||
this.handshakeTimeout = Timeout.of(handshakeTimeout, timeUnit);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines supported TLS protocols.
|
||||
* <p>
|
||||
* Default: {@code null} (undefined)
|
||||
* </p>
|
||||
*/
|
||||
public Builder setSupportedProtocols(final String... supportedProtocols) {
|
||||
this.supportedProtocols = supportedProtocols;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines supported cipher suites.
|
||||
* <p>
|
||||
* Default: {@code null} (undefined)
|
||||
* </p>
|
||||
*/
|
||||
public Builder setSupportedCipherSuites(final String... supportedCipherSuites) {
|
||||
this.supportedCipherSuites = supportedCipherSuites;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the HTTP protocol policy. By default, connections are expected to use TLS ALPN
|
||||
* extension to negotiate the application protocol to be used by both endpoints.
|
||||
* </p>
|
||||
* <p>
|
||||
* Default: {@link HttpVersionPolicy#NEGOTIATE}
|
||||
* </p>
|
||||
*/
|
||||
public Builder setVersionPolicy(final HttpVersionPolicy versionPolicy) {
|
||||
this.versionPolicy = versionPolicy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TlsConfig build() {
|
||||
return new TlsConfig(
|
||||
handshakeTimeout,
|
||||
supportedProtocols,
|
||||
supportedCipherSuites,
|
||||
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -47,6 +47,7 @@ import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
|||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||
import org.apache.hc.client5.http.cookie.CookieSpecFactory;
|
||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||
|
@ -196,7 +197,11 @@ public class HttpAsyncClientBuilder {
|
|||
|
||||
}
|
||||
|
||||
private HttpVersionPolicy versionPolicy;
|
||||
/**
|
||||
* @deprecated TLS should be configured by the connection manager
|
||||
*/
|
||||
@Deprecated
|
||||
private TlsConfig tlsConfig;
|
||||
private AsyncClientConnectionManager connManager;
|
||||
private boolean connManagerShared;
|
||||
private IOReactorConfig ioReactorConfig;
|
||||
|
@ -254,9 +259,12 @@ public class HttpAsyncClientBuilder {
|
|||
|
||||
/**
|
||||
* Sets HTTP protocol version policy.
|
||||
*
|
||||
* @deprecated Use {@link TlsConfig} and connection nanager methods
|
||||
*/
|
||||
@Deprecated
|
||||
public final HttpAsyncClientBuilder setVersionPolicy(final HttpVersionPolicy versionPolicy) {
|
||||
this.versionPolicy = versionPolicy;
|
||||
this.tlsConfig = versionPolicy != null ? TlsConfig.custom().setVersionPolicy(versionPolicy).build() : null;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -903,7 +911,6 @@ public class HttpAsyncClientBuilder {
|
|||
final IOEventHandlerFactory ioEventHandlerFactory = new HttpAsyncClientEventHandlerFactory(
|
||||
new DefaultHttpProcessor(new H2RequestContent(), new H2RequestTargetHost(), new H2RequestConnControl()),
|
||||
(request, context) -> pushConsumerRegistry.get(request),
|
||||
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
|
||||
h2Config != null ? h2Config : H2Config.DEFAULT,
|
||||
h1Config != null ? h1Config : Http1Config.DEFAULT,
|
||||
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
|
||||
|
@ -986,7 +993,7 @@ public class HttpAsyncClientBuilder {
|
|||
threadFactory != null ? threadFactory : new DefaultThreadFactory("httpclient-main", true),
|
||||
connManagerCopy,
|
||||
routePlannerCopy,
|
||||
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
|
||||
tlsConfig,
|
||||
cookieSpecRegistryCopy,
|
||||
authSchemeRegistryCopy,
|
||||
cookieStoreCopy,
|
||||
|
|
|
@ -74,7 +74,6 @@ class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory {
|
|||
|
||||
private final HttpProcessor httpProcessor;
|
||||
private final HandlerFactory<AsyncPushConsumer> exchangeHandlerFactory;
|
||||
private final HttpVersionPolicy versionPolicy;
|
||||
private final H2Config h2Config;
|
||||
private final Http1Config h1Config;
|
||||
private final CharCodingConfig charCodingConfig;
|
||||
|
@ -85,14 +84,12 @@ class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory {
|
|||
HttpAsyncClientEventHandlerFactory(
|
||||
final HttpProcessor httpProcessor,
|
||||
final HandlerFactory<AsyncPushConsumer> exchangeHandlerFactory,
|
||||
final HttpVersionPolicy versionPolicy,
|
||||
final H2Config h2Config,
|
||||
final Http1Config h1Config,
|
||||
final CharCodingConfig charCodingConfig,
|
||||
final ConnectionReuseStrategy connectionReuseStrategy) {
|
||||
this.httpProcessor = Args.notNull(httpProcessor, "HTTP processor");
|
||||
this.exchangeHandlerFactory = exchangeHandlerFactory;
|
||||
this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
|
||||
this.h2Config = h2Config != null ? h2Config : H2Config.DEFAULT;
|
||||
this.h1Config = h1Config != null ? h1Config : Http1Config.DEFAULT;
|
||||
this.charCodingConfig = charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT;
|
||||
|
@ -238,7 +235,7 @@ class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory {
|
|||
ioSession,
|
||||
http1StreamHandlerFactory,
|
||||
http2StreamHandlerFactory,
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy);
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : null);
|
||||
}
|
||||
final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
|
||||
httpProcessor,
|
||||
|
@ -258,7 +255,7 @@ class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory {
|
|||
ioSession,
|
||||
http1StreamHandlerFactory,
|
||||
http2StreamHandlerFactory,
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy);
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ package org.apache.hc.client5.http.impl.async;
|
|||
import org.apache.hc.client5.http.DnsResolver;
|
||||
import org.apache.hc.client5.http.SchemePortResolver;
|
||||
import org.apache.hc.client5.http.SystemDefaultDnsResolver;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.DefaultClientConnectionReuseStrategy;
|
||||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
|
@ -122,26 +123,29 @@ public final class HttpAsyncClients {
|
|||
private static MinimalHttpAsyncClient createMinimalHttpAsyncClientImpl(
|
||||
final IOEventHandlerFactory eventHandlerFactory,
|
||||
final AsyncPushConsumerRegistry pushConsumerRegistry,
|
||||
final HttpVersionPolicy versionPolicy,
|
||||
final IOReactorConfig ioReactorConfig,
|
||||
final AsyncClientConnectionManager connmgr,
|
||||
final SchemePortResolver schemePortResolver) {
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final TlsConfig tlsConfig) {
|
||||
return new MinimalHttpAsyncClient(
|
||||
eventHandlerFactory,
|
||||
pushConsumerRegistry,
|
||||
versionPolicy,
|
||||
ioReactorConfig,
|
||||
new DefaultThreadFactory("httpclient-main", true),
|
||||
new DefaultThreadFactory("httpclient-dispatch", true),
|
||||
connmgr,
|
||||
schemePortResolver);
|
||||
schemePortResolver,
|
||||
tlsConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link MinimalHttpAsyncClient} instance optimized for
|
||||
* HTTP/1.1 and HTTP/2 message transport without advanced HTTP protocol
|
||||
* functionality.
|
||||
*
|
||||
* @deprecated Use {@link #createMinimal(H2Config, Http1Config, IOReactorConfig, AsyncClientConnectionManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static MinimalHttpAsyncClient createMinimal(
|
||||
final HttpVersionPolicy versionPolicy,
|
||||
final H2Config h2Config,
|
||||
|
@ -153,16 +157,60 @@ public final class HttpAsyncClients {
|
|||
new HttpAsyncClientEventHandlerFactory(
|
||||
createMinimalProtocolProcessor(),
|
||||
(request, context) -> pushConsumerRegistry.get(request),
|
||||
versionPolicy,
|
||||
h2Config,
|
||||
h1Config,
|
||||
CharCodingConfig.DEFAULT,
|
||||
DefaultClientConnectionReuseStrategy.INSTANCE),
|
||||
pushConsumerRegistry,
|
||||
versionPolicy,
|
||||
ioReactorConfig,
|
||||
connmgr,
|
||||
DefaultSchemePortResolver.INSTANCE);
|
||||
DefaultSchemePortResolver.INSTANCE,
|
||||
versionPolicy != null ? TlsConfig.custom().setVersionPolicy(versionPolicy).build() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link MinimalHttpAsyncClient} instance optimized for
|
||||
* HTTP/1.1 and HTTP/2 message transport without advanced HTTP protocol
|
||||
* functionality.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static MinimalHttpAsyncClient createMinimal(
|
||||
final H2Config h2Config,
|
||||
final Http1Config h1Config,
|
||||
final IOReactorConfig ioReactorConfig,
|
||||
final AsyncClientConnectionManager connmgr) {
|
||||
final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
|
||||
return createMinimalHttpAsyncClientImpl(
|
||||
new HttpAsyncClientEventHandlerFactory(
|
||||
createMinimalProtocolProcessor(),
|
||||
(request, context) -> pushConsumerRegistry.get(request),
|
||||
h2Config,
|
||||
h1Config,
|
||||
CharCodingConfig.DEFAULT,
|
||||
DefaultClientConnectionReuseStrategy.INSTANCE),
|
||||
pushConsumerRegistry,
|
||||
ioReactorConfig,
|
||||
connmgr,
|
||||
DefaultSchemePortResolver.INSTANCE,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link MinimalHttpAsyncClient} instance optimized for
|
||||
* HTTP/1.1 and HTTP/2 message transport without advanced HTTP protocol
|
||||
* functionality.
|
||||
*
|
||||
* @deprecated Use {@link #createMinimal(H2Config, Http1Config, IOReactorConfig)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static MinimalHttpAsyncClient createMinimal(
|
||||
final HttpVersionPolicy versionPolicy,
|
||||
final H2Config h2Config,
|
||||
final Http1Config h1Config,
|
||||
final IOReactorConfig ioReactorConfig) {
|
||||
return createMinimal(versionPolicy, h2Config, h1Config, ioReactorConfig,
|
||||
PoolingAsyncClientConnectionManagerBuilder.create().build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,11 +219,10 @@ public final class HttpAsyncClients {
|
|||
* functionality.
|
||||
*/
|
||||
public static MinimalHttpAsyncClient createMinimal(
|
||||
final HttpVersionPolicy versionPolicy,
|
||||
final H2Config h2Config,
|
||||
final Http1Config h1Config,
|
||||
final IOReactorConfig ioReactorConfig) {
|
||||
return createMinimal(versionPolicy, h2Config, h1Config, ioReactorConfig,
|
||||
return createMinimal(h2Config, h1Config, ioReactorConfig,
|
||||
PoolingAsyncClientConnectionManagerBuilder.create().build());
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.hc.client5.http.async.AsyncExecRuntime;
|
|||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.cookie.CookieSpecFactory;
|
||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
|
||||
|
@ -48,7 +49,6 @@ import org.apache.hc.core5.http.HttpHost;
|
|||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -71,7 +71,7 @@ public final class InternalHttpAsyncClient extends InternalAbstractHttpAsyncClie
|
|||
private static final Logger LOG = LoggerFactory.getLogger(InternalHttpAsyncClient.class);
|
||||
private final AsyncClientConnectionManager manager;
|
||||
private final HttpRoutePlanner routePlanner;
|
||||
private final HttpVersionPolicy versionPolicy;
|
||||
private final TlsConfig tlsConfig;
|
||||
|
||||
InternalHttpAsyncClient(
|
||||
final DefaultConnectingIOReactor ioReactor,
|
||||
|
@ -80,7 +80,7 @@ public final class InternalHttpAsyncClient extends InternalAbstractHttpAsyncClie
|
|||
final ThreadFactory threadFactory,
|
||||
final AsyncClientConnectionManager manager,
|
||||
final HttpRoutePlanner routePlanner,
|
||||
final HttpVersionPolicy versionPolicy,
|
||||
final TlsConfig tlsConfig,
|
||||
final Lookup<CookieSpecFactory> cookieSpecRegistry,
|
||||
final Lookup<AuthSchemeFactory> authSchemeRegistry,
|
||||
final CookieStore cookieStore,
|
||||
|
@ -91,12 +91,12 @@ public final class InternalHttpAsyncClient extends InternalAbstractHttpAsyncClie
|
|||
cookieSpecRegistry, authSchemeRegistry, cookieStore, credentialsProvider, defaultConfig, closeables);
|
||||
this.manager = manager;
|
||||
this.routePlanner = routePlanner;
|
||||
this.versionPolicy = versionPolicy;
|
||||
this.tlsConfig = tlsConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
AsyncExecRuntime createAsyncExecRuntime(final HandlerFactory<AsyncPushConsumer> pushHandlerFactory) {
|
||||
return new InternalHttpAsyncExecRuntime(LOG, manager, getConnectionInitiator(), pushHandlerFactory, versionPolicy);
|
||||
return new InternalHttpAsyncExecRuntime(LOG, manager, getConnectionInitiator(), pushHandlerFactory, tlsConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import org.apache.hc.client5.http.HttpRoute;
|
||||
import org.apache.hc.client5.http.async.AsyncExecRuntime;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.ConnPoolSupport;
|
||||
import org.apache.hc.client5.http.impl.Operations;
|
||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
|
||||
|
@ -44,7 +45,6 @@ import org.apache.hc.core5.concurrent.FutureCallback;
|
|||
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.reactor.ConnectionInitiator;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
@ -57,7 +57,11 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
|
|||
private final AsyncClientConnectionManager manager;
|
||||
private final ConnectionInitiator connectionInitiator;
|
||||
private final HandlerFactory<AsyncPushConsumer> pushHandlerFactory;
|
||||
private final HttpVersionPolicy versionPolicy;
|
||||
/**
|
||||
* @deprecated TLS should be configured by the connection manager
|
||||
*/
|
||||
@Deprecated
|
||||
private final TlsConfig tlsConfig;
|
||||
private final AtomicReference<AsyncConnectionEndpoint> endpointRef;
|
||||
private volatile boolean reusable;
|
||||
private volatile Object state;
|
||||
|
@ -68,14 +72,14 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
|
|||
final AsyncClientConnectionManager manager,
|
||||
final ConnectionInitiator connectionInitiator,
|
||||
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
|
||||
final HttpVersionPolicy versionPolicy) {
|
||||
final TlsConfig tlsConfig) {
|
||||
super();
|
||||
this.log = log;
|
||||
this.manager = manager;
|
||||
this.connectionInitiator = connectionInitiator;
|
||||
this.pushHandlerFactory = pushHandlerFactory;
|
||||
this.versionPolicy = versionPolicy;
|
||||
this.endpointRef = new AtomicReference<>();
|
||||
this.tlsConfig = tlsConfig;
|
||||
this.endpointRef = new AtomicReference<>(null);
|
||||
this.validDuration = TimeValue.NEG_ONE_MILLISECOND;
|
||||
}
|
||||
|
||||
|
@ -213,7 +217,7 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
|
|||
endpoint,
|
||||
connectionInitiator,
|
||||
connectTimeout,
|
||||
versionPolicy,
|
||||
tlsConfig,
|
||||
context,
|
||||
new CallbackContribution<AsyncConnectionEndpoint>(callback) {
|
||||
|
||||
|
@ -242,7 +246,7 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
|
|||
if (log.isDebugEnabled()) {
|
||||
log.debug("{} upgrading endpoint", ConnPoolSupport.getId(endpoint));
|
||||
}
|
||||
manager.upgrade(endpoint, versionPolicy, context, new CallbackContribution<AsyncConnectionEndpoint>(callback) {
|
||||
manager.upgrade(endpoint, tlsConfig, context, new CallbackContribution<AsyncConnectionEndpoint>(callback) {
|
||||
|
||||
@Override
|
||||
public void completed(final AsyncConnectionEndpoint endpoint) {
|
||||
|
@ -320,7 +324,7 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
|
|||
|
||||
@Override
|
||||
public AsyncExecRuntime fork() {
|
||||
return new InternalHttpAsyncExecRuntime(log, manager, connectionInitiator, pushHandlerFactory, versionPolicy);
|
||||
return new InternalHttpAsyncExecRuntime(log, manager, connectionInitiator, pushHandlerFactory, tlsConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.apache.hc.client5.http.HttpRoute;
|
|||
import org.apache.hc.client5.http.SchemePortResolver;
|
||||
import org.apache.hc.client5.http.config.Configurable;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.ConnPoolSupport;
|
||||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
|
||||
import org.apache.hc.client5.http.impl.ExecSupport;
|
||||
|
@ -69,7 +70,6 @@ import org.apache.hc.core5.http.nio.HandlerFactory;
|
|||
import org.apache.hc.core5.http.nio.RequestChannel;
|
||||
import org.apache.hc.core5.http.nio.command.ShutdownCommand;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.io.Closer;
|
||||
import org.apache.hc.core5.reactor.Command;
|
||||
|
@ -101,17 +101,17 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
|
|||
private static final Logger LOG = LoggerFactory.getLogger(MinimalHttpAsyncClient.class);
|
||||
private final AsyncClientConnectionManager manager;
|
||||
private final SchemePortResolver schemePortResolver;
|
||||
private final HttpVersionPolicy versionPolicy;
|
||||
private final TlsConfig tlsConfig;
|
||||
|
||||
MinimalHttpAsyncClient(
|
||||
final IOEventHandlerFactory eventHandlerFactory,
|
||||
final AsyncPushConsumerRegistry pushConsumerRegistry,
|
||||
final HttpVersionPolicy versionPolicy,
|
||||
final IOReactorConfig reactorConfig,
|
||||
final ThreadFactory threadFactory,
|
||||
final ThreadFactory workerThreadFactory,
|
||||
final AsyncClientConnectionManager manager,
|
||||
final SchemePortResolver schemePortResolver) {
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final TlsConfig tlsConfig) {
|
||||
super(new DefaultConnectingIOReactor(
|
||||
eventHandlerFactory,
|
||||
reactorConfig,
|
||||
|
@ -124,7 +124,7 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
|
|||
threadFactory);
|
||||
this.manager = manager;
|
||||
this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE;
|
||||
this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
|
||||
this.tlsConfig = tlsConfig;
|
||||
}
|
||||
|
||||
private Future<AsyncConnectionEndpoint> leaseEndpoint(
|
||||
|
@ -153,7 +153,7 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
|
|||
connectionEndpoint,
|
||||
getConnectionInitiator(),
|
||||
connectTimeout,
|
||||
versionPolicy,
|
||||
tlsConfig,
|
||||
clientContext,
|
||||
new FutureCallback<AsyncConnectionEndpoint>() {
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ 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.impl.ConnPoolSupport;
|
||||
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
|
||||
import org.apache.hc.client5.http.io.ConnectionEndpoint;
|
||||
|
@ -109,6 +110,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
|
|||
private boolean leased;
|
||||
private SocketConfig socketConfig;
|
||||
private ConnectionConfig connectionConfig;
|
||||
private TlsConfig tlsConfig;
|
||||
|
||||
private final AtomicBoolean closed;
|
||||
|
||||
|
@ -142,6 +144,8 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
|
|||
this.id = String.format("ep-%010d", COUNT.getAndIncrement());
|
||||
this.expiry = Long.MAX_VALUE;
|
||||
this.socketConfig = SocketConfig.DEFAULT;
|
||||
this.connectionConfig = ConnectionConfig.DEFAULT;
|
||||
this.tlsConfig = TlsConfig.DEFAULT;
|
||||
this.closed = new AtomicBoolean(false);
|
||||
this.validateAfterInactivity = TimeValue.ofSeconds(2L);
|
||||
}
|
||||
|
@ -203,6 +207,13 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
|
|||
this.connectionConfig = connectionConfig != null ? connectionConfig : ConnectionConfig.DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public synchronized void setTlsConfig(final TlsConfig tlsConfig) {
|
||||
this.tlsConfig = tlsConfig != null ? tlsConfig : TlsConfig.DEFAULT;
|
||||
}
|
||||
|
||||
public LeaseRequest lease(final String id, final HttpRoute route, final Object state) {
|
||||
return lease(id, route, Timeout.DISABLED, state);
|
||||
}
|
||||
|
@ -358,8 +369,7 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
|
|||
} else {
|
||||
host = route.getTargetHost();
|
||||
}
|
||||
final ConnectionConfig config = connectionConfig != null ? connectionConfig : ConnectionConfig.DEFAULT;
|
||||
final TimeValue connectTimeout = timeout != null ? timeout : config.getConnectTimeout();
|
||||
final Timeout connectTimeout = timeout != null ? Timeout.of(timeout.getDuration(), timeout.getTimeUnit()) : connectionConfig.getConnectTimeout();
|
||||
final ManagedHttpClientConnection connection = internalEndpoint.getConnection();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} connecting endpoint to {} ({})", ConnPoolSupport.getId(endpoint), host, connectTimeout);
|
||||
|
@ -369,12 +379,13 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
|
|||
host,
|
||||
route.getLocalSocketAddress(),
|
||||
connectTimeout,
|
||||
this.socketConfig,
|
||||
socketConfig,
|
||||
tlsConfig,
|
||||
context);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} connected {}", ConnPoolSupport.getId(endpoint), ConnPoolSupport.getId(conn));
|
||||
}
|
||||
final Timeout socketTimeout = config.getSocketTimeout();
|
||||
final Timeout socketTimeout = connectionConfig.getSocketTimeout();
|
||||
if (socketTimeout != null) {
|
||||
connection.setSocketTimeout(socketTimeout);
|
||||
}
|
||||
|
@ -387,9 +398,11 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
|
|||
Args.notNull(endpoint, "Endpoint");
|
||||
Args.notNull(route, "HTTP route");
|
||||
final InternalConnectionEndpoint internalEndpoint = cast(endpoint);
|
||||
final ConnectionConfig config = connectionConfig != null ? connectionConfig : ConnectionConfig.DEFAULT;
|
||||
this.connectionOperator.upgrade(
|
||||
internalEndpoint.getConnection(),
|
||||
internalEndpoint.getRoute().getTargetHost(),
|
||||
tlsConfig,
|
||||
context);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.apache.hc.core5.http.io.SocketConfig;
|
|||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -107,6 +108,19 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
|
|||
final TimeValue connectTimeout,
|
||||
final SocketConfig socketConfig,
|
||||
final HttpContext context) throws IOException {
|
||||
final Timeout timeout = connectTimeout != null ? Timeout.of(connectTimeout.getDuration(), connectTimeout.getTimeUnit()) : null;
|
||||
connect(conn, host, localAddress, timeout, socketConfig, null, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(
|
||||
final ManagedHttpClientConnection conn,
|
||||
final HttpHost host,
|
||||
final InetSocketAddress localAddress,
|
||||
final Timeout connectTimeout,
|
||||
final SocketConfig socketConfig,
|
||||
final Object attachment,
|
||||
final HttpContext context) throws IOException {
|
||||
Args.notNull(conn, "Connection");
|
||||
Args.notNull(host, "Host");
|
||||
Args.notNull(socketConfig, "Socket config");
|
||||
|
@ -131,13 +145,17 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
|
|||
}
|
||||
}
|
||||
|
||||
final Timeout soTimeout = socketConfig.getSoTimeout();
|
||||
|
||||
final int port = this.schemePortResolver.resolve(host);
|
||||
for (int i = 0; i < remoteAddresses.length; i++) {
|
||||
final InetAddress address = remoteAddresses[i];
|
||||
final boolean last = i == remoteAddresses.length - 1;
|
||||
|
||||
Socket sock = sf.createSocket(context);
|
||||
sock.setSoTimeout(socketConfig.getSoTimeout().toMillisecondsIntBound());
|
||||
if (soTimeout != null) {
|
||||
sock.setSoTimeout(soTimeout.toMillisecondsIntBound());
|
||||
}
|
||||
sock.setReuseAddress(socketConfig.isSoReuseAddress());
|
||||
sock.setTcpNoDelay(socketConfig.isTcpNoDelay());
|
||||
sock.setKeepAlive(socketConfig.isSoKeepAlive());
|
||||
|
@ -160,8 +178,9 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
|
|||
host.getHostName(), host.getPort(), localAddress, remoteAddress, connectTimeout);
|
||||
}
|
||||
try {
|
||||
sock = sf.connectSocket(connectTimeout, sock, host, remoteAddress, localAddress, context);
|
||||
sock = sf.connectSocket(sock, host, remoteAddress, localAddress, connectTimeout, attachment, context);
|
||||
conn.bind(sock);
|
||||
conn.setSocketTimeout(soTimeout);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{}:{} connected {}->{} as {}",
|
||||
host.getHostName(), host.getPort(), localAddress, remoteAddress, ConnPoolSupport.getId(conn));
|
||||
|
@ -189,6 +208,15 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
|
|||
final ManagedHttpClientConnection conn,
|
||||
final HttpHost host,
|
||||
final HttpContext context) throws IOException {
|
||||
upgrade(conn, host, null, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upgrade(
|
||||
final ManagedHttpClientConnection conn,
|
||||
final HttpHost host,
|
||||
final Object attachment,
|
||||
final HttpContext context) throws IOException {
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
final Lookup<ConnectionSocketFactory> registry = getSocketFactoryRegistry(clientContext);
|
||||
final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName());
|
||||
|
@ -206,7 +234,7 @@ public class DefaultHttpClientConnectionOperator implements HttpClientConnection
|
|||
throw new ConnectionClosedException("Connection is closed");
|
||||
}
|
||||
final int port = this.schemePortResolver.resolve(host);
|
||||
sock = lsf.createLayeredSocket(sock, host.getHostName(), port, context);
|
||||
sock = lsf.createLayeredSocket(sock, host.getHostName(), port, attachment, context);
|
||||
conn.bind(sock);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ 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.impl.ConnPoolSupport;
|
||||
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
|
||||
import org.apache.hc.client5.http.io.ConnectionEndpoint;
|
||||
|
@ -115,6 +116,7 @@ public class PoolingHttpClientConnectionManager
|
|||
|
||||
private volatile Resolver<HttpRoute, SocketConfig> socketConfigResolver;
|
||||
private volatile Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver;
|
||||
private volatile Resolver<HttpHost, TlsConfig> tlsConfigResolver;
|
||||
|
||||
public PoolingHttpClientConnectionManager() {
|
||||
this(RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
|
@ -241,16 +243,22 @@ public class PoolingHttpClientConnectionManager
|
|||
throw new IllegalStateException("Unexpected endpoint class: " + endpoint.getClass());
|
||||
}
|
||||
|
||||
private SocketConfig resolveSocketConfig(final HttpRoute route) {
|
||||
final Resolver<HttpRoute, SocketConfig> resolver = this.socketConfigResolver;
|
||||
final SocketConfig socketConfig = resolver != null ? resolver.resolve(route) : null;
|
||||
return socketConfig != null ? socketConfig : SocketConfig.DEFAULT;
|
||||
}
|
||||
|
||||
private ConnectionConfig resolveConnectionConfig(final HttpRoute route) {
|
||||
final Resolver<HttpRoute, ConnectionConfig> resolver = this.connectionConfigResolver;
|
||||
final ConnectionConfig connectionConfig = resolver != null ? resolver.resolve(route) : null;
|
||||
return connectionConfig != null ? connectionConfig : ConnectionConfig.DEFAULT;
|
||||
}
|
||||
|
||||
private SocketConfig resolveSocketConfig(final HttpRoute route) {
|
||||
final Resolver<HttpRoute, SocketConfig> resolver = this.socketConfigResolver;
|
||||
final SocketConfig socketConfig = resolver != null ? resolver.resolve(route) : null;
|
||||
return socketConfig != null ? socketConfig : SocketConfig.DEFAULT;
|
||||
private TlsConfig resolveTlsConfig(final HttpHost host) {
|
||||
final Resolver<HttpHost, TlsConfig> resolver = this.tlsConfigResolver;
|
||||
final TlsConfig tlsConfig = resolver != null ? resolver.resolve(host) : null;
|
||||
return tlsConfig != null ? tlsConfig : TlsConfig.DEFAULT;
|
||||
}
|
||||
|
||||
private TimeValue resolveValidateAfterInactivity(final ConnectionConfig connectionConfig) {
|
||||
|
@ -401,15 +409,11 @@ public class PoolingHttpClientConnectionManager
|
|||
poolEntry.assignConnection(connFactory.createConnection(null));
|
||||
}
|
||||
final HttpRoute route = poolEntry.getRoute();
|
||||
final HttpHost host;
|
||||
if (route.getProxyHost() != null) {
|
||||
host = route.getProxyHost();
|
||||
} else {
|
||||
host = route.getTargetHost();
|
||||
}
|
||||
final HttpHost host = route.getProxyHost() != null ? route.getProxyHost() : route.getTargetHost();
|
||||
final SocketConfig socketConfig = resolveSocketConfig(route);
|
||||
final ConnectionConfig connectionConfig = resolveConnectionConfig(route);
|
||||
final TimeValue connectTimeout = timeout != null ? timeout : connectionConfig.getConnectTimeout();
|
||||
final TlsConfig tlsConfig = resolveTlsConfig(host);
|
||||
final Timeout connectTimeout = timeout != null ? Timeout.of(timeout.getDuration(), timeout.getTimeUnit()) : connectionConfig.getConnectTimeout();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} connecting endpoint to {} ({})", ConnPoolSupport.getId(endpoint), host, connectTimeout);
|
||||
}
|
||||
|
@ -418,8 +422,9 @@ public class PoolingHttpClientConnectionManager
|
|||
conn,
|
||||
host,
|
||||
route.getLocalSocketAddress(),
|
||||
timeout,
|
||||
connectTimeout,
|
||||
socketConfig,
|
||||
tlsConfig,
|
||||
context);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} connected {}", ConnPoolSupport.getId(endpoint), ConnPoolSupport.getId(conn));
|
||||
|
@ -436,7 +441,9 @@ public class PoolingHttpClientConnectionManager
|
|||
final InternalConnectionEndpoint internalEndpoint = cast(endpoint);
|
||||
final PoolEntry<HttpRoute, ManagedHttpClientConnection> poolEntry = internalEndpoint.getValidatedPoolEntry();
|
||||
final HttpRoute route = poolEntry.getRoute();
|
||||
this.connectionOperator.upgrade(poolEntry.getConnection(), route.getTargetHost(), context);
|
||||
final HttpHost host = route.getProxyHost() != null ? route.getProxyHost() : route.getTargetHost();
|
||||
final TlsConfig tlsConfig = resolveTlsConfig(host);
|
||||
this.connectionOperator.upgrade(poolEntry.getConnection(), route.getTargetHost(), tlsConfig, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -533,6 +540,24 @@ public class PoolingHttpClientConnectionManager
|
|||
this.connectionConfigResolver = connectionConfigResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the same {@link ConnectionConfig} for all hosts
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public void setDefaultTlsConfig(final TlsConfig config) {
|
||||
this.tlsConfigResolver = (host) -> config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@link Resolver} of {@link TlsConfig} on a per host basis.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public void setTlsConfigResolver(final Resolver<HttpHost, TlsConfig> tlsConfigResolver) {
|
||||
this.tlsConfigResolver = tlsConfigResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use custom {@link #setConnectionConfigResolver(Resolver)}
|
||||
*/
|
||||
|
|
|
@ -31,12 +31,14 @@ 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.core5.function.Resolver;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.URIScheme;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.io.HttpConnectionFactory;
|
||||
|
@ -81,6 +83,7 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
private PoolReusePolicy poolReusePolicy;
|
||||
private Resolver<HttpRoute, SocketConfig> socketConfigResolver;
|
||||
private Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver;
|
||||
private Resolver<HttpHost, TlsConfig> tlsConfigResolver;
|
||||
|
||||
private boolean systemProperties;
|
||||
|
||||
|
@ -203,6 +206,27 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the same {@link TlsConfig} for all hosts.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public final PoolingHttpClientConnectionManagerBuilder setDefaultTlsConfig(final TlsConfig config) {
|
||||
this.tlsConfigResolver = (host) -> config;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link Resolver} of {@link TlsConfig} on a per host basis.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public final PoolingHttpClientConnectionManagerBuilder setTlsConfigResolver(
|
||||
final Resolver<HttpHost, TlsConfig> tlsConfigResolver) {
|
||||
this.tlsConfigResolver = tlsConfigResolver;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets maximum time to live for persistent connections
|
||||
*/
|
||||
|
@ -251,6 +275,7 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
connectionFactory);
|
||||
poolingmgr.setSocketConfigResolver(socketConfigResolver);
|
||||
poolingmgr.setConnectionConfigResolver(connectionConfigResolver);
|
||||
poolingmgr.setTlsConfigResolver(tlsConfigResolver);
|
||||
if (maxConnTotal > 0) {
|
||||
poolingmgr.setMaxTotal(maxConnTotal);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.concurrent.Future;
|
|||
|
||||
import org.apache.hc.client5.http.DnsResolver;
|
||||
import org.apache.hc.client5.http.SchemePortResolver;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
|
||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionOperator;
|
||||
import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection;
|
||||
|
@ -81,13 +82,14 @@ final class DefaultAsyncClientConnectionOperator implements AsyncClientConnectio
|
|||
final HttpHost remoteEndpoint = RoutingSupport.normalize(host, schemePortResolver);
|
||||
final InetAddress remoteAddress = host.getAddress();
|
||||
final TlsStrategy tlsStrategy = tlsStrategyLookup != null ? tlsStrategyLookup.lookup(host.getSchemeName()) : null;
|
||||
final TlsConfig tlsConfig = attachment instanceof TlsConfig ? (TlsConfig) attachment : TlsConfig.DEFAULT;
|
||||
final Future<IOSession> sessionFuture = sessionRequester.connect(
|
||||
connectionInitiator,
|
||||
remoteEndpoint,
|
||||
remoteAddress != null ? new InetSocketAddress(remoteAddress, remoteEndpoint.getPort()) : null,
|
||||
localAddress,
|
||||
connectTimeout,
|
||||
attachment,
|
||||
tlsConfig.getHttpVersionPolicy(),
|
||||
new FutureCallback<IOSession>() {
|
||||
|
||||
@Override
|
||||
|
@ -95,15 +97,18 @@ final class DefaultAsyncClientConnectionOperator implements AsyncClientConnectio
|
|||
final DefaultManagedAsyncClientConnection connection = new DefaultManagedAsyncClientConnection(session);
|
||||
if (tlsStrategy != null && URIScheme.HTTPS.same(host.getSchemeName())) {
|
||||
try {
|
||||
final Timeout socketTimeout = connection.getSocketTimeout();
|
||||
final Timeout handshakeTimeout = tlsConfig.getHandshakeTimeout();
|
||||
tlsStrategy.upgrade(
|
||||
connection,
|
||||
host,
|
||||
attachment,
|
||||
null,
|
||||
handshakeTimeout != null ? handshakeTimeout : connectTimeout,
|
||||
new FutureContribution<TransportSecurityLayer>(future) {
|
||||
|
||||
@Override
|
||||
public void completed(final TransportSecurityLayer transportSecurityLayer) {
|
||||
connection.setSocketTimeout(socketTimeout);
|
||||
future.completed(connection);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ 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.impl.ConnPoolSupport;
|
||||
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
|
||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
|
||||
|
@ -123,6 +124,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
private final AtomicBoolean closed;
|
||||
|
||||
private volatile Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver;
|
||||
private volatile Resolver<HttpHost, TlsConfig> tlsConfigResolver;
|
||||
|
||||
public PoolingAsyncClientConnectionManager() {
|
||||
this(RegistryBuilder.<TlsStrategy>create()
|
||||
|
@ -227,6 +229,15 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
return connectionConfig != null ? connectionConfig : ConnectionConfig.DEFAULT;
|
||||
}
|
||||
|
||||
private TlsConfig resolveTlsConfig(final HttpHost host, final Object attachment) {
|
||||
if (attachment instanceof TlsConfig) {
|
||||
return (TlsConfig) attachment;
|
||||
}
|
||||
final Resolver<HttpHost, TlsConfig> resolver = this.tlsConfigResolver;
|
||||
final TlsConfig tlsConfig = resolver != null ? resolver.resolve(host) : null;
|
||||
return tlsConfig != null ? tlsConfig : TlsConfig.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<AsyncConnectionEndpoint> lease(
|
||||
final String id,
|
||||
|
@ -400,6 +411,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
}
|
||||
final InetSocketAddress localAddress = route.getLocalSocketAddress();
|
||||
final ConnectionConfig connectionConfig = resolveConnectionConfig(route);
|
||||
final TlsConfig tlsConfig = resolveTlsConfig(host, attachment);
|
||||
final Timeout connectTimeout = timeout != null ? timeout : connectionConfig.getConnectTimeout();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
@ -410,7 +422,9 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
host,
|
||||
localAddress,
|
||||
connectTimeout,
|
||||
route.isTunnelled() ? HttpVersionPolicy.FORCE_HTTP_1 : attachment,
|
||||
route.isTunnelled() ? TlsConfig.copy(tlsConfig)
|
||||
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
|
||||
.build() : tlsConfig,
|
||||
new FutureCallback<ManagedAsyncClientConnection>() {
|
||||
|
||||
@Override
|
||||
|
@ -455,10 +469,12 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
final InternalConnectionEndpoint internalEndpoint = cast(endpoint);
|
||||
final PoolEntry<HttpRoute, ManagedAsyncClientConnection> poolEntry = internalEndpoint.getValidatedPoolEntry();
|
||||
final HttpRoute route = poolEntry.getRoute();
|
||||
final HttpHost host = route.getProxyHost() != null ? route.getProxyHost() : route.getTargetHost();
|
||||
final TlsConfig tlsConfig = resolveTlsConfig(host, attachment);
|
||||
connectionOperator.upgrade(
|
||||
poolEntry.getConnection(),
|
||||
route.getTargetHost(),
|
||||
attachment,
|
||||
attachment != null ? attachment : tlsConfig,
|
||||
new CallbackContribution<ManagedAsyncClientConnection>(callback) {
|
||||
|
||||
@Override
|
||||
|
@ -566,6 +582,24 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
this.connectionConfigResolver = connectionConfigResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the same {@link ConnectionConfig} for all hosts
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public void setDefaultTlsConfig(final TlsConfig config) {
|
||||
this.tlsConfigResolver = (host) -> config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@link Resolver} of {@link TlsConfig} on a per host basis.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public void setTlsConfigResolver(final Resolver<HttpHost, TlsConfig> tlsConfigResolver) {
|
||||
this.tlsConfigResolver = tlsConfigResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use custom {@link #setConnectionConfigResolver(Resolver)}
|
||||
*/
|
||||
|
|
|
@ -31,9 +31,11 @@ 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.ssl.ConscryptClientTlsStrategy;
|
||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||
import org.apache.hc.core5.function.Resolver;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.io.SocketConfig;
|
||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||
|
@ -83,6 +85,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
|
||||
private Resolver<HttpRoute, SocketConfig> socketConfigResolver;
|
||||
private Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver;
|
||||
private Resolver<HttpHost, TlsConfig> tlsConfigResolver;
|
||||
private TimeValue timeToLive;
|
||||
|
||||
public static PoolingAsyncClientConnectionManagerBuilder create() {
|
||||
|
@ -171,6 +174,26 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the same {@link TlsConfig} for all hosts.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public final PoolingAsyncClientConnectionManagerBuilder setDefaultTlsConfig(final TlsConfig config) {
|
||||
this.tlsConfigResolver = (host) -> config;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link Resolver} of {@link TlsConfig} on a per host basis.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public final PoolingAsyncClientConnectionManagerBuilder setTlsConfigResolver(
|
||||
final Resolver<HttpHost, TlsConfig> tlsConfigResolver) {
|
||||
this.tlsConfigResolver = tlsConfigResolver;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets maximum time to live for persistent connections
|
||||
|
@ -232,6 +255,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
schemePortResolver,
|
||||
dnsResolver);
|
||||
poolingmgr.setConnectionConfigResolver(connectionConfigResolver);
|
||||
poolingmgr.setTlsConfigResolver(tlsConfigResolver);
|
||||
if (maxConnTotal > 0) {
|
||||
poolingmgr.setMaxTotal(maxConnTotal);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.hc.core5.http.HttpHost;
|
|||
import org.apache.hc.core5.http.io.SocketConfig;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Connection operator that performs connection connect and upgrade operations.
|
||||
|
@ -65,6 +66,30 @@ public interface HttpClientConnectionOperator {
|
|||
SocketConfig socketConfig,
|
||||
HttpContext context) throws IOException;
|
||||
|
||||
/**
|
||||
* Connect the given managed connection to the remote endpoint.
|
||||
*
|
||||
* @param conn the managed connection.
|
||||
* @param host the address of the opposite endpoint.
|
||||
* @param localAddress the address of the local endpoint.
|
||||
* @param connectTimeout the timeout of the connect operation.
|
||||
* @param socketConfig the socket configuration.
|
||||
* @param attachment connect request attachment.
|
||||
* @param context the execution context.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
default void connect(
|
||||
ManagedHttpClientConnection conn,
|
||||
HttpHost host,
|
||||
InetSocketAddress localAddress,
|
||||
Timeout connectTimeout,
|
||||
SocketConfig socketConfig,
|
||||
Object attachment,
|
||||
HttpContext context) throws IOException {
|
||||
connect(conn, host, localAddress, connectTimeout, socketConfig, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades transport security of the given managed connection
|
||||
* by using the TLS security protocol.
|
||||
|
@ -78,4 +103,23 @@ public interface HttpClientConnectionOperator {
|
|||
HttpHost host,
|
||||
HttpContext context) throws IOException;
|
||||
|
||||
/**
|
||||
* Upgrades transport security of the given managed connection
|
||||
* by using the TLS security protocol.
|
||||
*
|
||||
* @param conn the managed connection.
|
||||
* @param host the address of the opposite endpoint with TLS security.
|
||||
* @param attachment connect request attachment.
|
||||
* @param context the execution context.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
default void upgrade(
|
||||
ManagedHttpClientConnection conn,
|
||||
HttpHost host,
|
||||
Object attachment,
|
||||
HttpContext context) throws IOException {
|
||||
upgrade(conn, host, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ public interface AsyncClientConnectionOperator {
|
|||
Object attachment,
|
||||
FutureCallback<ManagedAsyncClientConnection> callback);
|
||||
|
||||
|
||||
/**
|
||||
* Upgrades transport security of the given managed connection
|
||||
* by using the TLS security protocol.
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
|
|||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* A factory for creating and connecting connection sockets.
|
||||
|
@ -81,4 +82,35 @@ public interface ConnectionSocketFactory {
|
|||
InetSocketAddress localAddress,
|
||||
HttpContext context) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects the socket to the target host with the given resolved remote address.
|
||||
*
|
||||
* @param socket the socket to connect, as obtained from {@link #createSocket(HttpContext)}.
|
||||
* {@code null} indicates that a new socket should be created and connected.
|
||||
* @param host target host as specified by the caller (end user).
|
||||
* @param remoteAddress the resolved remote address to connect to.
|
||||
* @param localAddress the local address to bind the socket to, or {@code null} for any.
|
||||
* @param connectTimeout connect timeout.
|
||||
* @param attachment connect request attachment.
|
||||
* @param context the actual HTTP context.
|
||||
*
|
||||
* @return the connected socket. The returned object may be different
|
||||
* from the {@code sock} argument if this factory supports
|
||||
* a layered protocol.
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
default Socket connectSocket(
|
||||
Socket socket,
|
||||
HttpHost host,
|
||||
InetSocketAddress remoteAddress,
|
||||
InetSocketAddress localAddress,
|
||||
Timeout connectTimeout,
|
||||
Object attachment,
|
||||
HttpContext context) throws IOException {
|
||||
return connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,4 +62,30 @@ public interface LayeredConnectionSocketFactory extends ConnectionSocketFactory
|
|||
int port,
|
||||
HttpContext context) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns a socket connected to the given host that is layered over an
|
||||
* existing socket. Used primarily for creating secure sockets through
|
||||
* proxies.
|
||||
*
|
||||
* @param socket the existing socket
|
||||
* @param target the name of the target host.
|
||||
* @param port the port to connect to on the target host.
|
||||
* @param context the actual HTTP context.
|
||||
* @param attachment connect request attachment.
|
||||
*
|
||||
* @return Socket a new socket
|
||||
*
|
||||
* @throws IOException if an I/O error occurs while creating the socket
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
default Socket createLayeredSocket(
|
||||
Socket socket,
|
||||
String target,
|
||||
int port,
|
||||
Object attachment,
|
||||
HttpContext context) throws IOException {
|
||||
return createLayeredSocket(socket, target, port, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import javax.net.ssl.SSLHandshakeException;
|
|||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
|
@ -109,17 +110,23 @@ abstract class AbstractClientTlsStrategy implements TlsStrategy {
|
|||
final FutureCallback<TransportSecurityLayer> callback) {
|
||||
tlsSession.startTls(sslContext, endpoint, sslBufferManagement, (e, sslEngine) -> {
|
||||
|
||||
final HttpVersionPolicy versionPolicy = attachment instanceof HttpVersionPolicy ?
|
||||
(HttpVersionPolicy) attachment : HttpVersionPolicy.NEGOTIATE;
|
||||
final TlsConfig tlsConfig = attachment instanceof TlsConfig ? (TlsConfig) attachment : TlsConfig.DEFAULT;
|
||||
final HttpVersionPolicy versionPolicy = tlsConfig.getHttpVersionPolicy();
|
||||
|
||||
final SSLParameters sslParameters = sslEngine.getSSLParameters();
|
||||
final String[] supportedProtocols = tlsConfig.getSupportedProtocols();
|
||||
if (supportedProtocols != null) {
|
||||
sslParameters.setProtocols(supportedProtocols);
|
||||
} else if (this.supportedProtocols != null) {
|
||||
sslParameters.setProtocols(this.supportedProtocols);
|
||||
} else if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
|
||||
sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
|
||||
}
|
||||
final String[] supportedCipherSuites = tlsConfig.getSupportedCipherSuites();
|
||||
if (supportedCipherSuites != null) {
|
||||
sslParameters.setCipherSuites(supportedCipherSuites);
|
||||
} else if (this.supportedCipherSuites != null) {
|
||||
sslParameters.setCipherSuites(this.supportedCipherSuites);
|
||||
} else if (versionPolicy == HttpVersionPolicy.FORCE_HTTP_2) {
|
||||
sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
|
||||
}
|
||||
|
@ -135,6 +142,7 @@ abstract class AbstractClientTlsStrategy implements TlsStrategy {
|
|||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Enabled protocols: {}", Arrays.asList(sslEngine.getEnabledProtocols()));
|
||||
LOG.debug("Enabled cipher suites:{}", Arrays.asList(sslEngine.getEnabledCipherSuites()));
|
||||
LOG.debug("Starting handshake ({})", handshakeTimeout);
|
||||
}
|
||||
}, (e, sslEngine) -> {
|
||||
verifySession(endpoint.getHostName(), sslEngine.getSession());
|
||||
|
|
|
@ -47,6 +47,7 @@ import javax.net.ssl.SSLHandshakeException;
|
|||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
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;
|
||||
|
@ -60,6 +61,7 @@ import org.apache.hc.core5.ssl.SSLInitializationException;
|
|||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.Asserts;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -200,6 +202,19 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||
final InetSocketAddress remoteAddress,
|
||||
final InetSocketAddress localAddress,
|
||||
final HttpContext context) throws IOException {
|
||||
final Timeout timeout = connectTimeout != null ? Timeout.of(connectTimeout.getDuration(), connectTimeout.getTimeUnit()) : null;
|
||||
return connectSocket(socket, host, remoteAddress, localAddress, timeout, timeout, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket connectSocket(
|
||||
final Socket socket,
|
||||
final HttpHost host,
|
||||
final InetSocketAddress remoteAddress,
|
||||
final InetSocketAddress localAddress,
|
||||
final Timeout connectTimeout,
|
||||
final Object attachment,
|
||||
final HttpContext context) throws IOException {
|
||||
Args.notNull(host, "HTTP host");
|
||||
Args.notNull(remoteAddress, "Remote address");
|
||||
final Socket sock = socket != null ? socket : createSocket(context);
|
||||
|
@ -214,7 +229,7 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||
// only to this library
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||
sock.connect(remoteAddress, connectTimeout != null ? connectTimeout.toMillisecondsIntBound() : 0);
|
||||
sock.connect(remoteAddress, Timeout.defaultsToDisabled(connectTimeout).toMillisecondsIntBound());
|
||||
return null;
|
||||
});
|
||||
} catch (final PrivilegedActionException e) {
|
||||
|
@ -230,12 +245,10 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||
// Setup SSL layering if necessary
|
||||
if (sock instanceof SSLSocket) {
|
||||
final SSLSocket sslsock = (SSLSocket) sock;
|
||||
LOG.debug("Starting handshake");
|
||||
sslsock.startHandshake();
|
||||
verifyHostname(sslsock, host.getHostName());
|
||||
executeHandshake(sslsock, host.getHostName(), attachment);
|
||||
return sock;
|
||||
}
|
||||
return createLayeredSocket(sock, host.getHostName(), remoteAddress.getPort(), context);
|
||||
return createLayeredSocket(sock, host.getHostName(), remoteAddress.getPort(), attachment, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -244,11 +257,27 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||
final String target,
|
||||
final int port,
|
||||
final HttpContext context) throws IOException {
|
||||
return createLayeredSocket(socket, target, port, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createLayeredSocket(
|
||||
final Socket socket,
|
||||
final String target,
|
||||
final int port,
|
||||
final Object attachment,
|
||||
final HttpContext context) throws IOException {
|
||||
final SSLSocket sslsock = (SSLSocket) this.socketFactory.createSocket(
|
||||
socket,
|
||||
target,
|
||||
port,
|
||||
true);
|
||||
executeHandshake(sslsock, target, attachment);
|
||||
return sslsock;
|
||||
}
|
||||
|
||||
private void executeHandshake(final SSLSocket sslsock, final String target, final Object attachment) throws IOException {
|
||||
final TlsConfig tlsConfig = attachment instanceof TlsConfig ? (TlsConfig) attachment : TlsConfig.DEFAULT;
|
||||
if (supportedProtocols != null) {
|
||||
sslsock.setEnabledProtocols(supportedProtocols);
|
||||
} else {
|
||||
|
@ -259,17 +288,20 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||
} else {
|
||||
sslsock.setEnabledCipherSuites(TlsCiphers.excludeWeak(sslsock.getEnabledCipherSuites()));
|
||||
}
|
||||
final Timeout handshakeTimeout = tlsConfig.getHandshakeTimeout();
|
||||
if (handshakeTimeout != null) {
|
||||
sslsock.setSoTimeout(handshakeTimeout.toMillisecondsIntBound());
|
||||
}
|
||||
|
||||
prepareSocket(sslsock);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Enabled protocols: {}", (Object) sslsock.getEnabledProtocols());
|
||||
LOG.debug("Enabled cipher suites: {}", (Object) sslsock.getEnabledCipherSuites());
|
||||
LOG.debug("Starting handshake ({})", handshakeTimeout);
|
||||
}
|
||||
|
||||
prepareSocket(sslsock);
|
||||
LOG.debug("Starting handshake");
|
||||
sslsock.startHandshake();
|
||||
verifyHostname(sslsock, target);
|
||||
return sslsock;
|
||||
}
|
||||
|
||||
private void verifyHostname(final SSLSocket sslsock, final String hostname) throws IOException {
|
||||
|
|
|
@ -52,11 +52,9 @@ import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
|||
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http.support.BasicRequestBuilder;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates a full-duplex, streaming HTTP/1.1 message exchange.
|
||||
|
@ -65,15 +63,10 @@ public class AsyncClientFullDuplexExchange {
|
|||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.NEGOTIATE,
|
||||
H2Config.DEFAULT,
|
||||
Http1Config.DEFAULT,
|
||||
ioReactorConfig);
|
||||
IOReactorConfig.DEFAULT);
|
||||
|
||||
client.start();
|
||||
|
||||
|
|
|
@ -32,13 +32,16 @@ import java.util.List;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.config.Http1Config;
|
||||
import org.apache.hc.core5.http.message.BasicHttpRequest;
|
||||
import org.apache.hc.core5.http.message.StatusLine;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
||||
|
@ -55,7 +58,6 @@ import org.apache.hc.core5.http2.HttpVersionPolicy;
|
|||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates a full-duplex, streaming HTTP/2 message exchange.
|
||||
|
@ -64,12 +66,15 @@ public class AsyncClientH2FullDuplexExchange {
|
|||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, null, ioReactorConfig);
|
||||
H2Config.DEFAULT,
|
||||
Http1Config.DEFAULT,
|
||||
IOReactorConfig.DEFAULT,
|
||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
client.start();
|
||||
|
||||
|
|
|
@ -35,17 +35,19 @@ import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
|||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
|
||||
import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.Http1Config;
|
||||
import org.apache.hc.core5.http.message.StatusLine;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates concurrent (multiplexed) execution of multiple
|
||||
|
@ -55,12 +57,15 @@ public class AsyncClientH2Multiplexing {
|
|||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, null, ioReactorConfig);
|
||||
H2Config.DEFAULT,
|
||||
Http1Config.DEFAULT,
|
||||
IOReactorConfig.DEFAULT,
|
||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
client.start();
|
||||
|
||||
|
|
|
@ -33,8 +33,10 @@ import java.util.concurrent.Future;
|
|||
|
||||
import org.apache.hc.client5.http.async.methods.AbstractBinPushConsumer;
|
||||
import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
|
@ -46,8 +48,6 @@ import org.apache.hc.core5.http.support.BasicRequestBuilder;
|
|||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates handling of HTTP/2 message exchanges pushed by the server.
|
||||
|
@ -56,18 +56,15 @@ public class AsyncClientH2ServerPush {
|
|||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final H2Config h2Config = H2Config.custom()
|
||||
.setPushEnabled(true)
|
||||
.build();
|
||||
|
||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||
.setIOReactorConfig(ioReactorConfig)
|
||||
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
|
||||
.setH2Config(h2Config)
|
||||
.setH2Config(H2Config.custom()
|
||||
.setPushEnabled(true)
|
||||
.build())
|
||||
.setConnectionManager(PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
|
||||
.build())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
client.start();
|
||||
|
|
|
@ -35,17 +35,19 @@ import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
|||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
|
||||
import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
|
||||
import org.apache.hc.client5.http.config.TlsConfig;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.Http1Config;
|
||||
import org.apache.hc.core5.http.message.StatusLine;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates pipelined execution of multiple HTTP/1.1 message exchanges.
|
||||
|
@ -54,12 +56,15 @@ public class AsyncClientHttp1Pipelining {
|
|||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.FORCE_HTTP_1, null, Http1Config.DEFAULT, ioReactorConfig);
|
||||
H2Config.DEFAULT,
|
||||
Http1Config.DEFAULT,
|
||||
IOReactorConfig.DEFAULT,
|
||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setDefaultTlsConfig(TlsConfig.custom()
|
||||
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
client.start();
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.apache.hc.core5.concurrent.FutureCallback;
|
|||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.message.StatusLine;
|
||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
|
||||
/**
|
||||
|
@ -74,7 +73,6 @@ public class AsyncClientTlsAlpn {
|
|||
.setTlsStrategy(tlsStrategy)
|
||||
.build();
|
||||
try (final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
|
||||
.setConnectionManager(cm)
|
||||
.build()) {
|
||||
|
||||
|
|
|
@ -40,13 +40,11 @@ import org.apache.hc.core5.http.HttpResponse;
|
|||
import org.apache.hc.core5.http.Message;
|
||||
import org.apache.hc.core5.http.config.Http1Config;
|
||||
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.reactive.ReactiveEntityProducer;
|
||||
import org.apache.hc.core5.reactive.ReactiveResponseConsumer;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import io.reactivex.Flowable;
|
||||
|
@ -59,15 +57,10 @@ public class ReactiveClientFullDuplexExchange {
|
|||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(
|
||||
HttpVersionPolicy.NEGOTIATE,
|
||||
H2Config.DEFAULT,
|
||||
Http1Config.DEFAULT,
|
||||
ioReactorConfig);
|
||||
IOReactorConfig.DEFAULT);
|
||||
|
||||
client.start();
|
||||
|
||||
|
|
|
@ -30,10 +30,13 @@ package org.apache.hc.client5.http.impl.io;
|
|||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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.ConnectionEndpoint;
|
||||
import org.apache.hc.client5.http.io.LeaseRequest;
|
||||
import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
|
||||
|
@ -361,26 +364,55 @@ public class TestBasicHttpClientConnectionManager {
|
|||
|
||||
mgr.setSocketConfig(sconfig);
|
||||
|
||||
final ConnectionConfig connectionConfig = ConnectionConfig.custom()
|
||||
.setConnectTimeout(234, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setConnectionConfig(connectionConfig);
|
||||
final TlsConfig tlsConfig = TlsConfig.custom()
|
||||
.setHandshakeTimeout(345, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setTlsConfig(tlsConfig);
|
||||
|
||||
Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[] {remote});
|
||||
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443);
|
||||
Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(plainSocketFactory);
|
||||
Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket);
|
||||
Mockito.when(plainSocketFactory.connectSocket(
|
||||
Mockito.any(),
|
||||
Mockito.eq(socket),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenReturn(socket);
|
||||
|
||||
mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
|
||||
mgr.connect(endpoint1, null, context);
|
||||
|
||||
Mockito.verify(dnsResolver, Mockito.times(1)).resolve("somehost");
|
||||
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).createSocket(context);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(TimeValue.ofMilliseconds(123), socket, target,
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(
|
||||
socket,
|
||||
target,
|
||||
new InetSocketAddress(remote, 8443),
|
||||
new InetSocketAddress(local, 0), context);
|
||||
new InetSocketAddress(local, 0),
|
||||
Timeout.ofMilliseconds(234),
|
||||
tlsConfig,
|
||||
context);
|
||||
|
||||
mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
|
||||
|
||||
Mockito.verify(dnsResolver, Mockito.times(2)).resolve("somehost");
|
||||
Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(2)).createSocket(context);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(
|
||||
socket,
|
||||
target,
|
||||
new InetSocketAddress(remote, 8443),
|
||||
new InetSocketAddress(local, 0),
|
||||
Timeout.ofMilliseconds(123),
|
||||
tlsConfig,
|
||||
context);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -402,6 +434,15 @@ public class TestBasicHttpClientConnectionManager {
|
|||
|
||||
mgr.setSocketConfig(sconfig);
|
||||
|
||||
final ConnectionConfig connectionConfig = ConnectionConfig.custom()
|
||||
.setConnectTimeout(234, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setConnectionConfig(connectionConfig);
|
||||
final TlsConfig tlsConfig = TlsConfig.custom()
|
||||
.setHandshakeTimeout(345, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setTlsConfig(tlsConfig);
|
||||
|
||||
Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote});
|
||||
Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080);
|
||||
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443);
|
||||
|
@ -409,21 +450,27 @@ public class TestBasicHttpClientConnectionManager {
|
|||
Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslSocketFactory);
|
||||
Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket);
|
||||
Mockito.when(plainSocketFactory.connectSocket(
|
||||
Mockito.any(),
|
||||
Mockito.eq(socket),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenReturn(socket);
|
||||
|
||||
mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
|
||||
mgr.connect(endpoint1, null, context);
|
||||
|
||||
Mockito.verify(dnsResolver, Mockito.times(1)).resolve("someproxy");
|
||||
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(proxy);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).createSocket(context);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(TimeValue.ofMilliseconds(123), socket, proxy,
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(
|
||||
socket,
|
||||
proxy,
|
||||
new InetSocketAddress(remote, 8080),
|
||||
new InetSocketAddress(local, 0), context);
|
||||
new InetSocketAddress(local, 0),
|
||||
Timeout.ofMilliseconds(234),
|
||||
tlsConfig,
|
||||
context);
|
||||
|
||||
Mockito.when(conn.getSocket()).thenReturn(socket);
|
||||
|
||||
|
@ -431,7 +478,7 @@ public class TestBasicHttpClientConnectionManager {
|
|||
|
||||
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target);
|
||||
Mockito.verify(sslSocketFactory, Mockito.times(1)).createLayeredSocket(
|
||||
socket, "somehost", 8443, context);
|
||||
socket, "somehost", 8443, tlsConfig, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.apache.hc.client5.http.DnsResolver;
|
|||
import org.apache.hc.client5.http.HttpHostConnectException;
|
||||
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.ManagedHttpClientConnection;
|
||||
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
|
||||
|
@ -48,6 +49,7 @@ import org.apache.hc.core5.http.io.SocketConfig;
|
|||
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -96,6 +98,7 @@ public class TestHttpClientConnectionOperator {
|
|||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenReturn(socket);
|
||||
|
||||
final SocketConfig socketConfig = SocketConfig.custom()
|
||||
|
@ -105,8 +108,11 @@ public class TestHttpClientConnectionOperator {
|
|||
.setTcpNoDelay(true)
|
||||
.setSoLinger(50, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
final TlsConfig tlsConfig = TlsConfig.custom()
|
||||
.build();
|
||||
final InetSocketAddress localAddress = new InetSocketAddress(local, 0);
|
||||
connectionOperator.connect(conn, host, localAddress, TimeValue.ofMilliseconds(1000), socketConfig, context);
|
||||
connectionOperator.connect(conn, host, localAddress,
|
||||
Timeout.ofMilliseconds(123), socketConfig, tlsConfig, context);
|
||||
|
||||
Mockito.verify(socket).setKeepAlive(true);
|
||||
Mockito.verify(socket).setReuseAddress(true);
|
||||
|
@ -115,11 +121,12 @@ public class TestHttpClientConnectionOperator {
|
|||
Mockito.verify(socket).setTcpNoDelay(true);
|
||||
|
||||
Mockito.verify(plainSocketFactory).connectSocket(
|
||||
TimeValue.ofMilliseconds(1000),
|
||||
socket,
|
||||
host,
|
||||
new InetSocketAddress(ip1, 80),
|
||||
localAddress,
|
||||
Timeout.ofMilliseconds(123),
|
||||
tlsConfig,
|
||||
context);
|
||||
Mockito.verify(conn, Mockito.times(2)).bind(socket);
|
||||
}
|
||||
|
@ -141,6 +148,7 @@ public class TestHttpClientConnectionOperator {
|
|||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenThrow(new SocketTimeoutException());
|
||||
|
||||
Assert.assertThrows(ConnectTimeoutException.class, () ->
|
||||
|
@ -165,6 +173,7 @@ public class TestHttpClientConnectionOperator {
|
|||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenThrow(new ConnectException());
|
||||
|
||||
Assert.assertThrows(HttpHostConnectException.class, () ->
|
||||
|
@ -185,29 +194,35 @@ public class TestHttpClientConnectionOperator {
|
|||
Mockito.when(schemePortResolver.resolve(host)).thenReturn(80);
|
||||
Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket);
|
||||
Mockito.when(plainSocketFactory.connectSocket(
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.eq(new InetSocketAddress(ip1, 80)),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenThrow(new ConnectException());
|
||||
Mockito.when(plainSocketFactory.connectSocket(
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.eq(new InetSocketAddress(ip2, 80)),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenReturn(socket);
|
||||
|
||||
final InetSocketAddress localAddress = new InetSocketAddress(local, 0);
|
||||
connectionOperator.connect(conn, host, localAddress, TimeValue.ofMilliseconds(1000), SocketConfig.DEFAULT, context);
|
||||
final TlsConfig tlsConfig = TlsConfig.custom()
|
||||
.build();
|
||||
connectionOperator.connect(conn, host, localAddress,
|
||||
Timeout.ofMilliseconds(123), SocketConfig.DEFAULT, tlsConfig, context);
|
||||
|
||||
Mockito.verify(plainSocketFactory).connectSocket(
|
||||
TimeValue.ofMilliseconds(1000),
|
||||
socket,
|
||||
host,
|
||||
new InetSocketAddress(ip2, 80),
|
||||
localAddress,
|
||||
Timeout.ofMilliseconds(123),
|
||||
tlsConfig,
|
||||
context);
|
||||
Mockito.verify(conn, Mockito.times(3)).bind(socket);
|
||||
}
|
||||
|
@ -228,17 +243,22 @@ public class TestHttpClientConnectionOperator {
|
|||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenReturn(socket);
|
||||
|
||||
final InetSocketAddress localAddress = new InetSocketAddress(local, 0);
|
||||
connectionOperator.connect(conn, host, localAddress, TimeValue.ofMilliseconds(1000), SocketConfig.DEFAULT, context);
|
||||
final TlsConfig tlsConfig = TlsConfig.custom()
|
||||
.build();
|
||||
connectionOperator.connect(conn, host, localAddress,
|
||||
Timeout.ofMilliseconds(123), SocketConfig.DEFAULT, tlsConfig, context);
|
||||
|
||||
Mockito.verify(plainSocketFactory).connectSocket(
|
||||
TimeValue.ofMilliseconds(1000),
|
||||
socket,
|
||||
host,
|
||||
new InetSocketAddress(ip, 80),
|
||||
localAddress,
|
||||
Timeout.ofMilliseconds(123),
|
||||
tlsConfig,
|
||||
context);
|
||||
Mockito.verify(dnsResolver, Mockito.never()).resolve(Mockito.anyString());
|
||||
Mockito.verify(conn, Mockito.times(2)).bind(socket);
|
||||
|
@ -258,9 +278,10 @@ public class TestHttpClientConnectionOperator {
|
|||
Mockito.any(),
|
||||
Mockito.eq("somehost"),
|
||||
Mockito.eq(443),
|
||||
Mockito.eq(Timeout.ofMilliseconds(345)),
|
||||
Mockito.any())).thenReturn(socket);
|
||||
|
||||
connectionOperator.upgrade(conn, host, context);
|
||||
connectionOperator.upgrade(conn, host, Timeout.ofMilliseconds(345), context);
|
||||
|
||||
Mockito.verify(conn).bind(socket);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ import java.util.concurrent.TimeoutException;
|
|||
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.ConnectionEndpoint;
|
||||
import org.apache.hc.client5.http.io.LeaseRequest;
|
||||
import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
|
||||
|
@ -247,26 +249,55 @@ public class TestPoolingHttpClientConnectionManager {
|
|||
|
||||
mgr.setDefaultSocketConfig(sconfig);
|
||||
|
||||
final ConnectionConfig connectionConfig = ConnectionConfig.custom()
|
||||
.setConnectTimeout(234, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setDefaultConnectionConfig(connectionConfig);
|
||||
final TlsConfig tlsConfig = TlsConfig.custom()
|
||||
.setHandshakeTimeout(345, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setDefaultTlsConfig(tlsConfig);
|
||||
|
||||
Mockito.when(dnsResolver.resolve("somehost")).thenReturn(new InetAddress[]{remote});
|
||||
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443);
|
||||
Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(plainSocketFactory);
|
||||
Mockito.when(plainSocketFactory.createSocket(Mockito.any())).thenReturn(socket);
|
||||
Mockito.when(plainSocketFactory.connectSocket(
|
||||
Mockito.any(),
|
||||
Mockito.eq(socket),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenReturn(socket);
|
||||
|
||||
mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
|
||||
mgr.connect(endpoint1, null, context);
|
||||
|
||||
Mockito.verify(dnsResolver, Mockito.times(1)).resolve("somehost");
|
||||
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).createSocket(context);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(TimeValue.ofMilliseconds(123), socket, target,
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(
|
||||
socket,
|
||||
target,
|
||||
new InetSocketAddress(remote, 8443),
|
||||
new InetSocketAddress(local, 0), context);
|
||||
new InetSocketAddress(local, 0),
|
||||
Timeout.ofMilliseconds(234),
|
||||
tlsConfig,
|
||||
context);
|
||||
|
||||
mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
|
||||
|
||||
Mockito.verify(dnsResolver, Mockito.times(2)).resolve("somehost");
|
||||
Mockito.verify(schemePortResolver, Mockito.times(2)).resolve(target);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(2)).createSocket(context);
|
||||
Mockito.verify(plainSocketFactory, Mockito.times(1)).connectSocket(
|
||||
socket,
|
||||
target,
|
||||
new InetSocketAddress(remote, 8443),
|
||||
new InetSocketAddress(local, 0),
|
||||
Timeout.ofMilliseconds(123),
|
||||
tlsConfig,
|
||||
context);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -301,6 +332,15 @@ public class TestPoolingHttpClientConnectionManager {
|
|||
|
||||
mgr.setDefaultSocketConfig(sconfig);
|
||||
|
||||
final ConnectionConfig connectionConfig = ConnectionConfig.custom()
|
||||
.setConnectTimeout(234, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setDefaultConnectionConfig(connectionConfig);
|
||||
final TlsConfig tlsConfig = TlsConfig.custom()
|
||||
.setHandshakeTimeout(345, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
mgr.setDefaultTlsConfig(tlsConfig);
|
||||
|
||||
Mockito.when(dnsResolver.resolve("someproxy")).thenReturn(new InetAddress[] {remote});
|
||||
Mockito.when(schemePortResolver.resolve(proxy)).thenReturn(8080);
|
||||
Mockito.when(schemePortResolver.resolve(target)).thenReturn(8443);
|
||||
|
@ -308,21 +348,27 @@ public class TestPoolingHttpClientConnectionManager {
|
|||
Mockito.when(socketFactoryRegistry.lookup("https")).thenReturn(sslsf);
|
||||
Mockito.when(plainsf.createSocket(Mockito.any())).thenReturn(mockSock);
|
||||
Mockito.when(plainsf.connectSocket(
|
||||
Mockito.any(),
|
||||
Mockito.eq(mockSock),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any(),
|
||||
Mockito.any())).thenReturn(mockSock);
|
||||
|
||||
mgr.connect(endpoint1, TimeValue.ofMilliseconds(123), context);
|
||||
mgr.connect(endpoint1, null, context);
|
||||
|
||||
Mockito.verify(dnsResolver, Mockito.times(1)).resolve("someproxy");
|
||||
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(proxy);
|
||||
Mockito.verify(plainsf, Mockito.times(1)).createSocket(context);
|
||||
Mockito.verify(plainsf, Mockito.times(1)).connectSocket(TimeValue.ofMilliseconds(123), mockSock, proxy,
|
||||
Mockito.verify(plainsf, Mockito.times(1)).connectSocket(
|
||||
mockSock,
|
||||
proxy,
|
||||
new InetSocketAddress(remote, 8080),
|
||||
new InetSocketAddress(local, 0), context);
|
||||
new InetSocketAddress(local, 0),
|
||||
Timeout.ofMilliseconds(234),
|
||||
tlsConfig,
|
||||
context);
|
||||
|
||||
Mockito.when(conn.isOpen()).thenReturn(true);
|
||||
Mockito.when(conn.getSocket()).thenReturn(mockSock);
|
||||
|
@ -331,7 +377,7 @@ public class TestPoolingHttpClientConnectionManager {
|
|||
|
||||
Mockito.verify(schemePortResolver, Mockito.times(1)).resolve(target);
|
||||
Mockito.verify(sslsf, Mockito.times(1)).createLayeredSocket(
|
||||
mockSock, "somehost", 8443, context);
|
||||
mockSock, "somehost", 8443, tlsConfig, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue