Updated connection and TLS configuration examples

This commit is contained in:
Oleg Kalnichevski 2021-10-23 19:48:00 +02:00
parent a02455acb3
commit ffc8cd7585
5 changed files with 270 additions and 2 deletions

View File

@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.http2.HttpVersionPolicy; import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.util.Timeout; import org.apache.hc.core5.util.Timeout;
@ -166,6 +167,23 @@ public class TlsConfig implements Cloneable {
return this; return this;
} }
/**
* Determines supported TLS protocols.
* <p>
* Default: {@code null} (undefined)
* </p>
*/
public Builder setSupportedProtocols(final TLS... supportedProtocols) {
this.supportedProtocols = new String[supportedProtocols.length];
for (int i = 0; i < supportedProtocols.length; i++) {
final TLS protocol = supportedProtocols[i];
if (protocol != null) {
this.supportedProtocols[i] = protocol.id;
}
}
return this;
}
/** /**
* Determines supported cipher suites. * Determines supported cipher suites.
* <p> * <p>

View File

@ -0,0 +1,133 @@
/*
* ====================================================================
* 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.examples;
import java.util.concurrent.Future;
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.async.methods.SimpleRequestProducer;
import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
import org.apache.hc.client5.http.config.ConnectionConfig;
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.PoolingAsyncClientConnectionManager;
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.URIScheme;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.io.CloseMode;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
/**
* This example demonstrates how to use connection configuration on a per-route or a per-host
* basis.
*/
public class AsyncClientConnectionConfig {
public static void main(final String[] args) throws Exception {
final PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create()
.setConnectionConfigResolver(route -> {
// Use different settings for all secure (TLS) connections
final HttpHost targetHost = route.getTargetHost();
if (route.isSecure()) {
return ConnectionConfig.custom()
.setConnectTimeout(Timeout.ofMinutes(2))
.setSocketTimeout(Timeout.ofMinutes(2))
.setValidateAfterInactivity(TimeValue.ofMinutes(1))
.setTimeToLive(TimeValue.ofHours(1))
.build();
} else {
return ConnectionConfig.custom()
.setConnectTimeout(Timeout.ofMinutes(1))
.setSocketTimeout(Timeout.ofMinutes(1))
.setValidateAfterInactivity(TimeValue.ofSeconds(15))
.setTimeToLive(TimeValue.ofMinutes(15))
.build();
}
})
.setTlsConfigResolver(host -> {
// Use different settings for specific hosts
if (host.getSchemeName().equalsIgnoreCase("httpbin.org")) {
return TlsConfig.custom()
.setSupportedProtocols(TLS.V_1_3)
.setHandshakeTimeout(Timeout.ofSeconds(10))
.build();
} else {
return TlsConfig.DEFAULT;
}
})
.build();
try (final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setConnectionManager(cm)
.build()) {
client.start();
for (final URIScheme uriScheme : URIScheme.values()) {
final SimpleHttpRequest request = SimpleRequestBuilder.get()
.setHttpHost(new HttpHost(uriScheme.id, "httpbin.org"))
.setPath("/headers")
.build();
System.out.println("Executing request " + request);
final Future<SimpleHttpResponse> future = client.execute(
SimpleRequestProducer.create(request),
SimpleResponseConsumer.create(),
new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(final SimpleHttpResponse response) {
System.out.println(request + "->" + new StatusLine(response));
System.out.println(response.getBody());
}
@Override
public void failed(final Exception ex) {
System.out.println(request + "->" + ex);
}
@Override
public void cancelled() {
System.out.println(request + " cancelled");
}
});
future.get();
}
System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);
}
}
}

View File

