You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2024/10/20 13:31:29 UTC
(httpcomponents-core) branch master updated (98f3252e3 -> 1ed6e1793)
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
from 98f3252e3 Add HTTP/1.1 TE header interceptor and strict client/server option (#498)
new b525b9402 Improved integration test resource wiring and configuration
new 1ed6e1793 Redesign of compatibility integration tests for greater flexibility and extensibility; added classic i/o and TLS compatibility tests
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.gitignore | 3 +
.../apache/hc/core5/testing/SSLTestContexts.java | 38 ++-
.../testing/classic/ClassicAuthenticationTest.java | 9 +-
.../classic/ClassicHttp1CoreTransportTest.java | 9 +-
.../ClassicHttp1SocksProxyCoreTransportTest.java | 9 +-
.../classic/ClassicServerBootstrapFilterTest.java | 9 +-
...gResponseOutOfOrderStrategyIntegrationTest.java | 10 +-
.../testing/compatibility/ApacheHttpDCompatIT.java | 128 ++++++++
.../testing/compatibility/ContainerImages.java | 109 +++++--
.../NginxCompatIT.java => HttpBinCompatIT.java} | 43 ++-
.../core5/testing/compatibility/NginxCompatIT.java | 128 ++++++++
.../TLSTestContexts.java} | 35 +-
.../classic/ClassicHttpCompatTest.java | 154 +++++++++
.../classic/HttpBinClassicCompatTest.java | 121 +++++++
.../compatibility/http2/ApacheHttpDCompatIT.java | 59 ----
.../nio/AsyncHttp1CompatTest.java} | 51 ++-
.../AsyncHttp2CompatTest.java} | 115 ++-----
.../AsyncHttpCompatTest.java} | 121 ++-----
.../HttpBinAsyncCompatTest.java} | 71 ++--
.../testing/extension/SocksProxyResource.java | 20 +-
.../extension/classic/HttpRequesterResource.java | 30 +-
.../extension/classic/HttpServerResource.java | 35 +-
.../extension/nio/H2AsyncRequesterResource.java | 39 +--
.../extension/nio/H2AsyncServerResource.java | 39 +--
.../nio/H2MultiplexingRequesterResource.java | 32 +-
.../extension/nio/HttpAsyncRequesterResource.java | 32 +-
.../extension/nio/HttpAsyncServerResource.java | 38 +--
.../nio/AsyncServerBootstrapFilterTest.java | 87 ++---
.../apache/hc/core5/testing/nio/H2AlpnTest.java | 7 +-
.../hc/core5/testing/nio/H2ConnPoolTest.java | 11 +-
.../nio/H2CoreTransportMultiplexingTest.java | 11 +-
.../hc/core5/testing/nio/H2CoreTransportTest.java | 11 +-
.../hc/core5/testing/nio/H2IntegrationTest.java | 1 -
.../testing/nio/H2ProtocolNegotiationTest.java | 11 +-
.../testing/nio/H2ServerBootstrapFiltersTest.java | 90 +++---
.../testing/nio/H2SocksProxyCoreTransportTest.java | 11 +-
.../core5/testing/nio/Http1AuthenticationTest.java | 11 +-
.../core5/testing/nio/Http1CoreTransportTest.java | 11 +-
.../hc/core5/testing/nio/Http1IntegrationTest.java | 2 -
.../nio/Http1SocksProxyCoreTransportTest.java | 11 +-
.../core5/testing/nio/HttpCoreTransportTest.java | 2 +-
.../hc/core5/testing/nio/TLSUpgradeTest.java | 11 +-
.../core5/testing/reactive/ReactiveClientTest.java | 11 +-
.../src/test/resources/docker/BUILDING.txt | 43 +++
.../{httpd-vhosts.conf => httpd-default.conf} | 20 +-
.../{ngnix/default.conf => httpd/httpd-h2c.conf} | 32 +-
.../src/test/resources/docker/httpd/httpd-ssl.conf | 53 +++
.../resources/docker/{ngnix => nginx}/default.conf | 8 +-
.../docker/{ngnix/default.conf => nginx/h2c.conf} | 2 +-
.../docker/{ngnix/default.conf => nginx/ssl.conf} | 6 +-
.../src/test/resources/docker/server-cert.pem | 83 +++++
.../src/test/resources/docker/server-key.pem | 28 ++
httpcore5-testing/src/test/resources/test-ca.jks | Bin 0 -> 1037 bytes
test-CA/ca-cert.pem | 23 ++
test-CA/ca-key.pem | 30 ++
test-CA/openssl.cnf | 357 +++++++++++++++++++++
56 files changed, 1755 insertions(+), 716 deletions(-)
create mode 100644 httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ApacheHttpDCompatIT.java
rename httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/{http2/NginxCompatIT.java => HttpBinCompatIT.java} (57%)
create mode 100644 httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/NginxCompatIT.java
copy httpcore5-testing/src/test/java/org/apache/hc/core5/testing/{SSLTestContexts.java => compatibility/TLSTestContexts.java} (59%)
create mode 100644 httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/ClassicHttpCompatTest.java
create mode 100644 httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/HttpBinClassicCompatTest.java
delete mode 100644 httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/ApacheHttpDCompatIT.java
copy httpcore5-testing/src/test/java/org/apache/hc/core5/testing/{nio/H2CoreTransportTest.java => compatibility/nio/AsyncHttp1CompatTest.java} (50%)
copy httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/{http2/AbstractHttp2CompatIT.java => nio/AsyncHttp2CompatTest.java} (57%)
rename httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/{http2/AbstractHttp2CompatIT.java => nio/AsyncHttpCompatTest.java} (56%)
rename httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/{http1/HttpBinCompatIT.java => nio/HttpBinAsyncCompatTest.java} (78%)
create mode 100644 httpcore5-testing/src/test/resources/docker/BUILDING.txt
rename httpcore5-testing/src/test/resources/docker/httpd/{httpd-vhosts.conf => httpd-default.conf} (79%)
copy httpcore5-testing/src/test/resources/docker/{ngnix/default.conf => httpd/httpd-h2c.conf} (67%)
create mode 100644 httpcore5-testing/src/test/resources/docker/httpd/httpd-ssl.conf
copy httpcore5-testing/src/test/resources/docker/{ngnix => nginx}/default.conf (85%)
copy httpcore5-testing/src/test/resources/docker/{ngnix/default.conf => nginx/h2c.conf} (97%)
rename httpcore5-testing/src/test/resources/docker/{ngnix/default.conf => nginx/ssl.conf} (83%)
create mode 100644 httpcore5-testing/src/test/resources/docker/server-cert.pem
create mode 100644 httpcore5-testing/src/test/resources/docker/server-key.pem
create mode 100644 httpcore5-testing/src/test/resources/test-ca.jks
create mode 100644 test-CA/ca-cert.pem
create mode 100644 test-CA/ca-key.pem
create mode 100644 test-CA/openssl.cnf
(httpcomponents-core) 01/02: Improved integration test resource wiring and configuration
Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
commit b525b9402d61fb7b70dfe8fb5075a830e1ceac85
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Oct 15 12:17:57 2024 +0200
Improved integration test resource wiring and configuration
---
.../apache/hc/core5/testing/SSLTestContexts.java | 38 ++++++---
.../testing/classic/ClassicAuthenticationTest.java | 9 ++-
.../classic/ClassicHttp1CoreTransportTest.java | 9 ++-
.../ClassicHttp1SocksProxyCoreTransportTest.java | 9 ++-
.../classic/ClassicServerBootstrapFilterTest.java | 9 ++-
...gResponseOutOfOrderStrategyIntegrationTest.java | 10 ++-
.../testing/extension/SocksProxyResource.java | 20 ++---
.../extension/classic/HttpRequesterResource.java | 30 +++-----
.../extension/classic/HttpServerResource.java | 35 ++++-----
.../extension/nio/H2AsyncRequesterResource.java | 39 ++++------
.../extension/nio/H2AsyncServerResource.java | 39 ++++------
.../nio/H2MultiplexingRequesterResource.java | 32 ++++----
.../extension/nio/HttpAsyncRequesterResource.java | 32 ++++----
.../extension/nio/HttpAsyncServerResource.java | 38 ++++-----
.../nio/AsyncServerBootstrapFilterTest.java | 87 ++++++++++++---------
.../apache/hc/core5/testing/nio/H2AlpnTest.java | 7 +-
.../hc/core5/testing/nio/H2ConnPoolTest.java | 11 ++-
.../nio/H2CoreTransportMultiplexingTest.java | 11 ++-
.../hc/core5/testing/nio/H2CoreTransportTest.java | 11 ++-
.../hc/core5/testing/nio/H2IntegrationTest.java | 1 -
.../testing/nio/H2ProtocolNegotiationTest.java | 11 ++-
.../testing/nio/H2ServerBootstrapFiltersTest.java | 90 ++++++++++++----------
.../testing/nio/H2SocksProxyCoreTransportTest.java | 11 ++-
.../core5/testing/nio/Http1AuthenticationTest.java | 11 ++-
.../core5/testing/nio/Http1CoreTransportTest.java | 11 ++-
.../hc/core5/testing/nio/Http1IntegrationTest.java | 2 -
.../nio/Http1SocksProxyCoreTransportTest.java | 11 ++-
.../core5/testing/nio/HttpCoreTransportTest.java | 2 +-
.../hc/core5/testing/nio/TLSUpgradeTest.java | 11 ++-
.../core5/testing/reactive/ReactiveClientTest.java | 11 ++-
30 files changed, 366 insertions(+), 282 deletions(-)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/SSLTestContexts.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/SSLTestContexts.java
index 52e164977..9cbec8048 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/SSLTestContexts.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/SSLTestContexts.java
@@ -27,7 +27,13 @@
package org.apache.hc.core5.testing;
+import java.io.IOException;
import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
import javax.net.ssl.SSLContext;
@@ -35,23 +41,33 @@ import org.apache.hc.core5.ssl.SSLContextBuilder;
public final class SSLTestContexts {
- public static SSLContext createServerSSLContext() throws Exception {
+ public static SSLContext createServerSSLContext() {
final URL keyStoreURL = SSLTestContexts.class.getResource("/test.p12");
final String storePassword = "nopassword";
- return SSLContextBuilder.create()
- .setKeyStoreType("pkcs12")
- .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
- .loadKeyMaterial(keyStoreURL, storePassword.toCharArray(), storePassword.toCharArray())
- .build();
+ try {
+ return SSLContextBuilder.create()
+ .setKeyStoreType("pkcs12")
+ .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
+ .loadKeyMaterial(keyStoreURL, storePassword.toCharArray(), storePassword.toCharArray())
+ .build();
+ } catch (final NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException |
+ UnrecoverableKeyException | IOException ex) {
+ throw new IllegalStateException(ex);
+ }
}
- public static SSLContext createClientSSLContext() throws Exception {
+ public static SSLContext createClientSSLContext() {
final URL keyStoreURL = SSLTestContexts.class.getResource("/test.p12");
final String storePassword = "nopassword";
- return SSLContextBuilder.create()
- .setKeyStoreType("pkcs12")
- .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
- .build();
+ try {
+ return SSLContextBuilder.create()
+ .setKeyStoreType("pkcs12")
+ .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
+ .build();
+ } catch (final NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException |
+ IOException ex) {
+ throw new IllegalStateException(ex);
+ }
}
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicAuthenticationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicAuthenticationTest.java
index ec0d142ba..881508d98 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicAuthenticationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicAuthenticationTest.java
@@ -43,7 +43,6 @@ import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.Method;
-import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
import org.apache.hc.core5.http.impl.bootstrap.StandardFilter;
@@ -58,6 +57,7 @@ import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.net.URIAuthority;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.classic.HttpRequesterResource;
import org.apache.hc.core5.testing.extension.classic.HttpServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -75,7 +75,8 @@ abstract class ClassicAuthenticationTest {
private HttpRequesterResource clientResource;
public ClassicAuthenticationTest(final Boolean respondImmediately) {
- this.serverResource = new HttpServerResource(URIScheme.HTTP, bootstrap -> bootstrap
+ this.serverResource = new HttpServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setSocketConfig(
SocketConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -116,7 +117,9 @@ abstract class ClassicAuthenticationTest {
}
})
);
- this.clientResource = new HttpRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setSslContext(SSLTestContexts.createClientSSLContext())
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1CoreTransportTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1CoreTransportTest.java
index a9e5b9857..8c1afe4b5 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1CoreTransportTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1CoreTransportTest.java
@@ -41,6 +41,7 @@ import org.apache.hc.core5.http.impl.routing.RequestRouter;
import org.apache.hc.core5.http.io.HttpFilterChain;
import org.apache.hc.core5.http.io.HttpRequestHandler;
import org.apache.hc.core5.http.io.SocketConfig;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.classic.HttpRequesterResource;
import org.apache.hc.core5.testing.extension.classic.HttpServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -57,7 +58,9 @@ abstract class ClassicHttp1CoreTransportTest extends ClassicHttpCoreTransportTes
public ClassicHttp1CoreTransportTest(final URIScheme scheme) {
super(scheme);
- this.serverResource = new HttpServerResource(scheme, bootstrap -> bootstrap
+ this.serverResource = new HttpServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setSslContext(scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null)
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
@@ -84,7 +87,9 @@ abstract class ClassicHttp1CoreTransportTest extends ClassicHttpCoreTransportTes
}
}, context)));
- this.clientResource = new HttpRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setSslContext(SSLTestContexts.createClientSSLContext())
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.build()));
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1SocksProxyCoreTransportTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1SocksProxyCoreTransportTest.java
index deb3598ae..11e92328b 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1SocksProxyCoreTransportTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicHttp1SocksProxyCoreTransportTest.java
@@ -41,6 +41,7 @@ import org.apache.hc.core5.http.impl.routing.RequestRouter;
import org.apache.hc.core5.http.io.HttpFilterChain;
import org.apache.hc.core5.http.io.HttpRequestHandler;
import org.apache.hc.core5.http.io.SocketConfig;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.SocksProxyResource;
import org.apache.hc.core5.testing.extension.classic.HttpRequesterResource;
import org.apache.hc.core5.testing.extension.classic.HttpServerResource;
@@ -63,7 +64,9 @@ abstract class ClassicHttp1SocksProxyCoreTransportTest extends ClassicHttpCoreTr
public ClassicHttp1SocksProxyCoreTransportTest(final URIScheme scheme) {
super(scheme);
this.proxyResource = new SocksProxyResource();
- this.serverResource = new HttpServerResource(scheme, bootstrap -> bootstrap
+ this.serverResource = new HttpServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setSslContext(scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null)
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
@@ -90,7 +93,9 @@ abstract class ClassicHttp1SocksProxyCoreTransportTest extends ClassicHttpCoreTr
}
}, context)));
- this.clientResource = new HttpRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setSslContext(SSLTestContexts.createClientSSLContext())
.setSocketConfig(SocketConfig.custom()
.setSocksProxyAddress(proxyResource.proxy().getProxyAddress())
.setSoTimeout(TIMEOUT)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java
index ef191c3c8..435df746b 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java
@@ -49,6 +49,7 @@ import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.classic.HttpRequesterResource;
import org.apache.hc.core5.testing.extension.classic.HttpServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -70,7 +71,9 @@ abstract class ClassicServerBootstrapFilterTest {
public ClassicServerBootstrapFilterTest(final URIScheme scheme) {
this.scheme = scheme;
- this.serverResource = new HttpServerResource(scheme, bootstrap -> bootstrap
+ this.serverResource = new HttpServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setSslContext(scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null)
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
@@ -96,7 +99,9 @@ abstract class ClassicServerBootstrapFilterTest {
}, context)));
- this.clientResource = new HttpRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setSslContext(SSLTestContexts.createClientSSLContext())
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.build()));
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
index 38d25ea63..81ff0e804 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
@@ -49,6 +49,7 @@ import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.classic.HttpRequesterResource;
import org.apache.hc.core5.testing.extension.classic.HttpServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -72,8 +73,9 @@ abstract class MonitoringResponseOutOfOrderStrategyIntegrationTest {
public MonitoringResponseOutOfOrderStrategyIntegrationTest(final URIScheme scheme) {
this.scheme = scheme;
-
- this.serverResource = new HttpServerResource(scheme, bootstrap -> bootstrap
+ this.serverResource = new HttpServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setSslContext(scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null)
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.setSndBufSize(BUFFER_SIZE)
@@ -88,7 +90,9 @@ abstract class MonitoringResponseOutOfOrderStrategyIntegrationTest {
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build()));
- this.clientResource = new HttpRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setSslContext(SSLTestContexts.createClientSSLContext())
.setSocketConfig(SocketConfig.custom()
.setSoTimeout(TIMEOUT)
.setRcvBufSize(BUFFER_SIZE)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/SocksProxyResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/SocksProxyResource.java
index e8158f99a..8ee33f5c4 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/SocksProxyResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/SocksProxyResource.java
@@ -27,26 +27,29 @@
package org.apache.hc.core5.testing.extension;
+import java.io.IOException;
+
import org.apache.hc.core5.testing.SocksProxy;
import org.apache.hc.core5.util.TimeValue;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class SocksProxyResource implements BeforeEachCallback, AfterEachCallback {
+public class SocksProxyResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(SocksProxyResource.class);
- private SocksProxy proxy;
+ private final SocksProxy proxy;
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
+ public SocksProxyResource() {
LOG.debug("Starting up SOCKS proxy");
- proxy = new SocksProxy();
- proxy.start();
+ this.proxy = new SocksProxy();
+ try {
+ this.proxy.start();
+ } catch (final IOException ex) {
+ throw new RuntimeException(ex);
+ }
}
@Override
@@ -61,7 +64,6 @@ public class SocksProxyResource implements BeforeEachCallback, AfterEachCallback
}
public SocksProxy proxy() {
- Assertions.assertNotNull(proxy);
return proxy;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpRequesterResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpRequesterResource.java
index b5d6be531..4858e460b 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpRequesterResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpRequesterResource.java
@@ -32,39 +32,30 @@ import java.util.function.Consumer;
import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
import org.apache.hc.core5.testing.classic.LoggingHttp1StreamListener;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class HttpRequesterResource implements BeforeEachCallback, AfterEachCallback {
+public class HttpRequesterResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(HttpRequesterResource.class);
- private final Consumer<RequesterBootstrap> bootstrapCustomizer;
-
+ private final RequesterBootstrap bootstrap;
private HttpRequester requester;
- public HttpRequesterResource(final Consumer<RequesterBootstrap> bootstrapCustomizer) {
- this.bootstrapCustomizer = bootstrapCustomizer;
- }
-
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
- LOG.debug("Starting up test client");
- final RequesterBootstrap bootstrap = RequesterBootstrap.bootstrap()
- .setSslContext(SSLTestContexts.createClientSSLContext())
+ public HttpRequesterResource() {
+ this.bootstrap = RequesterBootstrap.bootstrap()
.setMaxTotal(2)
.setDefaultMaxPerRoute(2)
.setStreamListener(LoggingHttp1StreamListener.INSTANCE)
.setConnPoolListener(LoggingConnPoolListener.INSTANCE);
- bootstrapCustomizer.accept(bootstrap);
- requester = bootstrap.create();
+ }
+
+ public void configure(final Consumer<RequesterBootstrap> customizer) {
+ customizer.accept(bootstrap);
}
@Override
@@ -79,7 +70,10 @@ public class HttpRequesterResource implements BeforeEachCallback, AfterEachCallb
}
public HttpRequester start() {
- Assertions.assertNotNull(requester);
+ if (requester == null) {
+ LOG.debug("Starting up test client");
+ requester = bootstrap.create();
+ }
return requester;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpServerResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpServerResource.java
index ec961f104..cf09b8917 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpServerResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/classic/HttpServerResource.java
@@ -30,44 +30,32 @@ package org.apache.hc.core5.testing.extension.classic;
import java.io.IOException;
import java.util.function.Consumer;
-import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.classic.LoggingExceptionListener;
import org.apache.hc.core5.testing.classic.LoggingHttp1StreamListener;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class HttpServerResource implements BeforeEachCallback, AfterEachCallback {
+public class HttpServerResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(HttpServerResource.class);
- private final URIScheme scheme;
- private final Consumer<ServerBootstrap> bootstrapCustomizer;
+ private final ServerBootstrap bootstrap;
private HttpServer server;
- public HttpServerResource(final URIScheme scheme, final Consumer<ServerBootstrap> bootstrapCustomizer) {
- this.scheme = scheme;
- this.bootstrapCustomizer = bootstrapCustomizer;
- }
-
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
- LOG.debug("Starting up test server");
-
- final ServerBootstrap bootstrap = ServerBootstrap.bootstrap()
- .setSslContext(scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null)
+ public HttpServerResource() {
+ this.bootstrap = ServerBootstrap.bootstrap()
.setExceptionListener(LoggingExceptionListener.INSTANCE)
.setStreamListener(LoggingHttp1StreamListener.INSTANCE);
- bootstrapCustomizer.accept(bootstrap);
- server = bootstrap.create();
+ }
+
+ public void configure(final Consumer<ServerBootstrap> customizer) {
+ customizer.accept(bootstrap);
}
@Override
@@ -82,8 +70,11 @@ public class HttpServerResource implements BeforeEachCallback, AfterEachCallback
}
public HttpServer start() throws IOException {
- Assertions.assertNotNull(server);
- server.start();
+ if (server == null) {
+ LOG.debug("Starting up test server");
+ server = bootstrap.create();
+ server.start();
+ }
return server;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncRequesterResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncRequesterResource.java
index c343de763..8815e04dc 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncRequesterResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncRequesterResource.java
@@ -29,11 +29,9 @@ package org.apache.hc.core5.testing.extension.nio;
import java.util.function.Consumer;
-import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2AsyncRequester;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
-import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
import org.apache.hc.core5.testing.nio.LoggingExceptionCallback;
import org.apache.hc.core5.testing.nio.LoggingH2StreamListener;
@@ -41,30 +39,20 @@ import org.apache.hc.core5.testing.nio.LoggingHttp1StreamListener;
import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class H2AsyncRequesterResource implements BeforeEachCallback, AfterEachCallback {
+public class H2AsyncRequesterResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(H2AsyncRequesterResource.class);
- private final Consumer<H2RequesterBootstrap> bootstrapCustomizer;
+ private final H2RequesterBootstrap bootstrap;
+ private H2AsyncRequester requester;
- private HttpAsyncRequester requester;
-
- public H2AsyncRequesterResource(final Consumer<H2RequesterBootstrap> bootstrapCustomizer) {
- this.bootstrapCustomizer = bootstrapCustomizer;
- }
-
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
- LOG.debug("Starting up test client");
- final H2RequesterBootstrap bootstrap = H2RequesterBootstrap.bootstrap()
- .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
+ public H2AsyncRequesterResource() {
+ this.bootstrap = H2RequesterBootstrap.bootstrap()
.setStreamListener(LoggingHttp1StreamListener.INSTANCE_CLIENT)
.setStreamListener(LoggingH2StreamListener.INSTANCE)
.setConnPoolListener(LoggingConnPoolListener.INSTANCE)
@@ -72,8 +60,10 @@ public class H2AsyncRequesterResource implements BeforeEachCallback, AfterEachCa
.setExceptionCallback(LoggingExceptionCallback.INSTANCE)
.setIOSessionListener(LoggingIOSessionListener.INSTANCE)
.setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE);
- bootstrapCustomizer.accept(bootstrap);
- requester = bootstrap.create();
+ }
+
+ public void configure(final Consumer<H2RequesterBootstrap> customizer) {
+ customizer.accept(bootstrap);
}
@Override
@@ -87,9 +77,12 @@ public class H2AsyncRequesterResource implements BeforeEachCallback, AfterEachCa
}
}
- public HttpAsyncRequester start() {
- Assertions.assertNotNull(requester);
- requester.start();
+ public H2AsyncRequester start() {
+ if (requester == null) {
+ LOG.debug("Starting up test client");
+ requester = bootstrap.create();
+ requester.start();
+ }
return requester;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncServerResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncServerResource.java
index 91e4ae56e..04f71d5b8 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncServerResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2AsyncServerResource.java
@@ -27,52 +27,42 @@
package org.apache.hc.core5.testing.extension.nio;
+import java.io.IOException;
import java.util.function.Consumer;
import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2ServerBootstrap;
-import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.nio.LoggingExceptionCallback;
import org.apache.hc.core5.testing.nio.LoggingH2StreamListener;
import org.apache.hc.core5.testing.nio.LoggingHttp1StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
-import org.junit.jupiter.api.Assertions;
+import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class H2AsyncServerResource implements BeforeEachCallback, AfterEachCallback {
+public class H2AsyncServerResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(H2AsyncServerResource.class);
- private final Consumer<H2ServerBootstrap> bootstrapCustomizer;
-
+ private final H2ServerBootstrap bootstrap;
private HttpAsyncServer server;
- public H2AsyncServerResource(final Consumer<H2ServerBootstrap> bootstrapCustomizer) {
- this.bootstrapCustomizer = bootstrapCustomizer;
- }
-
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
- LOG.debug("Starting up test server");
-
- final H2ServerBootstrap bootstrap = H2ServerBootstrap.bootstrap()
- .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
+ public H2AsyncServerResource() {
+ this.bootstrap = H2ServerBootstrap.bootstrap()
.setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
.setStreamListener(LoggingH2StreamListener.INSTANCE)
.setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
.setExceptionCallback(LoggingExceptionCallback.INSTANCE)
.setIOSessionListener(LoggingIOSessionListener.INSTANCE)
.setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE);
- bootstrapCustomizer.accept(bootstrap);
- server = bootstrap.create();
+ }
+
+ public void configure(final Consumer<H2ServerBootstrap> customizer) {
+ customizer.accept(bootstrap);
}
@Override
@@ -86,9 +76,12 @@ public class H2AsyncServerResource implements BeforeEachCallback, AfterEachCallb
}
}
- public HttpAsyncServer start() {
- Assertions.assertNotNull(server);
- server.start();
+ public HttpAsyncServer start() throws IOException {
+ if (server == null) {
+ LOG.debug("Starting up test server");
+ server = bootstrap.create();
+ server.start();
+ }
return server;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2MultiplexingRequesterResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2MultiplexingRequesterResource.java
index 144d80571..03bba4802 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2MultiplexingRequesterResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/H2MultiplexingRequesterResource.java
@@ -31,45 +31,36 @@ import java.util.function.Consumer;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2MultiplexingRequester;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2MultiplexingRequesterBootstrap;
-import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.nio.LoggingExceptionCallback;
import org.apache.hc.core5.testing.nio.LoggingH2StreamListener;
import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class H2MultiplexingRequesterResource implements BeforeEachCallback, AfterEachCallback {
+public class H2MultiplexingRequesterResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(H2MultiplexingRequesterResource.class);
- private final Consumer<H2MultiplexingRequesterBootstrap> bootstrapCustomizer;
+ private final H2MultiplexingRequesterBootstrap bootstrap;
private H2MultiplexingRequester requester;
- public H2MultiplexingRequesterResource(final Consumer<H2MultiplexingRequesterBootstrap> bootstrapCustomizer) {
- this.bootstrapCustomizer = bootstrapCustomizer;
- }
-
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
- LOG.debug("Starting up test client");
- final H2MultiplexingRequesterBootstrap bootstrap = H2MultiplexingRequesterBootstrap.bootstrap()
- .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
+ public H2MultiplexingRequesterResource() {
+ this.bootstrap = H2MultiplexingRequesterBootstrap.bootstrap()
.setStreamListener(LoggingH2StreamListener.INSTANCE)
.setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
.setExceptionCallback(LoggingExceptionCallback.INSTANCE)
.setIOSessionListener(LoggingIOSessionListener.INSTANCE)
.setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE);
- bootstrapCustomizer.accept(bootstrap);
- requester = bootstrap.create();
+ }
+
+ public void configure(final Consumer<H2MultiplexingRequesterBootstrap> customizer) {
+ customizer.accept(bootstrap);
}
@Override
@@ -84,8 +75,11 @@ public class H2MultiplexingRequesterResource implements BeforeEachCallback, Afte
}
public H2MultiplexingRequester start() {
- Assertions.assertNotNull(requester);
- requester.start();
+ if (requester == null) {
+ LOG.debug("Starting up test client");
+ requester = bootstrap.create();
+ requester.start();
+ }
return requester;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncRequesterResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncRequesterResource.java
index 9eadba556..28f521994 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncRequesterResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncRequesterResource.java
@@ -31,38 +31,27 @@ import java.util.function.Consumer;
import org.apache.hc.core5.http.impl.bootstrap.AsyncRequesterBootstrap;
import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
-import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
import org.apache.hc.core5.testing.nio.LoggingHttp1StreamListener;
import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class HttpAsyncRequesterResource implements BeforeEachCallback, AfterEachCallback {
+public class HttpAsyncRequesterResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(HttpAsyncRequesterResource.class);
- private final Consumer<AsyncRequesterBootstrap> bootstrapCustomizer;
+ private final AsyncRequesterBootstrap bootstrap;
private HttpAsyncRequester requester;
- public HttpAsyncRequesterResource(final Consumer<AsyncRequesterBootstrap> bootstrapCustomizer) {
- this.bootstrapCustomizer = bootstrapCustomizer;
- }
-
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
- LOG.debug("Starting up test client");
- final AsyncRequesterBootstrap bootstrap = AsyncRequesterBootstrap.bootstrap()
- .setTlsStrategy(new BasicClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
+ public HttpAsyncRequesterResource() {
+ this.bootstrap = AsyncRequesterBootstrap.bootstrap()
.setMaxTotal(2)
.setDefaultMaxPerRoute(2)
.setIOSessionListener(LoggingIOSessionListener.INSTANCE)
@@ -70,8 +59,10 @@ public class HttpAsyncRequesterResource implements BeforeEachCallback, AfterEach
.setConnPoolListener(LoggingConnPoolListener.INSTANCE)
.setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
.setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE);
- bootstrapCustomizer.accept(bootstrap);
- requester = bootstrap.create();
+ }
+
+ public void configure(final Consumer<AsyncRequesterBootstrap> customizer) {
+ customizer.accept(bootstrap);
}
@Override
@@ -86,8 +77,11 @@ public class HttpAsyncRequesterResource implements BeforeEachCallback, AfterEach
}
public HttpAsyncRequester start() {
- Assertions.assertNotNull(requester);
- requester.start();
+ if (requester == null) {
+ LOG.debug("Starting up test client");
+ requester = bootstrap.create();
+ requester.start();
+ }
return requester;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncServerResource.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncServerResource.java
index a522d7e76..15c97c300 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncServerResource.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/extension/nio/HttpAsyncServerResource.java
@@ -27,50 +27,41 @@
package org.apache.hc.core5.testing.extension.nio;
+import java.io.IOException;
import java.util.function.Consumer;
import org.apache.hc.core5.http.impl.bootstrap.AsyncServerBootstrap;
import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
-import org.apache.hc.core5.http.nio.ssl.BasicServerTlsStrategy;
import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.nio.LoggingExceptionCallback;
import org.apache.hc.core5.testing.nio.LoggingHttp1StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
-import org.junit.jupiter.api.Assertions;
+import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class HttpAsyncServerResource implements BeforeEachCallback, AfterEachCallback {
+public class HttpAsyncServerResource implements AfterEachCallback {
private static final Logger LOG = LoggerFactory.getLogger(HttpAsyncServerResource.class);
- private final Consumer<AsyncServerBootstrap> bootstrapCustomizer;
+ private final AsyncServerBootstrap bootstrap;
private HttpAsyncServer server;
- public HttpAsyncServerResource(final Consumer<AsyncServerBootstrap> bootstrapCustomizer) {
- this.bootstrapCustomizer = bootstrapCustomizer;
- }
-
- @Override
- public void beforeEach(final ExtensionContext extensionContext) throws Exception {
- LOG.debug("Starting up test server");
-
- final AsyncServerBootstrap bootstrap = AsyncServerBootstrap.bootstrap()
- .setTlsStrategy(new BasicServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
+ public HttpAsyncServerResource() {
+ this.bootstrap = AsyncServerBootstrap.bootstrap()
.setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
.setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
.setExceptionCallback(LoggingExceptionCallback.INSTANCE)
.setIOSessionListener(LoggingIOSessionListener.INSTANCE)
.setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE);
- bootstrapCustomizer.accept(bootstrap);
- server = bootstrap.create();
+ }
+
+ public void configure(final Consumer<AsyncServerBootstrap> customizer) {
+ customizer.accept(bootstrap);
}
@Override
@@ -84,9 +75,12 @@ public class HttpAsyncServerResource implements BeforeEachCallback, AfterEachCal
}
}
- public HttpAsyncServer start() {
- Assertions.assertNotNull(server);
- server.start();
+ public HttpAsyncServer start() throws IOException {
+ if (server == null) {
+ LOG.debug("Starting up test server");
+ server = bootstrap.create();
+ server.start();
+ }
return server;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java
index ebdee6816..6707b2397 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java
@@ -55,8 +55,11 @@ import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -69,47 +72,55 @@ abstract class AsyncServerBootstrapFilterTest {
private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
@RegisterExtension
- private final HttpAsyncServerResource serverResource = new HttpAsyncServerResource(bootstrap -> bootstrap
- .setIOReactorConfig(
- IOReactorConfig.custom()
- .setSoTimeout(TIMEOUT)
- .build())
- .setRequestRouter(RequestRouter.<Supplier<AsyncServerExchangeHandler>>builder()
+ private final HttpAsyncServerResource serverResource;
+ @RegisterExtension
+ private final HttpAsyncRequesterResource clientResource;
+
+ public AsyncServerBootstrapFilterTest() {
+ this.serverResource = new HttpAsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
+ .setIOReactorConfig(
+ IOReactorConfig.custom()
+ .setSoTimeout(TIMEOUT)
+ .build())
+ .setRequestRouter(RequestRouter.<Supplier<AsyncServerExchangeHandler>>builder()
.addRoute(RequestRouter.LOCAL_AUTHORITY, "*", () -> new EchoHandler(2048))
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
- .addFilterLast("test-filter", (request, entityDetails, context, responseTrigger, chain) ->
- chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
-
- @Override
- public void sendInformation(
- final HttpResponse response) throws HttpException, IOException {
- responseTrigger.sendInformation(response);
- }
-
- @Override
- public void submitResponse(
- final HttpResponse response,
- final AsyncEntityProducer entityProducer) throws HttpException, IOException {
- response.setHeader("X-Test-Filter", "active");
- responseTrigger.submitResponse(response, entityProducer);
- }
-
- @Override
- public void pushPromise(
- final HttpRequest promise,
- final AsyncPushProducer responseProducer) throws HttpException, IOException {
- responseTrigger.pushPromise(promise, responseProducer);
- }
-
- })));
-
- @RegisterExtension
- private final HttpAsyncRequesterResource clientResource = new HttpAsyncRequesterResource(bootstrap -> bootstrap
- .setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(TIMEOUT)
- .build()));
-
+ .addFilterLast("test-filter", (request, entityDetails, context, responseTrigger, chain) ->
+ chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
+
+ @Override
+ public void sendInformation(
+ final HttpResponse response) throws HttpException, IOException {
+ responseTrigger.sendInformation(response);
+ }
+
+ @Override
+ public void submitResponse(
+ final HttpResponse response,
+ final AsyncEntityProducer entityProducer) throws HttpException, IOException {
+ response.setHeader("X-Test-Filter", "active");
+ responseTrigger.submitResponse(response, entityProducer);
+ }
+
+ @Override
+ public void pushPromise(
+ final HttpRequest promise,
+ final AsyncPushProducer responseProducer) throws HttpException, IOException {
+ responseTrigger.pushPromise(promise, responseProducer);
+ }
+
+ })));
+
+ this.clientResource = new HttpAsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
+ .setIOReactorConfig(IOReactorConfig.custom()
+ .setSoTimeout(TIMEOUT)
+ .build()));
+ }
@Test
void testFilters() throws Exception {
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java
index 003695965..39c39b551 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java
@@ -73,7 +73,6 @@ abstract class H2AlpnTest {
private final boolean strictALPN;
private final boolean h2Allowed;
-
@RegisterExtension
private final H2AsyncServerResource serverResource;
@RegisterExtension
@@ -87,7 +86,8 @@ abstract class H2AlpnTest {
new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()) :
new BasicServerTlsStrategy(SSLTestContexts.createServerSSLContext());
- this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -101,7 +101,8 @@ abstract class H2AlpnTest {
final TlsStrategy clientTlsStrategy = new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext());
- this.clientResource = new H2MultiplexingRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new H2MultiplexingRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ConnPoolTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ConnPoolTest.java
index cf80289d3..e72e4b1f3 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ConnPoolTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ConnPoolTest.java
@@ -43,10 +43,13 @@ import org.apache.hc.core5.http2.impl.nio.bootstrap.H2MultiplexingRequester;
import org.apache.hc.core5.http2.nio.command.PingCommand;
import org.apache.hc.core5.http2.nio.pool.H2ConnPool;
import org.apache.hc.core5.http2.nio.support.BasicPingHandler;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.Command;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.IOSession;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
import org.apache.hc.core5.testing.extension.nio.H2MultiplexingRequesterResource;
import org.apache.hc.core5.util.Timeout;
@@ -66,8 +69,10 @@ class H2ConnPoolTest {
private final H2MultiplexingRequesterResource clientResource;
public H2ConnPoolTest() throws Exception {
- this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -79,7 +84,9 @@ class H2ConnPoolTest {
);
this.clientConnCount = new AtomicLong();
- this.clientResource = new H2MultiplexingRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new H2MultiplexingRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportMultiplexingTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportMultiplexingTest.java
index 28b14c548..3a8ff8028 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportMultiplexingTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportMultiplexingTest.java
@@ -56,8 +56,11 @@ import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
import org.apache.hc.core5.http.protocol.HttpCoreContext;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2MultiplexingRequester;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
import org.apache.hc.core5.testing.extension.nio.H2MultiplexingRequesterResource;
import org.apache.hc.core5.util.TimeValue;
@@ -78,8 +81,10 @@ abstract class H2CoreTransportMultiplexingTest {
public H2CoreTransportMultiplexingTest(final URIScheme scheme) {
this.scheme = scheme;
- this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -89,7 +94,9 @@ abstract class H2CoreTransportMultiplexingTest {
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
);
- this.clientResource = new H2MultiplexingRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new H2MultiplexingRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportTest.java
index 3289a56af..2738936c2 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2CoreTransportTest.java
@@ -36,7 +36,10 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
import org.apache.hc.core5.http.impl.routing.RequestRouter;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -53,8 +56,10 @@ abstract class H2CoreTransportTest extends HttpCoreTransportTest {
public H2CoreTransportTest(final URIScheme scheme) {
super(scheme);
- this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -64,8 +69,10 @@ abstract class H2CoreTransportTest extends HttpCoreTransportTest {
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
);
- this.clientResource = new H2AsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
index f635786f5..e34f6e972 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
@@ -129,7 +129,6 @@ abstract class H2IntegrationTest {
private static final Timeout LONG_TIMEOUT = Timeout.ofMinutes(2);
private final URIScheme scheme;
-
@RegisterExtension
private final H2TestResources resources;
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
index 8b2b1d274..09d6ce3e1 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
@@ -51,8 +51,11 @@ import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -70,8 +73,10 @@ class H2ProtocolNegotiationTest {
private final H2AsyncRequesterResource clientResource;
public H2ProtocolNegotiationTest() {
- this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -81,8 +86,10 @@ class H2ProtocolNegotiationTest {
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
);
- this.clientResource = new H2AsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java
index 7638d2013..61d2a8522 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java
@@ -56,8 +56,11 @@ import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -70,48 +73,57 @@ abstract class H2ServerBootstrapFiltersTest {
private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
@RegisterExtension
- private final H2AsyncServerResource serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
- .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
- .setIOReactorConfig(
- IOReactorConfig.custom()
- .setSoTimeout(TIMEOUT)
- .build())
- .setRequestRouter(RequestRouter.<Supplier<AsyncServerExchangeHandler>>builder()
+ private final H2AsyncServerResource serverResource;
+ @RegisterExtension
+ private final H2AsyncRequesterResource clientResource;
+
+ H2ServerBootstrapFiltersTest() {
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
+ .setIOReactorConfig(
+ IOReactorConfig.custom()
+ .setSoTimeout(TIMEOUT)
+ .build())
+ .setRequestRouter(RequestRouter.<Supplier<AsyncServerExchangeHandler>>builder()
.addRoute(RequestRouter.LOCAL_AUTHORITY, "*", () -> new EchoHandler(2048))
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
- .addFilterLast("test-filter", (request, entityDetails, context, responseTrigger, chain) ->
- chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
-
- @Override
- public void sendInformation(
- final HttpResponse response) throws HttpException, IOException {
- responseTrigger.sendInformation(response);
- }
-
- @Override
- public void submitResponse(
- final HttpResponse response,
- final AsyncEntityProducer entityProducer) throws HttpException, IOException {
- response.setHeader("X-Test-Filter", "active");
- responseTrigger.submitResponse(response, entityProducer);
- }
-
- @Override
- public void pushPromise(
- final HttpRequest promise,
- final AsyncPushProducer responseProducer) throws HttpException, IOException {
- responseTrigger.pushPromise(promise, responseProducer);
- }
-
- })));
-
- @RegisterExtension
- private final H2AsyncRequesterResource clientResource = new H2AsyncRequesterResource(bootstrap -> bootstrap
- .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
- .setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(TIMEOUT)
- .build()));
+ .addFilterLast("test-filter", (request, entityDetails, context, responseTrigger, chain) ->
+ chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
+
+ @Override
+ public void sendInformation(
+ final HttpResponse response) throws HttpException, IOException {
+ responseTrigger.sendInformation(response);
+ }
+
+ @Override
+ public void submitResponse(
+ final HttpResponse response,
+ final AsyncEntityProducer entityProducer) throws HttpException, IOException {
+ response.setHeader("X-Test-Filter", "active");
+ responseTrigger.submitResponse(response, entityProducer);
+ }
+
+ @Override
+ public void pushPromise(
+ final HttpRequest promise,
+ final AsyncPushProducer responseProducer) throws HttpException, IOException {
+ responseTrigger.pushPromise(promise, responseProducer);
+ }
+
+ })));
+
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
+ .setIOReactorConfig(IOReactorConfig.custom()
+ .setSoTimeout(TIMEOUT)
+ .build()));
+ }
@Test
void testSequentialRequests() throws Exception {
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2SocksProxyCoreTransportTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2SocksProxyCoreTransportTest.java
index 5c3246130..943d3296e 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2SocksProxyCoreTransportTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2SocksProxyCoreTransportTest.java
@@ -36,7 +36,10 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
import org.apache.hc.core5.http.impl.routing.RequestRouter;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.SocksProxyResource;
import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
@@ -59,8 +62,10 @@ abstract class H2SocksProxyCoreTransportTest extends HttpCoreTransportTest {
public H2SocksProxyCoreTransportTest(final URIScheme scheme) {
super(scheme);
this.proxyResource = new SocksProxyResource();
- this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -70,8 +75,10 @@ abstract class H2SocksProxyCoreTransportTest extends HttpCoreTransportTest {
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
);
- this.clientResource = new H2AsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSocksProxyAddress(proxyResource.proxy().getProxyAddress())
.setSoTimeout(TIMEOUT)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
index 6385fc698..3a77f018e 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
@@ -59,9 +59,12 @@ import org.apache.hc.core5.http.nio.support.AbstractAsyncServerAuthFilter;
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.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.net.URIAuthority;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -79,7 +82,9 @@ abstract class Http1AuthenticationTest {
private final HttpAsyncRequesterResource clientResource;
public Http1AuthenticationTest(final boolean respondImmediately) {
- this.serverResource = new HttpAsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new HttpAsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -120,7 +125,9 @@ abstract class Http1AuthenticationTest {
}
})
);
- this.clientResource = new HttpAsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpAsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1CoreTransportTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1CoreTransportTest.java
index cddbf326a..22376331b 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1CoreTransportTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1CoreTransportTest.java
@@ -57,8 +57,11 @@ import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -77,7 +80,9 @@ abstract class Http1CoreTransportTest extends HttpCoreTransportTest {
public Http1CoreTransportTest(final URIScheme scheme) {
super(scheme);
- this.serverResource = new HttpAsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new HttpAsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -114,7 +119,9 @@ abstract class Http1CoreTransportTest extends HttpCoreTransportTest {
}))
);
- this.clientResource = new HttpAsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpAsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 9c8b80ba3..945dde1eb 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -142,9 +142,7 @@ abstract class Http1IntegrationTest {
private static final Timeout LONG_TIMEOUT = Timeout.ofMinutes(2);
private final URIScheme scheme;
-
private final ReentrantLock lock = new ReentrantLock();
-
@RegisterExtension
private final Http1TestResources resources;
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1SocksProxyCoreTransportTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1SocksProxyCoreTransportTest.java
index 95c06534f..7a01a5d3f 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1SocksProxyCoreTransportTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1SocksProxyCoreTransportTest.java
@@ -44,7 +44,10 @@ import org.apache.hc.core5.http.nio.AsyncEntityProducer;
import org.apache.hc.core5.http.nio.AsyncFilterChain;
import org.apache.hc.core5.http.nio.AsyncPushProducer;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.SocksProxyResource;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncServerResource;
@@ -67,7 +70,9 @@ abstract class Http1SocksProxyCoreTransportTest extends HttpCoreTransportTest {
public Http1SocksProxyCoreTransportTest(final URIScheme scheme) {
super(scheme);
this.proxyResource = new SocksProxyResource();
- this.serverResource = new HttpAsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new HttpAsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -104,7 +109,9 @@ abstract class Http1SocksProxyCoreTransportTest extends HttpCoreTransportTest {
}))
);
- this.clientResource = new HttpAsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpAsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSocksProxyAddress(proxyResource.proxy().getProxyAddress())
.setSoTimeout(TIMEOUT)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/HttpCoreTransportTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/HttpCoreTransportTest.java
index 8766d950b..a870ec209 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/HttpCoreTransportTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/HttpCoreTransportTest.java
@@ -62,7 +62,7 @@ abstract class HttpCoreTransportTest {
final URIScheme scheme;
- HttpCoreTransportTest(final URIScheme scheme) {
+ public HttpCoreTransportTest(final URIScheme scheme) {
this.scheme = scheme;
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TLSUpgradeTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TLSUpgradeTest.java
index 8e52db309..025f04b1f 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TLSUpgradeTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/TLSUpgradeTest.java
@@ -52,10 +52,13 @@ import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
import org.apache.hc.core5.http.nio.ssl.TlsUpgradeCapable;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
import org.apache.hc.core5.reactor.ProtocolIOSession;
import org.apache.hc.core5.reactor.ssl.TlsDetails;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.HttpAsyncServerResource;
import org.apache.hc.core5.util.Timeout;
@@ -74,7 +77,9 @@ class TLSUpgradeTest {
private final HttpAsyncRequesterResource clientResource;
public TLSUpgradeTest() {
- this.serverResource = new HttpAsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new HttpAsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
@@ -84,7 +89,9 @@ class TLSUpgradeTest {
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
);
- this.clientResource = new HttpAsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new HttpAsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java
index e4bf3a948..be8e058d4 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java
@@ -59,11 +59,14 @@ import org.apache.hc.core5.http.impl.routing.RequestRouter;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
+import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.reactive.ReactiveEntityProducer;
import org.apache.hc.core5.reactive.ReactiveResponseConsumer;
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.SSLTestContexts;
import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
import org.apache.hc.core5.testing.extension.nio.H2AsyncServerResource;
import org.apache.hc.core5.testing.reactive.Reactive3TestUtils.StreamDescription;
@@ -90,8 +93,10 @@ abstract class ReactiveClientTest {
public ReactiveClientTest(final HttpVersionPolicy httpVersionPolicy) {
this.versionPolicy = httpVersionPolicy;
- this.serverResource = new H2AsyncServerResource(bootstrap -> bootstrap
+ this.serverResource = new H2AsyncServerResource();
+ this.serverResource.configure(bootstrap -> bootstrap
.setVersionPolicy(versionPolicy)
+ .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
.setIOReactorConfig(
IOReactorConfig.custom()
.setSoTimeout(SOCKET_TIMEOUT)
@@ -101,8 +106,10 @@ abstract class ReactiveClientTest {
.resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
.build())
);
- this.clientResource = new H2AsyncRequesterResource(bootstrap -> bootstrap
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
.setVersionPolicy(versionPolicy)
+ .setTlsStrategy(new H2ClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(SOCKET_TIMEOUT)
.build())
(httpcomponents-core) 02/02: Redesign of compatibility integration tests for greater flexibility and extensibility; added classic i/o and TLS compatibility tests
Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
commit 1ed6e17937b80b26607af0ec8620c55c8e9285df
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Oct 15 16:34:17 2024 +0200
Redesign of compatibility integration tests for greater flexibility and extensibility; added classic i/o and TLS compatibility tests
---
.gitignore | 3 +
.../testing/compatibility/ApacheHttpDCompatIT.java | 128 ++++++++
.../testing/compatibility/ContainerImages.java | 109 +++++--
...acheHttpDCompatIT.java => HttpBinCompatIT.java} | 43 ++-
.../core5/testing/compatibility/NginxCompatIT.java | 128 ++++++++
.../NginxCompatIT.java => TLSTestContexts.java} | 55 ++--
.../classic/ClassicHttpCompatTest.java | 154 +++++++++
.../classic/HttpBinClassicCompatTest.java | 121 +++++++
.../compatibility/nio/AsyncHttp1CompatTest.java | 70 ++++
.../AsyncHttp2CompatTest.java} | 115 ++-----
.../AsyncHttpCompatTest.java} | 121 ++-----
.../HttpBinAsyncCompatTest.java} | 71 ++--
.../src/test/resources/docker/BUILDING.txt | 43 +++
.../{httpd-vhosts.conf => httpd-default.conf} | 20 +-
.../{ngnix/default.conf => httpd/httpd-h2c.conf} | 32 +-
.../src/test/resources/docker/httpd/httpd-ssl.conf | 53 +++
.../resources/docker/{ngnix => nginx}/default.conf | 8 +-
.../docker/{ngnix/default.conf => nginx/h2c.conf} | 2 +-
.../docker/{ngnix/default.conf => nginx/ssl.conf} | 6 +-
.../src/test/resources/docker/server-cert.pem | 83 +++++
.../src/test/resources/docker/server-key.pem | 28 ++
httpcore5-testing/src/test/resources/test-ca.jks | Bin 0 -> 1037 bytes
test-CA/ca-cert.pem | 23 ++
test-CA/ca-key.pem | 30 ++
test-CA/openssl.cnf | 357 +++++++++++++++++++++
25 files changed, 1450 insertions(+), 353 deletions(-)
diff --git a/.gitignore b/.gitignore
index cde3cfff4..e6786cd55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@ maven-eclipse.xml
*.iml
**/log4j2-debug.xml
**/.checkstyle
+/test-CA/newcerts/
+/test-CA/serial.txt*
+/test-CA/index.txt*
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ApacheHttpDCompatIT.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ApacheHttpDCompatIT.java
new file mode 100644
index 000000000..78cbd98f7
--- /dev/null
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ApacheHttpDCompatIT.java
@@ -0,0 +1,128 @@
+/*
+ * ====================================================================
+ * 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.core5.testing.compatibility;
+
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.testing.compatibility.classic.ClassicHttpCompatTest;
+import org.apache.hc.core5.testing.compatibility.nio.AsyncHttp1CompatTest;
+import org.apache.hc.core5.testing.compatibility.nio.AsyncHttp2CompatTest;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+@Testcontainers(disabledWithoutDocker = true)
+class ApacheHttpDCompatIT {
+
+ private static Network NETWORK = Network.newNetwork();
+ @Container
+ static final GenericContainer<?> HTTPD_CONTAINER = ContainerImages.apacheHttpD(NETWORK);
+
+ @AfterAll
+ static void cleanup() {
+ HTTPD_CONTAINER.close();
+ }
+
+ static HttpHost targetContainerHost() {
+ return new HttpHost(URIScheme.HTTP.id, HTTPD_CONTAINER.getHost(), HTTPD_CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
+ }
+
+ static HttpHost targetContainerH2CHost() {
+ return new HttpHost(URIScheme.HTTP.id, HTTPD_CONTAINER.getHost(), HTTPD_CONTAINER.getMappedPort(ContainerImages.H2C_PORT));
+ }
+
+ static HttpHost targetContainerTLSHost() {
+ return new HttpHost(URIScheme.HTTPS.id, HTTPD_CONTAINER.getHost(), HTTPD_CONTAINER.getMappedPort(ContainerImages.HTTPS_PORT));
+ }
+
+ @Nested
+ @DisplayName("Classic, HTTP/1, plain")
+ class ClassicHttp1 extends ClassicHttpCompatTest {
+
+ public ClassicHttp1() throws Exception {
+ super(targetContainerHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Classic, HTTP/1, TLS")
+ class ClassicHttp1Tls extends ClassicHttpCompatTest {
+
+ public ClassicHttp1Tls() throws Exception {
+ super(targetContainerTLSHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, HTTP/1, plain")
+ class AsyncHttp1 extends AsyncHttp1CompatTest {
+
+ public AsyncHttp1() throws Exception {
+ super(targetContainerHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, HTTP/2, plain")
+ class AsyncHttp2 extends AsyncHttp2CompatTest {
+
+ public AsyncHttp2() throws Exception {
+ super(targetContainerH2CHost(), HttpVersionPolicy.FORCE_HTTP_2);
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, HTTP/1, TLS")
+ class AsyncHttp1Tls extends AsyncHttp1CompatTest {
+
+ public AsyncHttp1Tls() throws Exception {
+ super(targetContainerTLSHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, protocol HTTP/2, TLS")
+ class AsyncHttp2Tls extends AsyncHttp2CompatTest {
+
+ public AsyncHttp2Tls() throws Exception {
+ super(targetContainerTLSHost(), HttpVersionPolicy.FORCE_HTTP_2);
+ }
+
+ }
+
+}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ContainerImages.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ContainerImages.java
index 89d467844..ac7849a78 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ContainerImages.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/ContainerImages.java
@@ -26,69 +26,110 @@
*/
package org.apache.hc.core5.testing.compatibility;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.utility.DockerImageName;
public final class ContainerImages {
+ private static final Logger LOG = LoggerFactory.getLogger(ContainerImages.class);
+
public static final String AAA = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
public static final String BBB = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
public static final String CCC = "ccccccccccccccccccccccccccccccccccccccccccccccccc";
public static final String PUSHY = "I am being very pushy";
+ public static final String APACHE_HTTPD = "test-apache";
+ public static final String NGINX = "test-nginx";
+ public static final String HTTPBIN = "test-httpbin";
+
public static int HTTP_PORT = 80;
+ public static int H2C_PORT = 81;
+ public static int HTTPS_PORT = 443;
- public static GenericContainer<?> httpBin() {
+ public static GenericContainer<?> httpBin(final Network network) {
return new GenericContainer<>(DockerImageName.parse("kennethreitz/httpbin:latest"))
+ .withNetwork(network)
+ .withNetworkAliases(HTTPBIN)
+ .withLogConsumer(new Slf4jLogConsumer(LOG))
.withExposedPorts(HTTP_PORT);
}
- public static GenericContainer<?> apacheHttpD() {
+ public static GenericContainer<?> apacheHttpD(final Network network) {
return new GenericContainer<>(new ImageFromDockerfile()
- .withFileFromClasspath("httpd-vhosts.conf", "docker/httpd/httpd-vhosts.conf")
+ .withFileFromClasspath("httpd-default.conf", "docker/httpd/httpd-default.conf")
+ .withFileFromClasspath("httpd-h2c.conf", "docker/httpd/httpd-h2c.conf")
+ .withFileFromClasspath("httpd-ssl.conf", "docker/httpd/httpd-ssl.conf")
+ .withFileFromClasspath("server-cert.pem", "docker/server-cert.pem")
+ .withFileFromClasspath("server-key.pem", "docker/server-key.pem")
.withFileFromString("pushy", PUSHY)
.withFileFromString("aaa", AAA)
.withFileFromString("bbb", BBB)
.withFileFromString("ccc", CCC)
- .withDockerfileFromBuilder(builder ->
- builder
- .from("httpd:2.4")
- .env("var_dir", "/var/httpd")
- .env("www_dir", "${var_dir}/www")
- .run("mkdir -p ${var_dir}")
- .run("sed -i -E 's/^\\s*#\\s*(LoadModule\\s+http2_module\\s+modules\\/mod_http2.so)/\\1/' conf/httpd.conf")
- .run("sed -i -E 's/^\\s*ServerAdmin.*$/ServerAdmin dev@hc.apache.org/' conf/httpd.conf")
- .run("sed -i -E 's/^\\s*#\\s*(Include\\s+conf\\/extra\\/httpd-vhosts.conf)/\\1/' conf/httpd.conf")
- .copy("httpd-vhosts.conf", "/usr/local/apache2/conf/extra/httpd-vhosts.conf")
- .copy("pushy", "${www_dir}/")
- .copy("aaa", "${www_dir}/")
- .copy("bbb", "${www_dir}/")
- .copy("ccc", "${www_dir}/")
- .build()))
- .withExposedPorts(HTTP_PORT);
+ .withDockerfileFromBuilder(builder -> builder
+ .from("httpd:2.4")
+ .env("var_dir", "/var/httpd")
+ .env("www_dir", "${var_dir}/www")
+ .run("mkdir -p ${var_dir}")
+ .run("mkdir -p ${www_dir}")
+ .run("echo '\\n" +
+ "LoadModule http2_module modules/mod_http2.so\\n" +
+ "LoadModule ssl_module modules/mod_ssl.so\\n" +
+ "Include conf/extra/httpd-default.conf\\n" +
+ "Include conf/extra/httpd-h2c.conf\\n" +
+ "Include conf/extra/httpd-ssl.conf\\n" +
+ "'" +
+ " >> /usr/local/apache2/conf/httpd.conf")
+ .copy("httpd-default.conf", "/usr/local/apache2/conf/extra/httpd-default.conf")
+ .copy("httpd-h2c.conf", "/usr/local/apache2/conf/extra/httpd-h2c.conf")
+ .copy("httpd-ssl.conf", "/usr/local/apache2/conf/extra/httpd-ssl.conf")
+ .copy("server-cert.pem", "/usr/local/apache2/conf/server-cert.pem")
+ .copy("server-key.pem", "/usr/local/apache2/conf/server-key.pem")
+ .copy("pushy", "${www_dir}/")
+ .copy("aaa", "${www_dir}/")
+ .copy("bbb", "${www_dir}/")
+ .copy("ccc", "${www_dir}/")
+ .build()))
+ .withNetwork(network)
+ .withNetworkAliases(APACHE_HTTPD)
+ .withLogConsumer(new Slf4jLogConsumer(LOG))
+ .withExposedPorts(HTTP_PORT, H2C_PORT, HTTPS_PORT);
}
- public static GenericContainer<?> ngnix() {
+ public static GenericContainer<?> nginx(final Network network) {
return new GenericContainer<>(new ImageFromDockerfile()
- .withFileFromClasspath("default.conf", "docker/ngnix/default.conf")
+ .withFileFromClasspath("default.conf", "docker/nginx/default.conf")
+ .withFileFromClasspath("h2c.conf", "docker/nginx/h2c.conf")
+ .withFileFromClasspath("ssl.conf", "docker/nginx/ssl.conf")
+ .withFileFromClasspath("server-cert.pem", "docker/server-cert.pem")
+ .withFileFromClasspath("server-key.pem", "docker/server-key.pem")
.withFileFromString("pushy", PUSHY)
.withFileFromString("aaa", AAA)
.withFileFromString("bbb", BBB)
.withFileFromString("ccc", CCC)
- .withDockerfileFromBuilder(builder ->
- builder
- .from("nginx:1.22")
- .env("var_dir", "/var/nginx")
- .env("www_dir", "${var_dir}/www")
- .run("mkdir -p ${var_dir}")
- .copy("default.conf", "/etc/nginx/conf.d/default.conf")
- .copy("pushy", "${www_dir}/")
- .copy("aaa", "${www_dir}/")
- .copy("bbb", "${www_dir}/")
- .copy("ccc", "${www_dir}/")
- .build()))
- .withExposedPorts(HTTP_PORT);
+ .withDockerfileFromBuilder(builder -> builder
+ .from("nginx:1.22")
+ .env("var_dir", "/var/nginx")
+ .env("www_dir", "${var_dir}/www")
+ .run("mkdir -p ${var_dir}")
+ .copy("default.conf", "/etc/nginx/conf.d/default.conf")
+ .copy("h2c.conf", "/etc/nginx/conf.d/h2c.conf")
+ .copy("ssl.conf", "/etc/nginx/conf.d/ssl.conf")
+ .copy("server-cert.pem", "/etc/nginx/server-cert.pem")
+ .copy("server-key.pem", "/etc/nginx/server-key.pem")
+ .copy("pushy", "${www_dir}/")
+ .copy("aaa", "${www_dir}/")
+ .copy("bbb", "${www_dir}/")
+ .copy("ccc", "${www_dir}/")
+ .build()))
+ .withNetwork(network)
+ .withNetworkAliases(NGINX)
+ .withLogConsumer(new Slf4jLogConsumer(LOG))
+ .withExposedPorts(HTTP_PORT, H2C_PORT, HTTPS_PORT);
}
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/ApacheHttpDCompatIT.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/HttpBinCompatIT.java
similarity index 57%
rename from httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/ApacheHttpDCompatIT.java
rename to httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/HttpBinCompatIT.java
index 0277dba0a..6157acf12 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/ApacheHttpDCompatIT.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/HttpBinCompatIT.java
@@ -25,35 +25,48 @@
*
*/
-package org.apache.hc.core5.testing.compatibility.http2;
+package org.apache.hc.core5.testing.compatibility;
import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
-import org.apache.hc.core5.testing.compatibility.ContainerImages;
-import org.junit.jupiter.api.AfterAll;
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.testing.compatibility.classic.HttpBinClassicCompatTest;
+import org.apache.hc.core5.testing.compatibility.nio.HttpBinAsyncCompatTest;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Testcontainers(disabledWithoutDocker = true)
-class ApacheHttpDCompatIT extends AbstractHttp2CompatIT {
+class HttpBinCompatIT {
+ private static Network NETWORK = Network.newNetwork();
@Container
- static final GenericContainer<?> CONTAINER = ContainerImages.apacheHttpD();
+ static final GenericContainer<?> HTTP_BIN_CONTAINER = ContainerImages.httpBin(NETWORK);
- @Override
- void configure(final H2RequesterBootstrap bootstrap) {
+ static HttpHost targetContainerHost() {
+ return new HttpHost(URIScheme.HTTP.id, HTTP_BIN_CONTAINER.getHost(), HTTP_BIN_CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
}
- HttpHost targetHost() {
- return new HttpHost("http",
- CONTAINER.getHost(),
- CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
+ @Nested
+ @DisplayName("Classic")
+ class Classic extends HttpBinClassicCompatTest {
+
+ public Classic() throws Exception {
+ super(targetContainerHost());
+ }
+
}
- @AfterAll
- static void cleanup() {
- CONTAINER.close();
+ @Nested
+ @DisplayName("Async")
+ class Async extends HttpBinAsyncCompatTest {
+
+ public Async() throws Exception {
+ super(targetContainerHost());
+ }
+
}
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/NginxCompatIT.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/NginxCompatIT.java
new file mode 100644
index 000000000..3a8a632b1
--- /dev/null
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/NginxCompatIT.java
@@ -0,0 +1,128 @@
+/*
+ * ====================================================================
+ * 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.core5.testing.compatibility;
+
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.testing.compatibility.classic.ClassicHttpCompatTest;
+import org.apache.hc.core5.testing.compatibility.nio.AsyncHttp1CompatTest;
+import org.apache.hc.core5.testing.compatibility.nio.AsyncHttp2CompatTest;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+@Testcontainers(disabledWithoutDocker = true)
+class NginxCompatIT {
+
+ private static Network NETWORK = Network.newNetwork();
+ @Container
+ static final GenericContainer<?> NGINX_CONTAINER = ContainerImages.nginx(NETWORK);
+
+ @AfterAll
+ static void cleanup() {
+ NGINX_CONTAINER.close();
+ }
+
+ static HttpHost targetContainerHost() {
+ return new HttpHost(URIScheme.HTTP.id, NGINX_CONTAINER.getHost(), NGINX_CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
+ }
+
+ static HttpHost targetContainerH2CHost() {
+ return new HttpHost(URIScheme.HTTP.id, NGINX_CONTAINER.getHost(), NGINX_CONTAINER.getMappedPort(ContainerImages.H2C_PORT));
+ }
+
+ static HttpHost targetContainerTLSHost() {
+ return new HttpHost(URIScheme.HTTPS.id, NGINX_CONTAINER.getHost(), NGINX_CONTAINER.getMappedPort(ContainerImages.HTTPS_PORT));
+ }
+
+ @Nested
+ @DisplayName("Classic, HTTP/1, plain")
+ class ClassicHttp1 extends ClassicHttpCompatTest {
+
+ public ClassicHttp1() throws Exception {
+ super(targetContainerHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Classic, HTTP/1, TLS")
+ class ClassicHttp1Tls extends ClassicHttpCompatTest {
+
+ public ClassicHttp1Tls() throws Exception {
+ super(targetContainerTLSHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, HTTP/1, plain")
+ class AsyncHttp1 extends AsyncHttp1CompatTest {
+
+ public AsyncHttp1() throws Exception {
+ super(targetContainerHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, HTTP/2, plain")
+ class AsyncHttp2 extends AsyncHttp2CompatTest {
+
+ public AsyncHttp2() throws Exception {
+ super(targetContainerH2CHost(), HttpVersionPolicy.FORCE_HTTP_2);
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, HTTP/1, TLS")
+ class AsyncHttp1Tls extends AsyncHttp1CompatTest {
+
+ public AsyncHttp1Tls() throws Exception {
+ super(targetContainerTLSHost());
+ }
+
+ }
+
+ @Nested
+ @DisplayName("Async, HTTP/2, TLS")
+ class AsyncHttp2Tls extends AsyncHttp2CompatTest {
+
+ public AsyncHttp2Tls() throws Exception {
+ super(targetContainerTLSHost(), HttpVersionPolicy.FORCE_HTTP_2);
+ }
+
+ }
+
+}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/NginxCompatIT.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/TLSTestContexts.java
similarity index 55%
rename from httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/NginxCompatIT.java
rename to httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/TLSTestContexts.java
index 06ef115bc..527f90aa7 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/NginxCompatIT.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/TLSTestContexts.java
@@ -25,35 +25,32 @@
*
*/
-package org.apache.hc.core5.testing.compatibility.http2;
-
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
-import org.apache.hc.core5.testing.compatibility.ContainerImages;
-import org.junit.jupiter.api.AfterAll;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
-
-@Testcontainers(disabledWithoutDocker = true)
-class NginxCompatIT extends AbstractHttp2CompatIT {
-
- @Container
- static final GenericContainer<?> CONTAINER = ContainerImages.ngnix();
-
- @Override
- void configure(final H2RequesterBootstrap bootstrap) {
- }
-
- HttpHost targetHost() {
- return new HttpHost("http",
- CONTAINER.getHost(),
- CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
- }
-
- @AfterAll
- static void cleanup() {
- CONTAINER.close();
+package org.apache.hc.core5.testing.compatibility;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.hc.core5.ssl.SSLContextBuilder;
+
+public final class TLSTestContexts {
+
+ public static SSLContext createClientSSLContext() {
+ final URL keyStoreURL = TLSTestContexts.class.getResource("/test-ca.jks");
+ final String storePassword = "nopassword";
+ try {
+ return SSLContextBuilder.create()
+ .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
+ .build();
+ } catch (final NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException |
+ IOException ex) {
+ throw new IllegalStateException(ex);
+ }
}
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/ClassicHttpCompatTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/ClassicHttpCompatTest.java
new file mode 100644
index 000000000..3b8cd1bbc
--- /dev/null
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/ClassicHttpCompatTest.java
@@ -0,0 +1,154 @@
+/*
+ * ====================================================================
+ * 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.core5.testing.compatibility.classic;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
+import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
+import org.apache.hc.core5.http.io.SocketConfig;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
+import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.apache.hc.core5.testing.compatibility.ContainerImages;
+import org.apache.hc.core5.testing.compatibility.Result;
+import org.apache.hc.core5.testing.compatibility.TLSTestContexts;
+import org.apache.hc.core5.testing.extension.classic.HttpRequesterResource;
+import org.apache.hc.core5.util.Timeout;
+import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public abstract class ClassicHttpCompatTest {
+
+ static final Timeout TIMEOUT = Timeout.ofSeconds(5);
+
+ private final HttpHost target;
+ @RegisterExtension
+ private final HttpRequesterResource clientResource;
+
+ public ClassicHttpCompatTest(final HttpHost target) {
+ this.target = target;
+ this.clientResource = new HttpRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setSocketConfig(SocketConfig.custom()
+ .setSoTimeout(TIMEOUT)
+ .build())
+ .setSslContext(TLSTestContexts.createClientSSLContext())
+ );
+ }
+
+ void configure(final Consumer<RequesterBootstrap> customizer) {
+ clientResource.configure(customizer);
+ }
+
+ HttpRequester client() {
+ return clientResource.start();
+ }
+
+ @Test
+ void test_sequential_requests() throws Exception {
+ final HttpRequester requester = client();
+
+ final int n = 20;
+ for (int i = 0; i < n; i++) {
+ final HttpCoreContext context = HttpCoreContext.create();
+ final ClassicHttpRequest request = ClassicRequestBuilder.get("/aaa")
+ .setHttpHost(target)
+ .build();
+ requester.execute(target, request, TIMEOUT, context, response -> {
+ assertThat(response.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
+ final String body1 = EntityUtils.toString(response.getEntity());
+ assertThat(body1, CoreMatchers.equalTo(ContainerImages.AAA));
+ return null;
+ });
+ }
+ }
+
+ @Test
+ void test_multi_threaded_requests() throws Exception {
+ final HttpRequester requester = client();
+
+ final int c = 10;
+ final AtomicInteger n = new AtomicInteger(20 * c);
+ final CountDownLatch countDownLatch = new CountDownLatch(c);
+ final Queue<Result<String>> resultQueue = new ConcurrentLinkedQueue<>();
+ final ExecutorService executorService = Executors.newFixedThreadPool(c);
+ try {
+ for (int i = 0; i < c; i++) {
+ executorService.execute(() -> {
+ try {
+ while (n.decrementAndGet() > 0) {
+ final HttpCoreContext context = HttpCoreContext.create();
+ final ClassicHttpRequest request = ClassicRequestBuilder.get("/aaa")
+ .setHttpHost(target)
+ .build();
+ try {
+ requester.execute(target, request, TIMEOUT, context, response -> {
+ resultQueue.add(new Result<>(
+ request,
+ response,
+ EntityUtils.toString(response.getEntity())));
+ return null;
+ });
+ } catch (final Exception ex) {
+ resultQueue.add(new Result<>(request, ex));
+ }
+ }
+ } finally {
+ countDownLatch.countDown();
+ }
+ });
+ }
+ Assertions.assertTrue(countDownLatch.await(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()), "Request executions have not completed in time");
+ for (final Result<String> result : resultQueue) {
+ if (result.isOK()) {
+ Assertions.assertNotNull(result.response);
+ Assertions.assertEquals(HttpStatus.SC_OK, result.response.getCode(), "Response message returned non 200 status");
+ } else {
+ Assertions.fail(result.exception);
+ }
+ }
+ } finally {
+ executorService.shutdownNow();
+ }
+ }
+
+}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/HttpBinClassicCompatTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/HttpBinClassicCompatTest.java
new file mode 100644
index 000000000..bf447fd0e
--- /dev/null
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/classic/HttpBinClassicCompatTest.java
@@ -0,0 +1,121 @@
+/*
+ * ====================================================================
+ * 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.core5.testing.compatibility.classic;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
+import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
+import org.apache.hc.core5.http.io.SocketConfig;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
+import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.apache.hc.core5.testing.extension.classic.HttpRequesterResource;
+import org.apache.hc.core5.util.Timeout;
+import org.hamcrest.CoreMatchers;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public abstract class HttpBinClassicCompatTest {
+
+ static final Timeout TIMEOUT = Timeout.ofSeconds(5);
+
+ private final HttpHost target;
+ @RegisterExtension
+ private final HttpRequesterResource clientResource;
+
+ public HttpBinClassicCompatTest(final HttpHost target) {
+ this.target = target;
+ this.clientResource = new HttpRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setSocketConfig(SocketConfig.custom()
+ .setSoTimeout(TIMEOUT)
+ .build())
+ );
+ }
+
+ void configure(final Consumer<RequesterBootstrap> customizer) {
+ clientResource.configure(customizer);
+ }
+
+ HttpRequester client() {
+ return clientResource.start();
+ }
+
+ @Test
+ void test_sequential_request_execution() throws Exception {
+ final HttpRequester client = client();
+ final List<ClassicHttpRequest> requestMessages = Arrays.asList(
+ ClassicRequestBuilder.get("/headers")
+ .setHttpHost(target)
+ .build(),
+ ClassicRequestBuilder.post("/anything")
+ .setHttpHost(target)
+ .setEntity(new StringEntity("some important message", ContentType.TEXT_PLAIN))
+ .build(),
+ ClassicRequestBuilder.put("/anything")
+ .setHttpHost(target)
+ .setEntity(new StringEntity("some important message", ContentType.TEXT_PLAIN))
+ .build(),
+ ClassicRequestBuilder.get("/drip")
+ .setHttpHost(target)
+ .build(),
+ ClassicRequestBuilder.get("/bytes/20000")
+ .setHttpHost(target)
+ .build(),
+ ClassicRequestBuilder.get("/delay/2")
+ .setHttpHost(target)
+ .build(),
+ ClassicRequestBuilder.post("/delay/2")
+ .setHttpHost(target)
+ .setEntity(new StringEntity("some important message", ContentType.TEXT_PLAIN))
+ .build(),
+ ClassicRequestBuilder.put("/delay/2")
+ .setHttpHost(target)
+ .setEntity(new StringEntity("some important message", ContentType.TEXT_PLAIN))
+ .build()
+ );
+
+ for (final ClassicHttpRequest request : requestMessages) {
+ final HttpCoreContext context = HttpCoreContext.create();
+ client.execute(target, request, TIMEOUT, context, response -> {
+ assertThat(response.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
+ return null;
+ });
+ }
+ }
+
+}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttp1CompatTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttp1CompatTest.java
new file mode 100644
index 000000000..2ddd89ec4
--- /dev/null
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttp1CompatTest.java
@@ -0,0 +1,70 @@
+/*
+ * ====================================================================
+ * 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.core5.testing.compatibility.nio;
+
+import java.util.function.Consumer;
+
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2AsyncRequester;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.testing.compatibility.TLSTestContexts;
+import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
+import org.apache.hc.core5.util.Timeout;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public abstract class AsyncHttp1CompatTest extends AsyncHttpCompatTest<H2AsyncRequester> {
+
+ static final Timeout TIMEOUT = Timeout.ofSeconds(5);
+
+ @RegisterExtension
+ private final H2AsyncRequesterResource clientResource;
+
+ public AsyncHttp1CompatTest(final HttpHost target) {
+ super(target);
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
+ .setIOReactorConfig(IOReactorConfig.custom()
+ .setSoTimeout(TIMEOUT)
+ .build())
+ .setTlsStrategy(new BasicClientTlsStrategy(TLSTestContexts.createClientSSLContext()))
+ .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1));
+ }
+
+ void configure(final Consumer<H2RequesterBootstrap> customizer) {
+ clientResource.configure(customizer);
+ }
+
+ @Override
+ H2AsyncRequester client() {
+ return clientResource.start();
+ }
+
+}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/AbstractHttp2CompatIT.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttp2CompatTest.java
similarity index 57%
copy from httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/AbstractHttp2CompatIT.java
copy to httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttp2CompatTest.java
index a2c80620f..e1f2fa577 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/AbstractHttp2CompatIT.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttp2CompatTest.java
@@ -25,12 +25,13 @@
*
*/
-package org.apache.hc.core5.testing.compatibility.http2;
+package org.apache.hc.core5.testing.compatibility.nio;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
+import java.util.function.Consumer;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.HttpHost;
@@ -40,7 +41,6 @@ import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.Message;
import org.apache.hc.core5.http.Method;
import org.apache.hc.core5.http.RequestNotExecutedException;
-import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
@@ -49,119 +49,54 @@ import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2AsyncRequester;
import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
-import org.apache.hc.core5.io.CloseMode;
+import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
-import org.apache.hc.core5.testing.compatibility.ContainerImages;
import org.apache.hc.core5.testing.compatibility.Result;
-import org.apache.hc.core5.testing.nio.LoggingExceptionCallback;
-import org.apache.hc.core5.testing.nio.LoggingH2StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingHttp1StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
-import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
-import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
+import org.apache.hc.core5.testing.compatibility.TLSTestContexts;
+import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
import org.apache.hc.core5.util.Timeout;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
-abstract class AbstractHttp2CompatIT {
+public abstract class AsyncHttp2CompatTest extends AsyncHttpCompatTest<H2AsyncRequester> {
static final Timeout TIMEOUT = Timeout.ofSeconds(5);
- abstract HttpHost targetHost();
+ private final HttpHost target;
+ @RegisterExtension
+ private final H2AsyncRequesterResource clientResource;
- HttpAsyncRequester client;
-
- abstract void configure(H2RequesterBootstrap bootstrap);
-
- @BeforeEach
- void start() throws Exception {
- final H2RequesterBootstrap bootstrap = H2RequesterBootstrap.bootstrap()
+ public AsyncHttp2CompatTest(final HttpHost target, final HttpVersionPolicy versionPolicy) {
+ super(target);
+ this.target = target;
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
.setH2Config(H2Config.custom()
.setPushEnabled(true)
.build())
- .setStreamListener(LoggingHttp1StreamListener.INSTANCE_CLIENT)
- .setStreamListener(LoggingH2StreamListener.INSTANCE)
- .setConnPoolListener(LoggingConnPoolListener.INSTANCE)
- .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
- .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
- .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
- .setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE);
- configure(bootstrap);
- client = bootstrap.create();
- client.start();
+ .setTlsStrategy(new H2ClientTlsStrategy(TLSTestContexts.createClientSSLContext()))
+ .setVersionPolicy(versionPolicy));
}
- @AfterEach
- void shutdown() throws Exception {
- if (client != null) {
- client.close(CloseMode.GRACEFUL);
- }
+ void configure(final Consumer<H2RequesterBootstrap> customizer) {
+ clientResource.configure(customizer);
}
- @Test
- void test_multiple_request_execution() throws Exception {
- final HttpHost target = targetHost();
- final Future<AsyncClientEndpoint> connectFuture = client.connect(target, TIMEOUT, HttpVersionPolicy.FORCE_HTTP_2, null);
- final AsyncClientEndpoint endpoint = connectFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
- try {
- final int n = 20;
- final CountDownLatch countDownLatch = new CountDownLatch(n);
- final Queue<Result<String>> resultQueue = new ConcurrentLinkedQueue<>();
- for (int i = 0; i < n; i++) {
- final HttpRequest httpget = new BasicHttpRequest(Method.GET, target, "/aaa");
- endpoint.execute(
- new BasicRequestProducer(httpget, null),
- new BasicResponseConsumer<>(new StringAsyncEntityConsumer()),
- new FutureCallback<Message<HttpResponse, String>>() {
-
- @Override
- public void completed(final Message<HttpResponse, String> responseMessage) {
- resultQueue.add(new Result<>(
- httpget,
- responseMessage.getHead(),
- responseMessage.getBody()));
- countDownLatch.countDown();
- }
-
- @Override
- public void failed(final Exception ex) {
- resultQueue.add(new Result<>(httpget, ex));
- countDownLatch.countDown();
- }
-
- @Override
- public void cancelled() {
- failed(new RequestNotExecutedException());
- }
-
- });
- }
- Assertions.assertTrue(countDownLatch.await(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()), "Request executions have not completed in time");
- for (final Result<String> result : resultQueue) {
- if (result.isOK()) {
- Assertions.assertNotNull(result.response);
- Assertions.assertEquals(HttpStatus.SC_OK, result.response.getCode(), "Response message returned non 200 status");
- Assertions.assertEquals(ContainerImages.AAA, result.content);
- } else {
- Assertions.fail(result.exception);
- }
- }
- } finally {
- endpoint.releaseAndDiscard();
- }
+ @Override
+ H2AsyncRequester client() {
+ return clientResource.start();
}
@Test
void test_request_execution_with_push() throws Exception {
- final HttpHost target = targetHost();
- final Future<AsyncClientEndpoint> connectFuture = client.connect(target, TIMEOUT, HttpVersionPolicy.FORCE_HTTP_2, null);
+ final H2AsyncRequester client = client();
+ final Future<AsyncClientEndpoint> connectFuture = client.connect(target, TIMEOUT, null, null);
final AsyncClientEndpoint endpoint = connectFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
try {
final CountDownLatch countDownLatch = new CountDownLatch(4);
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/AbstractHttp2CompatIT.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttpCompatTest.java
similarity index 56%
rename from httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/AbstractHttp2CompatIT.java
rename to httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttpCompatTest.java
index a2c80620f..3107316c8 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/AbstractHttp2CompatIT.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/AsyncHttpCompatTest.java
@@ -25,7 +25,7 @@
*
*/
-package org.apache.hc.core5.testing.compatibility.http2;
+package org.apache.hc.core5.testing.compatibility.nio;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -44,71 +44,30 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
import org.apache.hc.core5.http.message.BasicHttpRequest;
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
-import org.apache.hc.core5.http.nio.support.AbstractAsyncPushHandler;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
-import org.apache.hc.core5.http2.HttpVersionPolicy;
-import org.apache.hc.core5.http2.config.H2Config;
-import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
-import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
import org.apache.hc.core5.testing.compatibility.ContainerImages;
import org.apache.hc.core5.testing.compatibility.Result;
-import org.apache.hc.core5.testing.nio.LoggingExceptionCallback;
-import org.apache.hc.core5.testing.nio.LoggingH2StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingHttp1StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
-import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
-import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
import org.apache.hc.core5.util.Timeout;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-abstract class AbstractHttp2CompatIT {
+public abstract class AsyncHttpCompatTest<T extends HttpAsyncRequester> {
static final Timeout TIMEOUT = Timeout.ofSeconds(5);
- abstract HttpHost targetHost();
-
- HttpAsyncRequester client;
-
- abstract void configure(H2RequesterBootstrap bootstrap);
-
- @BeforeEach
- void start() throws Exception {
- final H2RequesterBootstrap bootstrap = H2RequesterBootstrap.bootstrap()
- .setIOReactorConfig(IOReactorConfig.custom()
- .setSoTimeout(TIMEOUT)
- .build())
- .setH2Config(H2Config.custom()
- .setPushEnabled(true)
- .build())
- .setStreamListener(LoggingHttp1StreamListener.INSTANCE_CLIENT)
- .setStreamListener(LoggingH2StreamListener.INSTANCE)
- .setConnPoolListener(LoggingConnPoolListener.INSTANCE)
- .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
- .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
- .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
- .setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE);
- configure(bootstrap);
- client = bootstrap.create();
- client.start();
- }
+ private final HttpHost target;
- @AfterEach
- void shutdown() throws Exception {
- if (client != null) {
- client.close(CloseMode.GRACEFUL);
- }
+ public AsyncHttpCompatTest(final HttpHost target) {
+ this.target = target;
}
+ abstract T client();
+
@Test
- void test_multiple_request_execution() throws Exception {
- final HttpHost target = targetHost();
- final Future<AsyncClientEndpoint> connectFuture = client.connect(target, TIMEOUT, HttpVersionPolicy.FORCE_HTTP_2, null);
+ void test_multiple_request_execution_over_same_connection() throws Exception {
+ final HttpAsyncRequester client = client();
+ final Future<AsyncClientEndpoint> connectFuture = client.connect(target, TIMEOUT, null, null);
final AsyncClientEndpoint endpoint = connectFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
try {
final int n = 20;
@@ -159,37 +118,20 @@ abstract class AbstractHttp2CompatIT {
}
@Test
- void test_request_execution_with_push() throws Exception {
- final HttpHost target = targetHost();
- final Future<AsyncClientEndpoint> connectFuture = client.connect(target, TIMEOUT, HttpVersionPolicy.FORCE_HTTP_2, null);
- final AsyncClientEndpoint endpoint = connectFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
- try {
- final CountDownLatch countDownLatch = new CountDownLatch(4);
- final Queue<Result<String>> resultQueue = new ConcurrentLinkedQueue<>();
- final HttpRequest httpget = new BasicHttpRequest(Method.GET, target, "/pushy");
- endpoint.execute(
+ void test_multiple_request_execution_over_multiple_connections() throws Exception {
+ final HttpAsyncRequester client = client();
+ final int c = 10;
+ client.setDefaultMaxPerRoute(10);
+ final int n = 20 * c;
+ final CountDownLatch countDownLatch = new CountDownLatch(n);
+ final Queue<Result<String>> resultQueue = new ConcurrentLinkedQueue<>();
+ for (int i = 0; i < n; i++) {
+ final HttpRequest httpget = new BasicHttpRequest(Method.GET, target, "/aaa");
+ client.execute(
+ target,
new BasicRequestProducer(httpget, null),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()),
- (request, context) ->
- new AbstractAsyncPushHandler<Message<HttpResponse, String>>(new BasicResponseConsumer<>(new StringAsyncEntityConsumer())) {
-
- @Override
- protected void handleResponse(final HttpRequest promise, final Message<HttpResponse, String> responseMessage) {
- resultQueue.add(new Result<>(
- httpget,
- responseMessage.getHead(),
- responseMessage.getBody()));
- countDownLatch.countDown();
- }
-
- @Override
- protected void handleError(final HttpRequest promise, final Exception cause) {
- resultQueue.add(new Result<>(httpget, cause));
- countDownLatch.countDown();
- }
-
- },
- null,
+ TIMEOUT,
new FutureCallback<Message<HttpResponse, String>>() {
@Override
@@ -213,17 +155,16 @@ abstract class AbstractHttp2CompatIT {
}
});
- Assertions.assertTrue(countDownLatch.await(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()), "Request executions have not completed in time");
- for (final Result<String> result : resultQueue) {
- if (result.isOK()) {
- Assertions.assertNotNull(result.response);
- Assertions.assertEquals(HttpStatus.SC_OK, result.response.getCode(), "Response message returned non 200 status");
- } else {
- Assertions.fail(result.exception);
- }
+ }
+ Assertions.assertTrue(countDownLatch.await(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()), "Request executions have not completed in time");
+ for (final Result<String> result : resultQueue) {
+ if (result.isOK()) {
+ Assertions.assertNotNull(result.response);
+ Assertions.assertEquals(HttpStatus.SC_OK, result.response.getCode(), "Response message returned non 200 status");
+ Assertions.assertEquals(ContainerImages.AAA, result.content);
+ } else {
+ Assertions.fail(result.exception);
}
- } finally {
- endpoint.releaseAndDiscard();
}
}
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http1/HttpBinCompatIT.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/HttpBinAsyncCompatTest.java
similarity index 78%
rename from httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http1/HttpBinCompatIT.java
rename to httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/HttpBinAsyncCompatTest.java
index 38b063d88..f0dd5f5aa 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http1/HttpBinCompatIT.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/nio/HttpBinAsyncCompatTest.java
@@ -25,7 +25,7 @@
*
*/
-package org.apache.hc.core5.testing.compatibility.http1;
+package org.apache.hc.core5.testing.compatibility.nio;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
@@ -54,76 +54,41 @@ import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
-import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
-import org.apache.hc.core5.io.CloseMode;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2AsyncRequester;
import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
-import org.apache.hc.core5.testing.compatibility.ContainerImages;
import org.apache.hc.core5.testing.compatibility.Result;
-import org.apache.hc.core5.testing.nio.LoggingExceptionCallback;
-import org.apache.hc.core5.testing.nio.LoggingH2StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingHttp1StreamListener;
-import org.apache.hc.core5.testing.nio.LoggingIOSessionDecorator;
-import org.apache.hc.core5.testing.nio.LoggingIOSessionListener;
-import org.apache.hc.core5.testing.nio.LoggingReactorMetricsListener;
+import org.apache.hc.core5.testing.extension.nio.H2AsyncRequesterResource;
import org.apache.hc.core5.util.Timeout;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
+import org.junit.jupiter.api.extension.RegisterExtension;
-@Testcontainers(disabledWithoutDocker = true)
-class HttpBinCompatIT {
+public abstract class HttpBinAsyncCompatTest {
static final Timeout TIMEOUT = Timeout.ofSeconds(5);
- @Container
- static final GenericContainer<?> CONTAINER = ContainerImages.httpBin();
+ private final HttpHost target;
+ @RegisterExtension
+ private final H2AsyncRequesterResource clientResource;
- static HttpHost targetHost() {
- return new HttpHost("http",
- CONTAINER.getHost(),
- CONTAINER.getMappedPort(ContainerImages.HTTP_PORT));
- }
-
- HttpAsyncRequester client;
-
- @BeforeEach
- void start() throws Exception {
- client = H2RequesterBootstrap.bootstrap()
+ public HttpBinAsyncCompatTest(final HttpHost target) {
+ this.target = target;
+ this.clientResource = new H2AsyncRequesterResource();
+ this.clientResource.configure(bootstrap -> bootstrap
.setIOReactorConfig(IOReactorConfig.custom()
.setSoTimeout(TIMEOUT)
.build())
- .setStreamListener(LoggingHttp1StreamListener.INSTANCE_CLIENT)
- .setStreamListener(LoggingH2StreamListener.INSTANCE)
- .setConnPoolListener(LoggingConnPoolListener.INSTANCE)
- .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
- .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
- .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
- .setIOReactorMetricsListener(LoggingReactorMetricsListener.INSTANCE)
- .create();
- client.start();
- }
-
- @AfterEach
- void shutdown() throws Exception {
- if (client != null) {
- client.close(CloseMode.GRACEFUL);
- }
+ .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1));
}
- @AfterAll
- static void cleanup() {
- CONTAINER.close();
+ H2AsyncRequester client() {
+ return clientResource.start();
}
@Test
void test_sequential_request_execution() throws Exception {
- final HttpHost target = targetHost();
+ final HttpAsyncRequester client = client();
final List<Message<HttpRequest, AsyncEntityProducer>> requestMessages = Arrays.asList(
new Message<>(new BasicHttpRequest(Method.GET, target, "/headers")),
new Message<>(
@@ -162,7 +127,7 @@ class HttpBinCompatIT {
@Test
void test_pipelined_request_execution() throws Exception {
- final HttpHost target = targetHost();
+ final HttpAsyncRequester client = client();
final Future<AsyncClientEndpoint> connectFuture = client.connect(target, TIMEOUT);
final AsyncClientEndpoint streamEndpoint = connectFuture.get();
try {
diff --git a/httpcore5-testing/src/test/resources/docker/BUILDING.txt b/httpcore5-testing/src/test/resources/docker/BUILDING.txt
new file mode 100644
index 000000000..8896f184f
--- /dev/null
+++ b/httpcore5-testing/src/test/resources/docker/BUILDING.txt
@@ -0,0 +1,43 @@
+= SSL key / cert material
+
+Execute in the project root
+
+# Issue a certificate request
+---
+openssl req -config test-CA/openssl.cnf -new -nodes -sha256 -days 36500 \
+ -subj '/O=Apache Software Foundation/OU=HttpComponents Project/CN=localhost/emailAddress=dev@hc.apache.org/' \
+ -addext 'subjectAltName = DNS:localhost' \
+ -keyout httpcore5-testing/src/test/resources/docker/server-key.pem \
+ -out httpcore5-testing/src/test/resources/docker/server-certreq.pem
+---
+# Verify the request
+---
+openssl req -in httpcore5-testing/src/test/resources/docker/server-certreq.pem -text -noout
+---
+# Sign new certificate with the test CA key
+---
+openssl ca -config test-CA/openssl.cnf -days 36500 \
+ -out httpcore5-testing/src/test/resources/docker/server-cert.pem \
+ -in httpcore5-testing/src/test/resources/docker/server-certreq.pem \
+ && rm httpcore5-testing/src/test/resources/docker/server-certreq.pem
+---
+
+# Create JKS store with the Test CA cert
+keytool -import -trustcacerts -alias test-ca -file test-CA/ca-cert.pem -keystore httpcore5-testing/src/test/resources/test-ca.jks -storepass nopassword
+
+= Running a local version of HttpBin
+
+# Create container
+---
+docker container create -it --name test-httpbin -p 8080:80 kennethreitz/httpbin:latest
+docker start test-httpbin
+docker logs test-httpbin
+---
+# Trouble-shoot container
+---
+docker exec -it test-httpbin bash
+---
+# Delete container
+---
+docker rm --force test-httpbin
+---
\ No newline at end of file
diff --git a/httpcore5-testing/src/test/resources/docker/httpd/httpd-vhosts.conf b/httpcore5-testing/src/test/resources/docker/httpd/httpd-default.conf
similarity index 79%
rename from httpcore5-testing/src/test/resources/docker/httpd/httpd-vhosts.conf
rename to httpcore5-testing/src/test/resources/docker/httpd/httpd-default.conf
index fa29ea9c4..8465bdf60 100644
--- a/httpcore5-testing/src/test/resources/docker/httpd/httpd-vhosts.conf
+++ b/httpcore5-testing/src/test/resources/docker/httpd/httpd-default.conf
@@ -13,10 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-ServerName localhost:80
-
-Protocols h2c http/1.1
-
<Directory />
AllowOverride none
Require all denied
@@ -29,15 +25,7 @@ DocumentRoot "/var/httpd/www"
Require all granted
</Directory>
-<IfModule http2_module>
- LogLevel http2:info
- H2Push on
- H2EarlyHints on
-
- <Location /pushy>
- H2PushResource /aaa
- H2PushResource /bbb
- H2PushResource /ccc
- </Location>
-
-</IfModule>
+<VirtualHost _default_:80>
+ ServerName localhost:80
+ Protocols http/1.1
+</VirtualHost>
diff --git a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf b/httpcore5-testing/src/test/resources/docker/httpd/httpd-h2c.conf
similarity index 67%
copy from httpcore5-testing/src/test/resources/docker/ngnix/default.conf
copy to httpcore5-testing/src/test/resources/docker/httpd/httpd-h2c.conf
index c48cd4248..9091a37dd 100644
--- a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf
+++ b/httpcore5-testing/src/test/resources/docker/httpd/httpd-h2c.conf
@@ -13,24 +13,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-server {
- listen 80 http2;
- server_name localhost;
+Listen 81
- location / {
- root /var/nginx/www;
+<VirtualHost _default_:81>
+ ServerName localhost:81
+ Protocols h2c
- location = /pushy {
- http2_push "/aaa";
- http2_push "/bbb";
- http2_push "/ccc";
- }
- }
+ <IfModule http2_module>
+ LogLevel http2:info
+ H2Push on
+ H2EarlyHints on
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root /usr/share/nginx/html;
- }
-
-}
+ <Location /pushy>
+ H2PushResource /aaa
+ H2PushResource /bbb
+ H2PushResource /ccc
+ </Location>
+ </IfModule>
+</VirtualHost>
diff --git a/httpcore5-testing/src/test/resources/docker/httpd/httpd-ssl.conf b/httpcore5-testing/src/test/resources/docker/httpd/httpd-ssl.conf
new file mode 100644
index 000000000..d9722d24c
--- /dev/null
+++ b/httpcore5-testing/src/test/resources/docker/httpd/httpd-ssl.conf
@@ -0,0 +1,53 @@
+# 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.
+#
+
+Listen 443
+
+SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
+SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
+
+SSLHonorCipherOrder on
+
+SSLProtocol all -SSLv3
+SSLProxyProtocol all -SSLv3
+
+SSLPassPhraseDialog builtin
+
+SSLSessionCacheTimeout 300
+
+<VirtualHost _default_:443>
+ ServerName localhost:443
+ Protocols h2 http/1.1
+
+ SSLEngine on
+ SSLCertificateFile "/usr/local/apache2/conf/server-cert.pem"
+ SSLCertificateKeyFile "/usr/local/apache2/conf/server-key.pem"
+ CustomLog /proc/self/fd/1 \
+ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
+ <IfModule http2_module>
+ LogLevel http2:info
+ H2Push on
+ H2EarlyHints on
+
+ <Location /pushy>
+ H2PushResource /aaa
+ H2PushResource /bbb
+ H2PushResource /ccc
+ </Location>
+ </IfModule>
+
+</VirtualHost>
diff --git a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf b/httpcore5-testing/src/test/resources/docker/nginx/default.conf
similarity index 85%
copy from httpcore5-testing/src/test/resources/docker/ngnix/default.conf
copy to httpcore5-testing/src/test/resources/docker/nginx/default.conf
index c48cd4248..99b2ba4b7 100644
--- a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf
+++ b/httpcore5-testing/src/test/resources/docker/nginx/default.conf
@@ -14,17 +14,11 @@
# limitations under the License.
server {
- listen 80 http2;
+ listen 80;
server_name localhost;
location / {
root /var/nginx/www;
-
- location = /pushy {
- http2_push "/aaa";
- http2_push "/bbb";
- http2_push "/ccc";
- }
}
error_page 500 502 503 504 /50x.html;
diff --git a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf b/httpcore5-testing/src/test/resources/docker/nginx/h2c.conf
similarity index 97%
copy from httpcore5-testing/src/test/resources/docker/ngnix/default.conf
copy to httpcore5-testing/src/test/resources/docker/nginx/h2c.conf
index c48cd4248..f994f2f47 100644
--- a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf
+++ b/httpcore5-testing/src/test/resources/docker/nginx/h2c.conf
@@ -14,7 +14,7 @@
# limitations under the License.
server {
- listen 80 http2;
+ listen 81 http2;
server_name localhost;
location / {
diff --git a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf b/httpcore5-testing/src/test/resources/docker/nginx/ssl.conf
similarity index 83%
rename from httpcore5-testing/src/test/resources/docker/ngnix/default.conf
rename to httpcore5-testing/src/test/resources/docker/nginx/ssl.conf
index c48cd4248..e0d83e10a 100644
--- a/httpcore5-testing/src/test/resources/docker/ngnix/default.conf
+++ b/httpcore5-testing/src/test/resources/docker/nginx/ssl.conf
@@ -14,8 +14,12 @@
# limitations under the License.
server {
- listen 80 http2;
+ listen 443 ssl http2;
server_name localhost;
+ ssl_certificate /etc/nginx/server-cert.pem;
+ ssl_certificate_key /etc/nginx/server-key.pem;
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /var/nginx/www;
diff --git a/httpcore5-testing/src/test/resources/docker/server-cert.pem b/httpcore5-testing/src/test/resources/docker/server-cert.pem
new file mode 100644
index 000000000..ce3990fdd
--- /dev/null
+++ b/httpcore5-testing/src/test/resources/docker/server-cert.pem
@@ -0,0 +1,83 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: O=Apache Software Foundation, OU=HttpComponents Project, CN=Test CA/emailAddress=dev@hc.apache.org
+ Validity
+ Not Before: Oct 20 11:31:00 2024 GMT
+ Not After : Sep 26 11:31:00 2124 GMT
+ Subject: O=Apache Software Foundation, OU=HttpComponents Project, CN=localhost/emailAddress=dev@hc.apache.org
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:9a:cf:ff:49:86:9e:3a:0b:0c:2f:4f:89:10:86:
+ 11:30:da:81:8c:9e:26:f7:72:9f:c7:d0:8e:16:67:
+ be:0a:46:ee:d2:9f:67:89:37:b8:38:84:16:d8:66:
+ c1:c8:9a:9f:64:c6:06:8c:57:fe:0d:83:58:4d:3d:
+ f3:d5:35:a7:89:e3:5e:1b:c8:48:b5:66:34:38:ec:
+ 9f:ac:1a:05:81:66:0f:d4:9f:af:a9:0c:bf:20:51:
+ e5:1c:21:63:a5:95:39:86:b0:d6:eb:9d:9a:29:be:
+ 83:df:ef:6b:08:e4:e3:2e:a3:1e:49:4c:b1:2a:f7:
+ 89:49:45:4c:57:c0:47:63:49:5f:85:86:72:d7:06:
+ d1:e6:10:16:ab:60:a3:09:7d:9b:39:e4:13:4b:68:
+ 8e:c3:33:a0:50:ce:45:41:50:f6:38:d8:3e:89:e8:
+ cf:cd:15:24:3f:ea:37:a5:72:37:f8:7b:60:ce:d9:
+ 6b:e1:ef:bc:92:13:48:7a:97:c8:48:87:62:4b:7c:
+ 0e:6f:bf:a5:b7:47:78:2a:5d:74:92:5c:3a:40:8a:
+ f2:e2:d8:35:54:b2:13:1f:d7:c8:0b:c8:d9:89:56:
+ bd:72:d0:84:14:c8:b6:79:b8:22:b7:d0:20:9a:ef:
+ 59:0d:ca:0c:99:ad:27:da:3f:c8:f5:02:3b:e2:5f:
+ 98:6d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ F5:D3:EA:60:F9:5C:9E:DD:82:9D:DF:E4:71:43:A6:35:84:4D:07:46
+ X509v3 Authority Key Identifier:
+ 03:E4:E7:DA:0F:64:DB:13:1E:BD:85:AB:76:BC:29:CA:2F:A7:C7:4B
+ Signature Algorithm: sha256WithRSAEncryption
+ Signature Value:
+ 97:67:38:35:c2:da:ab:2b:22:5f:29:0a:cc:b3:a0:3c:a0:a5:
+ 5c:a3:75:ef:48:65:b5:45:3f:14:11:7b:95:09:78:e4:9a:b1:
+ db:10:23:33:7f:c8:37:89:1f:e4:be:51:48:8c:d4:1d:6b:25:
+ fd:ed:30:24:eb:20:f7:84:c4:49:d1:81:6d:f4:f5:54:71:ac:
+ a0:40:b1:c1:05:3a:fb:cb:79:5a:ee:ce:00:20:7c:31:f1:9a:
+ 16:1a:11:19:79:dd:49:8a:1b:91:e9:30:4f:33:72:2e:ee:71:
+ 5e:53:4a:59:9f:80:4b:cf:6a:da:c8:98:20:55:a1:45:c2:cc:
+ 86:05:45:49:df:72:48:54:88:02:91:aa:1b:e3:ed:b6:29:30:
+ a7:d3:46:d6:ab:58:c2:e5:1e:e6:8d:67:c0:2b:54:46:75:97:
+ f0:5a:f8:c2:04:8f:ce:31:50:28:de:37:dc:c6:8d:6b:24:f8:
+ fa:6c:ae:d9:bd:fc:87:22:dd:cc:c9:a0:c2:20:5f:13:ca:f8:
+ 32:96:66:14:1d:81:b7:36:4a:36:09:46:83:3d:80:07:9f:8b:
+ 64:e4:5c:42:93:55:c1:ea:f9:65:6d:10:b5:33:ee:90:27:11:
+ 3a:30:14:bf:a8:c8:ca:f0:fe:22:1b:b1:f0:76:b0:a4:32:3c:
+ 4a:52:af:1c
+-----BEGIN CERTIFICATE-----
+MIID7jCCAtagAwIBAgIBADANBgkqhkiG9w0BAQsFADB6MSMwIQYDVQQKDBpBcGFj
+aGUgU29mdHdhcmUgRm91bmRhdGlvbjEfMB0GA1UECwwWSHR0cENvbXBvbmVudHMg
+UHJvamVjdDEQMA4GA1UEAwwHVGVzdCBDQTEgMB4GCSqGSIb3DQEJARYRZGV2QGhj
+LmFwYWNoZS5vcmcwIBcNMjQxMDIwMTEzMTAwWhgPMjEyNDA5MjYxMTMxMDBaMHwx
+IzAhBgNVBAoMGkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMR8wHQYDVQQLDBZI
+dHRwQ29tcG9uZW50cyBQcm9qZWN0MRIwEAYDVQQDDAlsb2NhbGhvc3QxIDAeBgkq
+hkiG9w0BCQEWEWRldkBoYy5hcGFjaGUub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAms//SYaeOgsML0+JEIYRMNqBjJ4m93Kfx9COFme+Ckbu0p9n
+iTe4OIQW2GbByJqfZMYGjFf+DYNYTT3z1TWnieNeG8hItWY0OOyfrBoFgWYP1J+v
+qQy/IFHlHCFjpZU5hrDW652aKb6D3+9rCOTjLqMeSUyxKveJSUVMV8BHY0lfhYZy
+1wbR5hAWq2CjCX2bOeQTS2iOwzOgUM5FQVD2ONg+iejPzRUkP+o3pXI3+Htgztlr
+4e+8khNIepfISIdiS3wOb7+lt0d4Kl10klw6QIry4tg1VLITH9fIC8jZiVa9ctCE
+FMi2ebgit9Agmu9ZDcoMma0n2j/I9QI74l+YbQIDAQABo3sweTAJBgNVHRMEAjAA
+MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
+BgNVHQ4EFgQU9dPqYPlcnt2Cnd/kcUOmNYRNB0YwHwYDVR0jBBgwFoAUA+Tn2g9k
+2xMevYWrdrwpyi+nx0swDQYJKoZIhvcNAQELBQADggEBAJdnODXC2qsrIl8pCsyz
+oDygpVyjde9IZbVFPxQRe5UJeOSasdsQIzN/yDeJH+S+UUiM1B1rJf3tMCTrIPeE
+xEnRgW309VRxrKBAscEFOvvLeVruzgAgfDHxmhYaERl53UmKG5HpME8zci7ucV5T
+SlmfgEvPatrImCBVoUXCzIYFRUnfckhUiAKRqhvj7bYpMKfTRtarWMLlHuaNZ8Ar
+VEZ1l/Ba+MIEj84xUCjeN9zGjWsk+Ppsrtm9/Ici3czJoMIgXxPK+DKWZhQdgbc2
+SjYJRoM9gAefi2TkXEKTVcHq+WVtELUz7pAnETowFL+oyMrw/iIbsfB2sKQyPEpS
+rxw=
+-----END CERTIFICATE-----
diff --git a/httpcore5-testing/src/test/resources/docker/server-key.pem b/httpcore5-testing/src/test/resources/docker/server-key.pem
new file mode 100644
index 000000000..5871ecc91
--- /dev/null
+++ b/httpcore5-testing/src/test/resources/docker/server-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCaz/9Jhp46Cwwv
+T4kQhhEw2oGMnib3cp/H0I4WZ74KRu7Sn2eJN7g4hBbYZsHImp9kxgaMV/4Ng1hN
+PfPVNaeJ414byEi1ZjQ47J+sGgWBZg/Un6+pDL8gUeUcIWOllTmGsNbrnZopvoPf
+72sI5OMuox5JTLEq94lJRUxXwEdjSV+FhnLXBtHmEBarYKMJfZs55BNLaI7DM6BQ
+zkVBUPY42D6J6M/NFSQ/6jelcjf4e2DO2Wvh77ySE0h6l8hIh2JLfA5vv6W3R3gq
+XXSSXDpAivLi2DVUshMf18gLyNmJVr1y0IQUyLZ5uCK30CCa71kNygyZrSfaP8j1
+AjviX5htAgMBAAECggEABtpp+tduk141f2CoziZJMN2eD4YEGT8l60KvD4yEdqWr
+i9UKUHeQJvxTRegimvPxVhTdaa1kLd/1yDw+WjQNAxx2vYnGYjVbNCE8HkfBR6L8
+1L+Zl0UHrvFr0CzQNvPIqfmTwgwQ14PmCENBJzx5VsavdV+OQOXYBM+AW4AZCOrp
+yrRUVklecZwOF+lrkS+QgUuv5ZvufJq20PcuGhMGwFHaiOH+BHSfcPdqLKwxUjv0
+vpN36cXw4vELYUMpM7jd4B+0gsoJZXqFwTHBt/3wrqlOFWFqq+X+k9RcmWofP1kT
+yZGOKhexw6tuQB25ejnGJEIAcnCGT2fX7WMmPCoB0QKBgQDOv8OJwKiKLYNSv1Ln
+Ep6Q71xx2P7UcE6fF08mI+U8j1zAGnUVrVS2M9ysTyuZuiLtj6dBZ63ej4hdC+Q5
+elLo/r8KFR5k+i6KT6XfidpOcIxhIAIjHaXx/X/x1jOGl6kvr4CJqdWd9wrMMglx
+Wi3EmsVHmcjB14xtKX0WgXvJSQKBgQC/sPhWHOFAraM4Izemd+0GL4LkjpdtiWyQ
+TiFjvlSbYTgPyl3d8IQY5ubWpHfx7meZmWNj6lmiSBUIFV5/TNpuPbr5wD/KK/L6
+2cZevlPUYC4nSF+PTB9Hm5c6ocLbP6ddcD98cQz2efQZXixQhECoX8UDMxL3pIjb
+LdPrTalaBQKBgDiZ+1h9LCcYKrm+s12blVmsjiyE8c8LKBsZ8ItKjHm17fiRxbg3
+ideP/zwVOKSPdvx+tZWMYudpeDWxCbxKpuQuyfJisb2HWLJ497ppLSEIYwY8Exm2
+BjZn5l04/UY9ww3RCGmn21mxxnz8veUQgTMwBA6EJZgcAM/p6dr9e/wxAoGBAIQj
+AYyaq8th5jk0TZA66vBwn9HdWRTwvh1bPjj7YmcZRQPdg4cR3H0t7cHX7bafmFqR
+GaouSUtMVPMVh+ZIm+mSM+klVNOQKBYzOELm//JNuoLpqLWmy4kY/84y45cu8be/
+QIQPidf9iP5TpEh8YfWuzqe99T0v9gbgOEzjY/HhAoGBALr7Cwu3mvNLFug3n5UW
+1o+ImxlSI5LI1eqV9gG4pfKZbWzXuw8fXd8LLBxF3+WoE6eoSnnYVce8aUX3nDhd
+ZxUPattdKDOXmItHW+Oak2jZB6OSyTPM0uZWt3KfPDE+dPwnLmKuc7ZElo0rVwYW
+UiQnz6mwRNWK1Z/OGfkXqTxw
+-----END PRIVATE KEY-----
diff --git a/httpcore5-testing/src/test/resources/test-ca.jks b/httpcore5-testing/src/test/resources/test-ca.jks
new file mode 100644
index 000000000..fb70ffb15
Binary files /dev/null and b/httpcore5-testing/src/test/resources/test-ca.jks differ
diff --git a/test-CA/ca-cert.pem b/test-CA/ca-cert.pem
new file mode 100644
index 000000000..a40c7631b
--- /dev/null
+++ b/test-CA/ca-cert.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIIDyTCCArGgAwIBAgIJAO3mCIu9mboMMA0GCSqGSIb3DQEBCwUAMHoxIzAhBgNV
+BAoMGkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMR8wHQYDVQQLDBZIdHRwQ29t
+cG9uZW50cyBQcm9qZWN0MRAwDgYDVQQDDAdUZXN0IENBMSAwHgYJKoZIhvcNAQkB
+FhFkZXZAaGMuYXBhY2hlLm9yZzAgFw0xNDEwMTMxNTAxMjBaGA8yMjg4MDcyODE1
+MDEyMFowejEjMCEGA1UECgwaQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xHzAd
+BgNVBAsMFkh0dHBDb21wb25lbnRzIFByb2plY3QxEDAOBgNVBAMMB1Rlc3QgQ0Ex
+IDAeBgkqhkiG9w0BCQEWEWRldkBoYy5hcGFjaGUub3JnMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEApXhHtKRvAxbLI+f21zNe68dkVXAhSMIfHQJGb2en
+S1H8yE4HPIb4vPQ0U7fQCb7RXplm6cHExpof4cO3DmyqD5KeQk0TdM8XrhviDgwj
+Y0KQ/lgwGHR5CpYoZ6LYWaLSE/wt9dVu80UcK8a3hW9G0X/4b79fMO6HYDix+CI4
+b17sqZ4K0tWKA10Xe+2RJU8Y01pPBaPR/UsAn+a1pZ6f8BhL879oWHfLWKcgZOYP
+U4sYED0S8gs4/ED1zRj2/uHb313sHTl+OU4X5v+OvwBvbNBrl5qfMTZnRNxlOfRq
+UTJdcopsp2aNeqHiorSDOrHwMIJpxQ2XqHT2l9s8msXf4wIDAQABo1AwTjAdBgNV
+HQ4EFgQUA+Tn2g9k2xMevYWrdrwpyi+nx0swHwYDVR0jBBgwFoAUA+Tn2g9k2xMe
+vYWrdrwpyi+nx0swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFVEp
+8Nv6JoFY7oGgu6068fH/kq7A3SllqMpbv7dddI9fgwy352cBtg6PkYkGtEE037xs
+FQSYV1NiAkNWTJER+Q+kVbQrhuPNKZqh1g0sUKwv3X20BmgJ9hbU9klWZjdjujyd
+h9Ybjuntkn5XPp1zN6zHD0sQReEJnRlD6FT1axrQWpICzE4qoo8k64G+6/rqFywc
+oMc/Of3KCAHjtbWklEu97hjBvGC/nEP4/VhRrjWWSeGHv88LCyO/Yg6v3zrZHFLW
++KhsDCPyLxSSISFskLQfukiqf2lr87kQq/oF27sAr3sR3Jqh4qzflM2XLgjmZuRE
+OrHT6lvUemRyksA5qg==
+-----END CERTIFICATE-----
diff --git a/test-CA/ca-key.pem b/test-CA/ca-key.pem
new file mode 100644
index 000000000..a8a304241
--- /dev/null
+++ b/test-CA/ca-key.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIq0bLh96mWv4CAggA
+MBQGCCqGSIb3DQMHBAimZqUiELx13QSCBMgaLWrGFqveIzwQUsebS6FBdVq0lodz
+Vlekje8ycFDYSd21V9jPMwrSupZceeBQjCrpyLZ3oPkR+MvObmznev8XYcJzVCkF
+E9ApAaHZe248wWcu1/D7auHNG3GyZfvYS0c//Rs2OzMZfsUvX93RVullCRREvCYS
+qXhaO3ywFocndKRpSnkOBs2SRa0yc9POl4n4dwyKhsJUaMSmhPbJr9UBvCbXHZIA
+gLcSWzVon3EtZCSubMp9eo90G5MzIXEyPBTcIHwpyqRWTkaTUTq4R0c4/RTX+l7K
+OZuRIEeBEW6z009fSagymN/KEH3gUkg5pG6i1YWF63OVKTMGn+yQGWwYXwTyEGi5
+HZpD98wh3ycucmL93XLk+yYXQcTp1i+u4GaXNWGREQvNW6onCGeg6WWj1PrIsqoi
+TZ2pgQUJWPR1K3037hY0o9sakAkyYSyTPVvHOUcbf3+GhqGS1FsSNOxKRNpYm/3v
+Gf0SUN8BavPliK9NSU5JAbprr/hoL5o72dCX9DiOgwfW3HyD/gLh7sVyVBdAzTnE
+XFaYFnrb5QnqHbgWvaLbJUT5K7MW3OFLVConydYtYdaUl5z49OflhgnvYOPgTSUr
+k9c7exQjedAduPd8dXODh9l2g+QEXJoT+YYFEYHkQlsZgH1hCLXD1TmAeI4LMklb
+vPaGE8Ouj1pfbejdTNsqLfW0IiR/jZzEjRgqrueMf2VUjtqTZyPayc2rU4kOoKhv
+JzQ0wOFhgRztWJy2voRe+iYss3ToqZ7qLpjBfCTsxCJqbuaGeJWWSnOlDpSysgr+
+q4BvCzDcvf/0mKD2cQuJx/kynQMCcWB/VegRsQ24Y+3T7IU1w8ccmRfSZ93AwkAh
+MKJzKaVhD/gn9vUG/we18p7RMIc9pk1o2Z2Ru3mKjkO3QYRP6Y7yk0ah2JKrHIPf
+LWfPuHmtzHQXkY3RbVvxvwD/+qHm8ogXq52w8cpGhY5UwAEHrLLwypdBHccrAJjo
+bE13M/MrtTry/k8OMRqhhRzHUXBq6mLaWffCaP2SAVfJEez2iASvGJFvgy3bSkWY
+rwWMSfZKDkauwDMW5gpFrpeuqgD64LO72sN01riVDpaEyNODRCEEBGce+O+91R9K
+TLVgRYFsxClyZy1nynD66gkTepEm1yOgcdqV3651Os+TGm39jGYHy1k9mPz8ypqf
+8n8uw4nV3SbIwfpy4Z8onHixfc/Fugm7yQHW4dSuCpahyIJHom6Cq7SZfPuo9e3t
+8tqaxvK4U/dAXoimvN1eakH2FoVFIj3mk7OAKBgmDINH9GlzXPwRsTfiJSP4Xaod
+ouWIQLLeXQuuOc5VJd1Xex75o8ciSOomAS0uR4Fvk/2NkAm0EMddjZnuWLQaXPry
+JiUIgSx3w3yRq9RSQOxDRQpp2nP2roX7cyeGPzTmeujikExGTa3YBxuAShDLx5pt
+fpi0ol8H8ohDU4eV9pv96KRBG9e8sQf1zpGjeYLTFiN35IQxYJx3HTXp9/oFWkmA
+OdCEwggIKJ/RtgkWOWogTilQVA41p4XZr661fxoSE86sHXkZKn8IGnAKLFT46nWM
+IYVDalYUiSNZr+KbzmLIV3LmYE3mlqGI4vDvQtd9zQk/uatYBc2DetuTWPZHCEKS
+3Nk=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/test-CA/openssl.cnf b/test-CA/openssl.cnf
new file mode 100644
index 000000000..ab73071ba
--- /dev/null
+++ b/test-CA/openssl.cnf
@@ -0,0 +1,357 @@
+# 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 definition stops the following lines choking if HOME isn't
+# defined.
+HOME = .
+RANDFILE = $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file = $ENV::HOME/.oid
+oid_section = new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions =
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./test-CA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several ctificates with same subject.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/ca-cert.pem # The CA certificate
+serial = $dir/serial.txt # The current serial number
+crlnumber = $dir/crlnumber # the current crl number
+ # must be commented out to leave a V1 CRL
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/ca-key.pem# The private key
+RANDFILE = $dir/.rand # private random number file
+
+x509_extensions = usr_cert # The extentions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions = crl_ext
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = default # use public key default MD
+preserve = no # keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = optional
+stateOrProvinceName = optional
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 2048
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+x509_extensions = v3_ca # The extentions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default =
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = Some-State
+
+localityName = Locality Name (eg, city)
+
+0.organizationName = Organization Name (eg, company)
+0.organizationName_default = Apache Software Foundation
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+organizationalUnitName_default = HttpComponents Project
+
+commonName = Common Name (e.g. server FQDN or YOUR name)
+commonName_max = 64
+
+emailAddress = Email Address
+emailAddress_max = 64
+
+# SET-ex3 = SET extension number 3
+
+[ req_attributes ]
+challengePassword = A challenge password
+challengePassword_min = 4
+challengePassword_max = 20
+
+unstructuredName = An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType = server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment = "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1 # the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir = ./demoCA # TSA root directory
+serial = $dir/tsaserial # The current serial number (mandatory)
+crypto_device = builtin # OpenSSL engine to use for signing
+signer_cert = $dir/tsacert.pem # The TSA signing certificate
+ # (optional)
+certs = $dir/cacert.pem # Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
+
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = md5, sha1 # Acceptable message digests (mandatory)
+accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
+clock_precision_digits = 0 # number of digits after dot. (optional)
+ordering = yes # Is ordering defined for timestamps?
+ # (optional, default: no)
+tsa_name = yes # Must the TSA name be included in the reply?
+ # (optional, default: no)
+ess_cert_id_chain = no # Must the ESS cert id chain be included?
+ # (optional, default: no)