@ -44,6 +44,7 @@ import org.apache.hc.client5.http.auth.StandardAuthScheme;
import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig; 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.BasicCookieStore;
import org.apache.hc.client5.http.cookie.CookieStore; import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.cookie.StandardCookieSpec; import org.apache.hc.client5.http.cookie.StandardCookieSpec;
@ -80,6 +81,7 @@ import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.message.BasicHeader; import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.message.BasicLineParser; import org.apache.hc.core5.http.message.BasicLineParser;
import org.apache.hc.core5.http.message.LineParser; import org.apache.hc.core5.http.message.LineParser;
import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.pool.PoolConcurrencyPolicy; import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
import org.apache.hc.core5.pool.PoolReusePolicy; import org.apache.hc.core5.pool.PoolReusePolicy;
import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.SSLContexts;
@ -183,6 +185,13 @@ public class ClientConfiguration {
.setConnectTimeout(Timeout.ofSeconds(30)) .setConnectTimeout(Timeout.ofSeconds(30))
.setSocketTimeout(Timeout.ofSeconds(30)) .setSocketTimeout(Timeout.ofSeconds(30))
.setValidateAfterInactivity(TimeValue.ofSeconds(10)) .setValidateAfterInactivity(TimeValue.ofSeconds(10))
.setTimeToLive(TimeValue.ofHours(1))
.build());
// Use TLS v1.3 only
connManager.setDefaultTlsConfig(TlsConfig.custom()
.setHandshakeTimeout(Timeout.ofSeconds(30))
.setSupportedProtocols(TLS.V_1_3)
.build()); .build());
// Configure total max or per route limits for persistent connections // Configure total max or per route limits for persistent connections

View File

@ -0,0 +1,103 @@
/*
* ====================================================================
* 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.examples;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.TlsConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
/**
* This example demonstrates how to use connection configuration on a per-route or a per-host
* basis.
*/
public class ClientConnectionConfig {
public final static void main(final String[] args) throws Exception {
final PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
.setConnectionConfigResolver(route -> {
// Use different settings for all secure (TLS) connections
final HttpHost targetHost = route.getTargetHost();
if (route.isSecure()) {
return ConnectionConfig.custom()
.setConnectTimeout(Timeout.ofMinutes(2))
.setSocketTimeout(Timeout.ofMinutes(2))
.setValidateAfterInactivity(TimeValue.ofMinutes(1))
.setTimeToLive(TimeValue.ofHours(1))
.build();
} else {
return ConnectionConfig.custom()
.setConnectTimeout(Timeout.ofMinutes(1))
.setSocketTimeout(Timeout.ofMinutes(1))
.setValidateAfterInactivity(TimeValue.ofSeconds(15))
.setTimeToLive(TimeValue.ofMinutes(15))
.build();
}
})
.setTlsConfigResolver(host -> {
// Use different settings for specific hosts
if (host.getSchemeName().equalsIgnoreCase("httpbin.org")) {
return TlsConfig.custom()
.setSupportedProtocols(TLS.V_1_3)
.setHandshakeTimeout(Timeout.ofSeconds(10))
.build();
} else {
return TlsConfig.DEFAULT;
}
})
.build();
try (CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.build()) {
for (final URIScheme uriScheme : URIScheme.values()) {
final ClassicHttpRequest request = ClassicRequestBuilder.get()
.setHttpHost(new HttpHost(uriScheme.id, "httpbin.org"))
.setPath("/headers")
.build();
System.out.println("Executing request " + request);
try (CloseableHttpResponse response = httpclient.execute(request)) {
System.out.println(request + "->" + new StatusLine(response));
EntityUtils.consume(response.getEntity());
}
}
}
}
}

View File

@ -32,6 +32,7 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.TlsConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.classic.HttpClients;
@ -43,6 +44,7 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.ssl.TLS; import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.util.Timeout;
/** /**
* This example demonstrates how to create secure connections with a custom SSL * This example demonstrates how to create secure connections with a custom SSL
@ -58,13 +60,16 @@ public class ClientCustomSSL {
return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName()); return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
}) })
.build(); .build();
// Allow TLSv1.2 protocol only
final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create() final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
.setSslContext(sslcontext) .setSslContext(sslcontext)
.setTlsVersions(TLS.V_1_2)
.build(); .build();
// Allow TLSv1.3 protocol only
final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(sslSocketFactory) .setSSLSocketFactory(sslSocketFactory)
.setDefaultTlsConfig(TlsConfig.custom()
.setHandshakeTimeout(Timeout.ofSeconds(30))
.setSupportedProtocols(TLS.V_1_3)
.build())
.build(); .build();
try (CloseableHttpClient httpclient = HttpClients.custom() try (CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm) .setConnectionManager(cm)