Redesign of test server APIs and integration test setup
This commit is contained in:
parent
336263da6c
commit
034cd65aa5
|
@ -36,10 +36,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.AuthenticationStrategy;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
|
@ -52,73 +50,44 @@ import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
import org.apache.hc.client5.http.config.RequestConfig;
|
||||||
import org.apache.hc.client5.http.impl.DefaultAuthenticationStrategy;
|
import org.apache.hc.client5.http.impl.DefaultAuthenticationStrategy;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
|
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
|
||||||
import org.apache.hc.client5.http.impl.auth.BasicScheme;
|
import org.apache.hc.client5.http.impl.auth.BasicScheme;
|
||||||
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||||
import org.apache.hc.client5.testing.auth.BearerAuthenticationHandler;
|
import org.apache.hc.client5.testing.auth.BearerAuthenticationHandler;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.ProtocolException;
|
import org.apache.hc.core5.http.ProtocolException;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Lookup;
|
|
||||||
import org.apache.hc.core5.http.config.Registry;
|
import org.apache.hc.core5.http.config.Registry;
|
||||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http.support.BasicResponseBuilder;
|
import org.apache.hc.core5.http.support.BasicResponseBuilder;
|
||||||
import org.apache.hc.core5.net.URIAuthority;
|
import org.apache.hc.core5.net.URIAuthority;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
public abstract class AbstractHttpAsyncClientAuthenticationTest extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public AbstractHttpAsyncClientAuthenticationTest(final URIScheme scheme) {
|
public AbstractHttpAsyncClientAuthenticationTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel) {
|
||||||
super(scheme);
|
super(scheme, clientProtocolLevel, serverProtocolLevel);
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception;
|
|
||||||
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(requestHandler -> new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")));
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TestClientBuilder {
|
|
||||||
|
|
||||||
TestClientBuilder setDefaultAuthSchemeRegistry(Lookup<AuthSchemeFactory> authSchemeRegistry);
|
|
||||||
|
|
||||||
TestClientBuilder setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy);
|
|
||||||
|
|
||||||
TestClientBuilder addResponseInterceptor(HttpResponseInterceptor responseInterceptor);
|
|
||||||
|
|
||||||
TestClientBuilder addRequestInterceptor(HttpRequestInterceptor requestInterceptor);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected T startClientCustom(final Consumer<TestClientBuilder> clientCustomizer) throws Exception;
|
|
||||||
|
|
||||||
T startClient() throws Exception {
|
|
||||||
return startClientCustom(c -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationNoCreds() throws Exception {
|
public void testBasicAuthenticationNoCreds() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -138,11 +107,10 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailure() throws Exception {
|
public void testBasicAuthenticationFailure() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -164,11 +132,10 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccess() throws Exception {
|
public void testBasicAuthenticationSuccess() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -191,11 +158,10 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationWithEntitySuccess() throws Exception {
|
public void testBasicAuthenticationWithEntitySuccess() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -218,11 +184,10 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationExpectationFailure() throws Exception {
|
public void testBasicAuthenticationExpectationFailure() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -244,11 +209,10 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationExpectationSuccess() throws Exception {
|
public void testBasicAuthenticationExpectationSuccess() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -272,12 +236,12 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
final T client = startClientCustom(builder -> builder.setTargetAuthenticationStrategy(authStrategy));
|
configureClient(builder -> builder.setTargetAuthenticationStrategy(authStrategy));
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
||||||
|
@ -299,17 +263,17 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
final T client = startClientCustom(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setTargetAuthenticationStrategy(authStrategy)
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
.addResponseInterceptor((response, entity, context)
|
.addResponseInterceptorFirst((response, entity, context)
|
||||||
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(target, "test", "test".toCharArray())
|
.add(target, "test", "test".toCharArray())
|
||||||
|
@ -364,11 +328,10 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRequestFailure() throws Exception {
|
public void testAuthenticationUserinfoInRequestFailure() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
final HttpHost target = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
configureServer(bootstrap -> bootstrap.register("*", AsyncEchoHandler::new));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
|
@ -396,17 +359,18 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
|
final HttpHost target = startServer();
|
||||||
|
configureServer(bootstrap -> bootstrap
|
||||||
|
.register("*", AsyncEchoHandler::new)
|
||||||
|
.setExchangeHandlerDecorator(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}));
|
||||||
server.register("*", AsyncEchoHandler::new);
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -425,7 +389,9 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final T client = startClientCustom(builder -> builder.setDefaultAuthSchemeRegistry(authSchemeRegistry));
|
configureClient(builder -> builder.setDefaultAuthSchemeRegistry(authSchemeRegistry));
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setTargetPreferredAuthSchemes(Collections.singletonList("MyBasic"))
|
.setTargetPreferredAuthSchemes(Collections.singletonList("MyBasic"))
|
||||||
|
@ -448,18 +414,19 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationFallback() throws Exception {
|
public void testAuthenticationFallback() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
final HttpHost target = startServer();
|
||||||
|
configureServer(bootstrap -> bootstrap
|
||||||
|
.register("*", AsyncEchoHandler::new)
|
||||||
|
.setExchangeHandlerDecorator(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}));
|
||||||
server.register("*", AsyncEchoHandler::new);
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -489,15 +456,17 @@ public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends Closea
|
||||||
buf.append(CHARS.charAt(secureRandom.nextInt(CHARS.length() - 1)));
|
buf.append(CHARS.charAt(secureRandom.nextInt(CHARS.length() - 1)));
|
||||||
}
|
}
|
||||||
final String token = buf.toString();
|
final String token = buf.toString();
|
||||||
final H2TestServer server = startServer(requestHandler ->
|
|
||||||
new AuthenticatingAsyncDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new BearerAuthenticationHandler(),
|
|
||||||
new BasicTestAuthenticator(token, "test realm")));
|
|
||||||
server.register("*", AsyncEchoHandler::new);
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final HttpHost target = startServer();
|
||||||
|
configureServer(bootstrap -> bootstrap
|
||||||
|
.register("*", AsyncEchoHandler::new)
|
||||||
|
.setExchangeHandlerDecorator(requestHandler ->
|
||||||
|
new AuthenticatingAsyncDecorator(
|
||||||
|
requestHandler,
|
||||||
|
new BearerAuthenticationHandler(),
|
||||||
|
new BasicTestAuthenticator(token, "test realm"))));
|
||||||
|
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
final HttpClientContext context1 = HttpClientContext.create();
|
final HttpClientContext context1 = HttpClientContext.create();
|
||||||
|
|
|
@ -40,8 +40,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
@ -53,26 +55,22 @@ import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
|
||||||
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
|
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
public abstract class AbstractHttpAsyncFundamentalsTest extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
protected AbstractHttpAsyncFundamentalsTest(final URIScheme scheme) {
|
protected AbstractHttpAsyncFundamentalsTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel) {
|
||||||
super(scheme);
|
super(scheme, clientProtocolLevel, serverProtocolLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected H2TestServer startServer() throws Exception;
|
|
||||||
|
|
||||||
abstract protected T startClient() throws Exception;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSequentialGetRequests() throws Exception {
|
public void testSequentialGetRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
@ -90,10 +88,9 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSequentialHeadRequests() throws Exception {
|
public void testSequentialHeadRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
final TestAsyncClient client = startClient();
|
||||||
final T client = startClient();
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.head()
|
SimpleRequestBuilder.head()
|
||||||
|
@ -110,10 +107,9 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSequentialPostRequests() throws Exception {
|
public void testSequentialPostRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/echo/*", AsyncEchoHandler::new));
|
||||||
server.register("/echo/*", AsyncEchoHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
final TestAsyncClient client = startClient();
|
||||||
final T client = startClient();
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final byte[] b1 = new byte[1024];
|
final byte[] b1 = new byte[1024];
|
||||||
final Random rnd = new Random(System.currentTimeMillis());
|
final Random rnd = new Random(System.currentTimeMillis());
|
||||||
|
@ -133,10 +129,9 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConcurrentPostRequests() throws Exception {
|
public void testConcurrentPostRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/echo/*", AsyncEchoHandler::new));
|
||||||
server.register("/echo/*", AsyncEchoHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
final TestAsyncClient client = startClient();
|
||||||
final T client = startClient();
|
|
||||||
final byte[] b1 = new byte[1024];
|
final byte[] b1 = new byte[1024];
|
||||||
final Random rnd = new Random(System.currentTimeMillis());
|
final Random rnd = new Random(System.currentTimeMillis());
|
||||||
rnd.nextBytes(b1);
|
rnd.nextBytes(b1);
|
||||||
|
@ -165,10 +160,9 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestExecutionFromCallback() throws Exception {
|
public void testRequestExecutionFromCallback() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
final TestAsyncClient client = startClient();
|
||||||
final T client = startClient();
|
|
||||||
final int requestNum = 50;
|
final int requestNum = 50;
|
||||||
final AtomicInteger count = new AtomicInteger(requestNum);
|
final AtomicInteger count = new AtomicInteger(requestNum);
|
||||||
final Queue<SimpleHttpResponse> resultQueue = new ConcurrentLinkedQueue<>();
|
final Queue<SimpleHttpResponse> resultQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
@ -233,10 +227,9 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadRequest() throws Exception {
|
public void testBadRequest() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
final TestAsyncClient client = startClient();
|
||||||
final T client = startClient();
|
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
|
|
|
@ -41,13 +41,15 @@ import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
import org.apache.hc.client5.http.config.RequestConfig;
|
||||||
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
|
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncServer;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncServerBootstrap;
|
||||||
import org.apache.hc.client5.testing.redirect.Redirect;
|
import org.apache.hc.client5.testing.redirect.Redirect;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
|
@ -55,48 +57,31 @@ import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
import org.apache.hc.core5.http.HttpRequest;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
|
||||||
import org.apache.hc.core5.http.ProtocolException;
|
import org.apache.hc.core5.http.ProtocolException;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
public abstract class AbstractHttpAsyncRedirectsTest extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
private final HttpVersion version;
|
public AbstractHttpAsyncRedirectsTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel) {
|
||||||
|
super(scheme, clientProtocolLevel, serverProtocolLevel);
|
||||||
public AbstractHttpAsyncRedirectsTest(final URIScheme scheme, final HttpVersion version) {
|
|
||||||
super(scheme);
|
|
||||||
this.version = version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception;
|
|
||||||
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected T startClient() throws Exception;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final TestAsyncClient client = startClient();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -115,13 +100,14 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301() throws Exception {
|
public void testBasicRedirect301() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
exchangeHandler,
|
||||||
final HttpHost target = targetHost();
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -141,13 +127,14 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302() throws Exception {
|
public void testBasicRedirect302() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
exchangeHandler,
|
||||||
final HttpHost target = targetHost();
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -167,19 +154,20 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302NoLocation() throws Exception {
|
public void testBasicRedirect302NoLocation() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
requestUri -> {
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
final String path = requestUri.getPath();
|
exchangeHandler,
|
||||||
if (path.startsWith("/oldlocation")) {
|
requestUri -> {
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
final String path = requestUri.getPath();
|
||||||
}
|
if (path.startsWith("/oldlocation")) {
|
||||||
return null;
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
||||||
}));
|
}
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
return null;
|
||||||
final HttpHost target = targetHost();
|
})));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -198,13 +186,15 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect303() throws Exception {
|
public void testBasicRedirect303() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
exchangeHandler,
|
||||||
final HttpHost target = targetHost();
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER))));
|
||||||
|
|
||||||
final T client = startClient();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -224,19 +214,19 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect304() throws Exception {
|
public void testBasicRedirect304() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
||||||
final HttpCoreContext context) throws HttpException {
|
final HttpCoreContext context) throws HttpException {
|
||||||
return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
|
return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -255,19 +245,19 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect305() throws Exception {
|
public void testBasicRedirect305() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
||||||
final HttpCoreContext context) throws HttpException {
|
final HttpCoreContext context) throws HttpException {
|
||||||
return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
|
return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -286,13 +276,14 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect307() throws Exception {
|
public void testBasicRedirect307() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
exchangeHandler,
|
||||||
final HttpHost target = targetHost();
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -312,14 +303,15 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxRedirectCheck() throws Exception {
|
public void testMaxRedirectCheck() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
exchangeHandler,
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
final HttpHost target = targetHost();
|
HttpStatus.SC_MOVED_TEMPORARILY))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(true)
|
.setCircularRedirectsAllowed(true)
|
||||||
|
@ -337,14 +329,15 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCircularRedirect() throws Exception {
|
public void testCircularRedirect() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
exchangeHandler,
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
final HttpHost target = targetHost();
|
HttpStatus.SC_MOVED_TEMPORARILY))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(false)
|
.setCircularRedirectsAllowed(false)
|
||||||
|
@ -363,14 +356,14 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirect() throws Exception {
|
public void testPostRedirect() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/echo/*", AsyncEchoHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.register("/echo/*", AsyncEchoHandler::new);
|
final TestAsyncClient client = startClient();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -391,14 +384,14 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirectSeeOther() throws Exception {
|
public void testPostRedirectSeeOther() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/echo/*", AsyncEchoHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.register("/echo/*", AsyncEchoHandler::new);
|
final TestAsyncClient client = startClient();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -419,21 +412,21 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect() throws Exception {
|
public void testRelativeRedirect() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
requestUri -> {
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
final String path = requestUri.getPath();
|
exchangeHandler,
|
||||||
if (path.startsWith("/oldlocation")) {
|
requestUri -> {
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
final String path = requestUri.getPath();
|
||||||
|
if (path.startsWith("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
})));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final TestAsyncClient client = startClient();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -454,21 +447,21 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect2() throws Exception {
|
public void testRelativeRedirect2() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
requestUri -> {
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
final String path = requestUri.getPath();
|
exchangeHandler,
|
||||||
if (path.equals("/random/oldlocation")) {
|
requestUri -> {
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/random/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
})));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final TestAsyncClient client = startClient();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -489,20 +482,21 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectBogusRedirectLocation() throws Exception {
|
public void testRejectBogusRedirectLocation() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
requestUri -> {
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
final String path = requestUri.getPath();
|
exchangeHandler,
|
||||||
if (path.equals("/oldlocation/")) {
|
requestUri -> {
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/oldlocation/")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
})));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -517,20 +511,20 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
requestUri -> {
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
final String path = requestUri.getPath();
|
exchangeHandler,
|
||||||
if (path.equals("/oldlocation/")) {
|
requestUri -> {
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/oldlocation/")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
}
|
final TestAsyncClient client = startClient();
|
||||||
return null;
|
|
||||||
}));
|
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
|
||||||
|
|
||||||
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
@ -545,16 +539,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedirectWithCookie() throws Exception {
|
public void testRedirectWithCookie() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCookieStore(cookieStore);
|
context.setCookieStore(cookieStore);
|
||||||
|
|
||||||
|
@ -584,38 +578,34 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
@Test
|
@Test
|
||||||
public void testCrossSiteRedirect() throws Exception {
|
public void testCrossSiteRedirect() throws Exception {
|
||||||
final URIScheme scheme = scheme();
|
final URIScheme scheme = scheme();
|
||||||
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
|
final TestAsyncServer secondServer = new TestAsyncServerBootstrap(scheme(), getServerProtocolLevel())
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
|
.build();
|
||||||
try {
|
try {
|
||||||
secondServer.register("/random/*", AsyncRandomHandler::new);
|
final InetSocketAddress address2 = secondServer.start();
|
||||||
final InetSocketAddress address2;
|
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
|
||||||
address2 = secondServer.start(H2Config.DEFAULT);
|
|
||||||
} else {
|
|
||||||
address2 = secondServer.start(Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
|
final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
|
||||||
|
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
requestUri -> {
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
final String path = requestUri.getPath();
|
exchangeHandler,
|
||||||
if (path.equals("/oldlocation")) {
|
requestUri -> {
|
||||||
final URI location = new URIBuilder(requestUri)
|
final String path = requestUri.getPath();
|
||||||
.setHttpHost(redirectTarget)
|
if (path.equals("/oldlocation")) {
|
||||||
.setPath("/random/100")
|
final URI location = new URIBuilder(requestUri)
|
||||||
.build();
|
.setHttpHost(redirectTarget)
|
||||||
return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
|
.setPath("/random/100")
|
||||||
}
|
.build();
|
||||||
return null;
|
return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
|
||||||
}));
|
}
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final TestAsyncClient client = startClient();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final T client = startClient();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
|
|
|
@ -51,8 +51,10 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.core.Flowable;
|
import io.reactivex.rxjava3.core.Flowable;
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
@ -64,7 +66,6 @@ import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder;
|
||||||
import org.apache.hc.core5.reactive.ReactiveEntityProducer;
|
import org.apache.hc.core5.reactive.ReactiveEntityProducer;
|
||||||
import org.apache.hc.core5.reactive.ReactiveResponseConsumer;
|
import org.apache.hc.core5.reactive.ReactiveResponseConsumer;
|
||||||
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.testing.reactive.Reactive3TestUtils;
|
import org.apache.hc.core5.testing.reactive.Reactive3TestUtils;
|
||||||
import org.apache.hc.core5.testing.reactive.Reactive3TestUtils.StreamDescription;
|
import org.apache.hc.core5.testing.reactive.Reactive3TestUtils.StreamDescription;
|
||||||
import org.apache.hc.core5.testing.reactive.ReactiveEchoProcessor;
|
import org.apache.hc.core5.testing.reactive.ReactiveEchoProcessor;
|
||||||
|
@ -76,24 +77,20 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.Timeout;
|
import org.junit.jupiter.api.Timeout;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
|
|
||||||
public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
public abstract class AbstractHttpReactiveFundamentalsTest extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public AbstractHttpReactiveFundamentalsTest(final URIScheme scheme) {
|
public AbstractHttpReactiveFundamentalsTest(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel) {
|
||||||
super(scheme);
|
super(scheme, clientProtocolLevel, serverProtocolLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected H2TestServer startServer() throws Exception;
|
|
||||||
|
|
||||||
abstract protected T startClient() throws Exception;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
@Timeout(value = 60_000, unit = MILLISECONDS)
|
||||||
public void testSequentialGetRequests() throws Exception {
|
public void testSequentialGetRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.register("/random/*", () ->
|
.register("/random/*", () -> new ReactiveServerExchangeHandler(new ReactiveRandomProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
||||||
|
|
||||||
|
@ -112,11 +109,11 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 2000, unit = MILLISECONDS)
|
@Timeout(value = 2000, unit = MILLISECONDS)
|
||||||
public void testSequentialHeadRequests() throws Exception {
|
public void testSequentialHeadRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", () ->
|
||||||
server.register("/random/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
||||||
|
|
||||||
|
@ -134,11 +131,11 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
@Timeout(value = 60_000, unit = MILLISECONDS)
|
||||||
public void testSequentialPostRequests() throws Exception {
|
public void testSequentialPostRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/echo/*", () ->
|
||||||
server.register("/echo/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final byte[] b1 = new byte[1024];
|
final byte[] b1 = new byte[1024];
|
||||||
final Random rnd = new Random(System.currentTimeMillis());
|
final Random rnd = new Random(System.currentTimeMillis());
|
||||||
|
@ -164,11 +161,11 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
@Timeout(value = 60_000, unit = MILLISECONDS)
|
||||||
public void testConcurrentPostRequests() throws Exception {
|
public void testConcurrentPostRequests() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/echo/*", () ->
|
||||||
server.register("/echo/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final int reqCount = 500;
|
final int reqCount = 500;
|
||||||
final int maxSize = 128 * 1024;
|
final int maxSize = 128 * 1024;
|
||||||
|
@ -213,11 +210,11 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
@Timeout(value = 60_000, unit = MILLISECONDS)
|
||||||
public void testRequestExecutionFromCallback() throws Exception {
|
public void testRequestExecutionFromCallback() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", () ->
|
||||||
server.register("/random/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
final int requestNum = 50;
|
final int requestNum = 50;
|
||||||
final AtomicInteger count = new AtomicInteger(requestNum);
|
final AtomicInteger count = new AtomicInteger(requestNum);
|
||||||
final Queue<Message<HttpResponse, Publisher<ByteBuffer>>> resultQueue = new ConcurrentLinkedQueue<>();
|
final Queue<Message<HttpResponse, Publisher<ByteBuffer>>> resultQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
@ -275,11 +272,11 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadRequest() throws Exception {
|
public void testBadRequest() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", () ->
|
||||||
server.register("/random/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
final T client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
final AsyncRequestProducer request = AsyncRequestBuilder.get(target + "/random/boom").build();
|
final AsyncRequestProducer request = AsyncRequestBuilder.get(target + "/random/boom").build();
|
||||||
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
||||||
|
|
||||||
|
|
|
@ -27,24 +27,18 @@
|
||||||
|
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
import org.apache.hc.client5.http.impl.async.H2AsyncClientBuilder;
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalH2AsyncClient;
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClientBuilder;
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
|
||||||
import org.apache.hc.client5.testing.async.extension.TestAsyncResources;
|
import org.apache.hc.client5.testing.async.extension.TestAsyncResources;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.client5.testing.async.extension.TestAsyncServer;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncServerBootstrap;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
@ -55,68 +49,40 @@ public abstract class AbstractIntegrationTestBase {
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
private final TestAsyncResources testResources;
|
private final TestAsyncResources testResources;
|
||||||
|
|
||||||
protected AbstractIntegrationTestBase(final URIScheme scheme) {
|
protected AbstractIntegrationTestBase(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel) {
|
||||||
this.testResources = new TestAsyncResources(scheme, TIMEOUT);
|
this.testResources = new TestAsyncResources(scheme, clientProtocolLevel, serverProtocolLevel, TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URIScheme scheme() {
|
public URIScheme scheme() {
|
||||||
return testResources.scheme();
|
return testResources.scheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
public H2TestServer startServer(
|
public ServerProtocolLevel getServerProtocolLevel() {
|
||||||
final H2Config h2Config,
|
return testResources.getServerProtocolLevel();
|
||||||
final HttpProcessor httpProcessor,
|
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
return testResources.startServer(h2Config, httpProcessor, exchangeHandlerDecorator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public H2TestServer startServer(
|
public ClientProtocolLevel getClientProtocolLevel() {
|
||||||
final Http1Config http1Config,
|
return testResources.getClientProtocolLevel();
|
||||||
final HttpProcessor httpProcessor,
|
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
return testResources.startServer(http1Config, httpProcessor, exchangeHandlerDecorator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
public void configureServer(final Consumer<TestAsyncServerBootstrap> serverCustomizer) {
|
||||||
return testResources.targetHost();
|
testResources.configureServer(serverCustomizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CloseableHttpAsyncClient startClient(
|
public HttpHost startServer() throws Exception {
|
||||||
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer,
|
final TestAsyncServer server = testResources.server();
|
||||||
final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
|
final InetSocketAddress inetSocketAddress = server.start();
|
||||||
return testResources.startClient(connManagerCustomizer, clientCustomizer);
|
return new HttpHost(testResources.scheme().id, "localhost", inetSocketAddress.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
public CloseableHttpAsyncClient startClient(
|
public void configureClient(final Consumer<TestAsyncClientBuilder> clientCustomizer) {
|
||||||
final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
|
testResources.configureClient(clientCustomizer);
|
||||||
return testResources.startClient(clientCustomizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PoolingAsyncClientConnectionManager connManager() {
|
public TestAsyncClient startClient() throws Exception {
|
||||||
return testResources.connManager();
|
final TestAsyncClient client = testResources.client();
|
||||||
}
|
client.start();
|
||||||
|
return client;
|
||||||
public CloseableHttpAsyncClient startH2Client(
|
|
||||||
final Consumer<H2AsyncClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
return testResources.startH2Client(clientCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinimalHttpAsyncClient startMinimalClient(
|
|
||||||
final Http1Config http1Config,
|
|
||||||
final H2Config h2Config,
|
|
||||||
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer) throws Exception {
|
|
||||||
return testResources.startMinimalClient(http1Config, h2Config, connManagerCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinimalHttpAsyncClient startMinimalH2Client(
|
|
||||||
final Http1Config http1Config,
|
|
||||||
final H2Config h2Config,
|
|
||||||
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer) throws Exception {
|
|
||||||
return testResources.startMinimalClient(http1Config, h2Config, connManagerCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinimalH2AsyncClient startMinimalH2Client(final H2Config h2Config) throws Exception {
|
|
||||||
return testResources.startMinimalH2Client(h2Config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,44 +173,44 @@ public class HttpIntegrationTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
// @Nested
|
||||||
@DisplayName("Client authentication (HTTP/1.1)")
|
// @DisplayName("Client authentication (HTTP/1.1)")
|
||||||
public class AuthenticationHttp1 extends TestHttp1ClientAuthentication {
|
// public class AuthenticationHttp1 extends TestHttp1ClientAuthentication {
|
||||||
|
//
|
||||||
public AuthenticationHttp1() throws Exception {
|
// public AuthenticationHttp1() throws Exception {
|
||||||
super(URIScheme.HTTP);
|
// super(URIScheme.HTTP);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Nested
|
// @Nested
|
||||||
@DisplayName("Client authentication (HTTP/1.1, TLS)")
|
// @DisplayName("Client authentication (HTTP/1.1, TLS)")
|
||||||
public class AuthenticationHttp1Tls extends TestHttp1ClientAuthentication {
|
// public class AuthenticationHttp1Tls extends TestHttp1ClientAuthentication {
|
||||||
|
//
|
||||||
public AuthenticationHttp1Tls() throws Exception {
|
// public AuthenticationHttp1Tls() throws Exception {
|
||||||
super(URIScheme.HTTPS);
|
// super(URIScheme.HTTPS);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("Client authentication (HTTP/2)")
|
|
||||||
public class AuthenticationH2 extends TestH2ClientAuthentication {
|
|
||||||
|
|
||||||
public AuthenticationH2() throws Exception {
|
|
||||||
super(URIScheme.HTTP);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("Client authentication (HTTP/2, TLS)")
|
|
||||||
public class AuthenticationH2Tls extends TestH2ClientAuthentication {
|
|
||||||
|
|
||||||
public AuthenticationH2Tls() throws Exception {
|
|
||||||
super(URIScheme.HTTPS);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// @Nested
|
||||||
|
// @DisplayName("Client authentication (HTTP/2)")
|
||||||
|
// public class AuthenticationH2 extends TestH2ClientAuthentication {
|
||||||
|
//
|
||||||
|
// public AuthenticationH2() throws Exception {
|
||||||
|
// super(URIScheme.HTTP);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Nested
|
||||||
|
// @DisplayName("Client authentication (HTTP/2, TLS)")
|
||||||
|
// public class AuthenticationH2Tls extends TestH2ClientAuthentication {
|
||||||
|
//
|
||||||
|
// public AuthenticationH2Tls() throws Exception {
|
||||||
|
// super(URIScheme.HTTPS);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
}
|
}
|
|
@ -26,25 +26,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
|
|
||||||
public abstract class TestH2Async extends AbstractHttpAsyncFundamentalsTest<CloseableHttpAsyncClient> {
|
public abstract class TestH2Async extends AbstractHttpAsyncFundamentalsTest {
|
||||||
|
|
||||||
public TestH2Async(final URIScheme scheme) {
|
public TestH2Async(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.H2_ONLY, ServerProtocolLevel.H2_ONLY);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(H2Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startH2Client(b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,25 +26,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalH2AsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
|
|
||||||
public abstract class TestH2AsyncMinimal extends AbstractHttpAsyncFundamentalsTest<MinimalH2AsyncClient> {
|
public abstract class TestH2AsyncMinimal extends AbstractHttpAsyncFundamentalsTest {
|
||||||
|
|
||||||
public TestH2AsyncMinimal(final URIScheme scheme) {
|
public TestH2AsyncMinimal(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.MINIMAL_H2_ONLY, ServerProtocolLevel.H2_ONLY);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(H2Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MinimalH2AsyncClient startClient() throws Exception {
|
|
||||||
return startMinimalH2Client(H2Config.DEFAULT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,28 +26,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
|
|
||||||
public abstract class TestH2AsyncRedirect extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
|
public abstract class TestH2AsyncRedirect extends AbstractHttpAsyncRedirectsTest {
|
||||||
|
|
||||||
public TestH2AsyncRedirect(final URIScheme scheme) {
|
public TestH2AsyncRedirect(final URIScheme scheme) {
|
||||||
super(scheme, HttpVersion.HTTP_2);
|
super(scheme, ClientProtocolLevel.H2_ONLY, ServerProtocolLevel.H2_ONLY);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
return startServer(H2Config.DEFAULT, null, exchangeHandlerDecorator);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startH2Client(b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,71 +26,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.client5.http.AuthenticationStrategy;
|
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.async.H2AsyncClientBuilder;
|
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
|
||||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Lookup;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
|
|
||||||
public abstract class TestH2ClientAuthentication extends AbstractHttpAsyncClientAuthenticationTest<CloseableHttpAsyncClient> {
|
public abstract class TestH2ClientAuthentication extends AbstractHttpAsyncClientAuthenticationTest {
|
||||||
|
|
||||||
public TestH2ClientAuthentication(final URIScheme scheme) {
|
public TestH2ClientAuthentication(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.H2_ONLY, ServerProtocolLevel.H2_ONLY);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
return startServer(H2Config.DEFAULT, null, exchangeHandlerDecorator);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClientCustom(final Consumer<TestClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
|
|
||||||
return startH2Client(new Consumer<H2AsyncClientBuilder>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(final H2AsyncClientBuilder builder) {
|
|
||||||
|
|
||||||
clientCustomizer.accept(new TestClientBuilder() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder setDefaultAuthSchemeRegistry(final Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
|
||||||
builder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
|
||||||
builder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder addResponseInterceptor(final HttpResponseInterceptor responseInterceptor) {
|
|
||||||
builder.addResponseInterceptorLast(responseInterceptor);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder addRequestInterceptor(final HttpRequestInterceptor requestInterceptor) {
|
|
||||||
builder.addRequestInterceptorFirst(requestInterceptor);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,25 +26,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
|
|
||||||
public abstract class TestH2Reactive extends AbstractHttpReactiveFundamentalsTest<CloseableHttpAsyncClient> {
|
public abstract class TestH2Reactive extends AbstractHttpReactiveFundamentalsTest {
|
||||||
|
|
||||||
public TestH2Reactive(final URIScheme scheme) {
|
public TestH2Reactive(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.H2_ONLY, ServerProtocolLevel.H2_ONLY);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(H2Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startH2Client(b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,26 +26,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalH2AsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
|
|
||||||
public abstract class TestH2ReactiveMinimal extends AbstractHttpReactiveFundamentalsTest<MinimalH2AsyncClient> {
|
public abstract class TestH2ReactiveMinimal extends AbstractHttpReactiveFundamentalsTest {
|
||||||
|
|
||||||
public TestH2ReactiveMinimal(final URIScheme scheme) {
|
public TestH2ReactiveMinimal(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.MINIMAL_H2_ONLY, ServerProtocolLevel.H2_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(H2Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MinimalH2AsyncClient startClient() throws Exception {
|
|
||||||
return startMinimalH2Client(H2Config.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,42 +40,33 @@ import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.http.HeaderElements;
|
import org.apache.hc.core5.http.HeaderElements;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
public abstract class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableHttpAsyncClient> {
|
public abstract class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest {
|
||||||
|
|
||||||
public TestHttp1Async(final URIScheme scheme) {
|
public TestHttp1Async(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(Http1Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startClient(b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest(name = "{displayName}; concurrent connections: {0}")
|
@ParameterizedTest(name = "{displayName}; concurrent connections: {0}")
|
||||||
@ValueSource(ints = {5, 1, 20})
|
@ValueSource(ints = {5, 1, 20})
|
||||||
public void testSequentialGetRequestsCloseConnection(final int concurrentConns) throws Exception {
|
public void testSequentialGetRequestsCloseConnection(final int concurrentConns) throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
final PoolingAsyncClientConnectionManager connManager = connManager();
|
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = client.getConnectionManager();
|
||||||
connManager.setDefaultMaxPerRoute(concurrentConns);
|
connManager.setDefaultMaxPerRoute(concurrentConns);
|
||||||
connManager.setMaxTotal(100);
|
connManager.setMaxTotal(100);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
|
@ -96,12 +87,12 @@ public abstract class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<C
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSharedPool() throws Exception {
|
public void testSharedPool() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
final PoolingAsyncClientConnectionManager connManager = connManager();
|
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = client.getConnectionManager();
|
||||||
final Future<SimpleHttpResponse> future1 = client.execute(
|
final Future<SimpleHttpResponse> future1 = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
|
@ -148,12 +139,11 @@ public abstract class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<C
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestCancellation() throws Exception {
|
public void testRequestCancellation() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
final PoolingAsyncClientConnectionManager connManager = connManager();
|
final PoolingAsyncClientConnectionManager connManager = client.getConnectionManager();
|
||||||
connManager.setDefaultMaxPerRoute(1);
|
connManager.setDefaultMaxPerRoute(1);
|
||||||
connManager.setMaxTotal(1);
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
|
|
|
@ -36,49 +36,34 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.Message;
|
import org.apache.hc.core5.http.Message;
|
||||||
import org.apache.hc.core5.http.Method;
|
import org.apache.hc.core5.http.Method;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||||
import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
|
import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
|
||||||
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
|
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public abstract class TestHttp1AsyncMinimal extends AbstractHttpAsyncFundamentalsTest<MinimalHttpAsyncClient> {
|
public abstract class TestHttp1AsyncMinimal extends AbstractHttpAsyncFundamentalsTest {
|
||||||
|
|
||||||
public TestHttp1AsyncMinimal(final URIScheme scheme) {
|
public TestHttp1AsyncMinimal(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.MINIMAL, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(Http1Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MinimalHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startMinimalClient(
|
|
||||||
Http1Config.DEFAULT,
|
|
||||||
H2Config.DEFAULT,
|
|
||||||
b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/echo/*", AsyncEchoHandler::new));
|
||||||
server.register("/echo/*", AsyncEchoHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final MinimalHttpAsyncClient client = startClient();
|
final MinimalHttpAsyncClient client = startClient().getImplementation();
|
||||||
|
|
||||||
final byte[] b1 = new byte[1024];
|
final byte[] b1 = new byte[1024];
|
||||||
final Random rnd = new Random(System.currentTimeMillis());
|
final Random rnd = new Random(System.currentTimeMillis());
|
||||||
|
|
|
@ -32,55 +32,43 @@ import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.client5.testing.redirect.Redirect;
|
import org.apache.hc.client5.testing.redirect.Redirect;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
import org.apache.hc.core5.http.HttpRequest;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.message.BasicHeader;
|
import org.apache.hc.core5.http.message.BasicHeader;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirection test cases.
|
* Redirection test cases.
|
||||||
*/
|
*/
|
||||||
public abstract class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
|
public abstract class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest {
|
||||||
|
|
||||||
public TestHttp1AsyncRedirects(final URIScheme scheme) {
|
public TestHttp1AsyncRedirects(final URIScheme scheme) {
|
||||||
super(scheme, HttpVersion.HTTP_1_1);
|
super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
return startServer(Http1Config.DEFAULT, null, exchangeHandlerDecorator);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startClient(b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
Redirect.ConnControl.CLOSE)));
|
exchangeHandler,
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
||||||
final HttpHost target = targetHost();
|
Redirect.ConnControl.CLOSE))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
|
@ -98,14 +86,15 @@ public abstract class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirects
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
Redirect.ConnControl.CLOSE)));
|
exchangeHandler,
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
||||||
final HttpHost target = targetHost();
|
Redirect.ConnControl.CLOSE))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
|
@ -124,18 +113,20 @@ public abstract class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirects
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultHeadersRedirect() throws Exception {
|
public void testDefaultHeadersRedirect() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
exchangeHandler,
|
.register("/random/*", AsyncRandomHandler::new)
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
.setExchangeHandlerDecorator(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
Redirect.ConnControl.CLOSE)));
|
exchangeHandler,
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
||||||
final HttpHost target = targetHost();
|
Redirect.ConnControl.CLOSE))));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final List<Header> defaultHeaders = new ArrayList<>(1);
|
final List<Header> defaultHeaders = new ArrayList<>(1);
|
||||||
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
||||||
final CloseableHttpAsyncClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setDefaultHeaders(defaultHeaders)
|
.setDefaultHeaders(defaultHeaders)
|
||||||
);
|
);
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
|
|
|
@ -34,6 +34,9 @@ import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.EndpointDetails;
|
import org.apache.hc.core5.http.EndpointDetails;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
|
@ -41,28 +44,21 @@ import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
||||||
import org.apache.hc.core5.net.URIAuthority;
|
import org.apache.hc.core5.net.URIAuthority;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTestBase {
|
public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public TestHttp1AsyncStatefulConnManagement() {
|
public TestHttp1AsyncStatefulConnManagement() {
|
||||||
super(URIScheme.HTTP);
|
super(URIScheme.HTTP, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(Http1Config.DEFAULT, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatefulConnections() throws Exception {
|
public void testStatefulConnections() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SimpleHttpResponse handle(
|
protected SimpleHttpResponse handle(
|
||||||
|
@ -72,13 +68,14 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
configureClient(builder -> builder
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient(builer -> builer
|
|
||||||
.setUserTokenHandler((route, context) -> context.getAttribute("user")));
|
.setUserTokenHandler((route, context) -> context.getAttribute("user")));
|
||||||
|
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final int workerCount = 2;
|
final int workerCount = 2;
|
||||||
final int requestCount = 5;
|
final int requestCount = 5;
|
||||||
|
|
||||||
|
@ -177,8 +174,7 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRouteSpecificPoolRecylcing() throws Exception {
|
public void testRouteSpecificPoolRecylcing() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SimpleHttpResponse handle(
|
protected SimpleHttpResponse handle(
|
||||||
|
@ -188,17 +184,19 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
// This tests what happens when a maxed connection pool needs
|
// This tests what happens when a maxed connection pool needs
|
||||||
// to kill the last idle connection to a route to build a new
|
// to kill the last idle connection to a route to build a new
|
||||||
// one to the same route.
|
// one to the same route.
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
configureClient(builder -> builder
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient(builer -> builer
|
|
||||||
.setUserTokenHandler((route, context) -> context.getAttribute("user")));
|
.setUserTokenHandler((route, context) -> context.getAttribute("user")));
|
||||||
final PoolingAsyncClientConnectionManager connManager = connManager();
|
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = client.getConnectionManager();
|
||||||
|
|
||||||
final int maxConn = 2;
|
final int maxConn = 2;
|
||||||
// We build a client with 2 max active // connections, and 2 max per route.
|
// We build a client with 2 max active // connections, and 2 max per route.
|
||||||
|
|
|
@ -27,103 +27,49 @@
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.AuthenticationStrategy;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
|
||||||
import org.apache.hc.client5.http.auth.AuthScope;
|
import org.apache.hc.client5.http.auth.AuthScope;
|
||||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.http.HeaderElements;
|
import org.apache.hc.core5.http.HeaderElements;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.config.Lookup;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public abstract class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthenticationTest<CloseableHttpAsyncClient> {
|
public abstract class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthenticationTest {
|
||||||
|
|
||||||
public TestHttp1ClientAuthentication(final URIScheme scheme) {
|
public TestHttp1ClientAuthentication(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
return startServer(Http1Config.DEFAULT, null, exchangeHandlerDecorator);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClientCustom(final Consumer<TestClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
|
|
||||||
return startClient(new Consumer<HttpAsyncClientBuilder>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(final HttpAsyncClientBuilder builder) {
|
|
||||||
|
|
||||||
clientCustomizer.accept(new TestClientBuilder() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder setDefaultAuthSchemeRegistry(final Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
|
||||||
builder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
|
||||||
builder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder addResponseInterceptor(final HttpResponseInterceptor responseInterceptor) {
|
|
||||||
builder.addResponseInterceptorLast(responseInterceptor);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TestClientBuilder addRequestInterceptor(final HttpRequestInterceptor requestInterceptor) {
|
|
||||||
builder.addRequestInterceptorFirst(requestInterceptor);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccessNonPersistentConnection() throws Exception {
|
public void testBasicAuthenticationSuccessNonPersistentConnection() throws Exception {
|
||||||
final H2TestServer server = startServer(exchangeHandler ->
|
final HttpHost target = startServer();
|
||||||
new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
configureServer(bootstrap -> bootstrap
|
||||||
|
.register("*", AsyncEchoHandler::new)
|
||||||
|
.setExchangeHandlerDecorator(exchangeHandler ->
|
||||||
|
new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
server.register("*", AsyncEchoHandler::new);
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
|
|
@ -36,18 +36,19 @@ import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.http.HeaderElements;
|
import org.apache.hc.core5.http.HeaderElements;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.Message;
|
import org.apache.hc.core5.http.Message;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
||||||
import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder;
|
import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder;
|
||||||
import org.apache.hc.core5.reactive.ReactiveResponseConsumer;
|
import org.apache.hc.core5.reactive.ReactiveResponseConsumer;
|
||||||
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.testing.reactive.ReactiveRandomProcessor;
|
import org.apache.hc.core5.testing.reactive.ReactiveRandomProcessor;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -56,33 +57,23 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
|
|
||||||
public abstract class TestHttp1Reactive extends AbstractHttpReactiveFundamentalsTest<CloseableHttpAsyncClient> {
|
public abstract class TestHttp1Reactive extends AbstractHttpReactiveFundamentalsTest {
|
||||||
|
|
||||||
public TestHttp1Reactive(final URIScheme scheme) {
|
public TestHttp1Reactive(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(Http1Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startClient(b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest(name = "{displayName}; concurrent connections: {0}")
|
@ParameterizedTest(name = "{displayName}; concurrent connections: {0}")
|
||||||
@ValueSource(ints = {5, 1, 20})
|
@ValueSource(ints = {5, 1, 20})
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
@Timeout(value = 60_000, unit = MILLISECONDS)
|
||||||
public void testSequentialGetRequestsCloseConnection(final int concurrentConns) throws Exception {
|
public void testSequentialGetRequestsCloseConnection(final int concurrentConns) throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", () ->
|
||||||
server.register("/random/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
final PoolingAsyncClientConnectionManager connManager = connManager();
|
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = client.getConnectionManager();
|
||||||
connManager.setDefaultMaxPerRoute(concurrentConns);
|
connManager.setDefaultMaxPerRoute(concurrentConns);
|
||||||
connManager.setMaxTotal(100);
|
connManager.setMaxTotal(100);
|
||||||
|
|
||||||
|
@ -109,13 +100,13 @@ public abstract class TestHttp1Reactive extends AbstractHttpReactiveFundamentals
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
@Timeout(value = 60_000, unit = MILLISECONDS)
|
||||||
public void testSharedPool() throws Exception {
|
public void testSharedPool() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", () ->
|
||||||
server.register("/random/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient();
|
final TestAsyncClient client = startClient();
|
||||||
final PoolingAsyncClientConnectionManager connManager = connManager();
|
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = client.getConnectionManager();
|
||||||
|
|
||||||
final AsyncRequestProducer request1 = AsyncRequestBuilder.get(target + "/random/2048").build();
|
final AsyncRequestProducer request1 = AsyncRequestBuilder.get(target + "/random/2048").build();
|
||||||
final ReactiveResponseConsumer consumer1 = new ReactiveResponseConsumer();
|
final ReactiveResponseConsumer consumer1 = new ReactiveResponseConsumer();
|
||||||
|
|
|
@ -36,52 +36,37 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.Message;
|
import org.apache.hc.core5.http.Message;
|
||||||
import org.apache.hc.core5.http.Method;
|
import org.apache.hc.core5.http.Method;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||||
import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
|
import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
|
||||||
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
|
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.testing.reactive.ReactiveEchoProcessor;
|
import org.apache.hc.core5.testing.reactive.ReactiveEchoProcessor;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public abstract class TestHttp1ReactiveMinimal extends AbstractHttpReactiveFundamentalsTest<MinimalHttpAsyncClient> {
|
public abstract class TestHttp1ReactiveMinimal extends AbstractHttpReactiveFundamentalsTest {
|
||||||
|
|
||||||
public TestHttp1ReactiveMinimal(final URIScheme scheme) {
|
public TestHttp1ReactiveMinimal(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.MINIMAL, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
|
||||||
return startServer(Http1Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MinimalHttpAsyncClient startClient() throws Exception {
|
|
||||||
return startMinimalClient(
|
|
||||||
Http1Config.DEFAULT,
|
|
||||||
H2Config.DEFAULT,
|
|
||||||
b -> {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/echo/*", () ->
|
||||||
server.register("/echo/*", () ->
|
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor())));
|
||||||
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor()));
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final MinimalHttpAsyncClient client = startClient();
|
final MinimalHttpAsyncClient client = startClient().getImplementation();
|
||||||
|
|
||||||
final byte[] b1 = new byte[1024];
|
final byte[] b1 = new byte[1024];
|
||||||
final Random rnd = new Random(System.currentTimeMillis());
|
final Random rnd = new Random(System.currentTimeMillis());
|
||||||
|
|
|
@ -34,25 +34,27 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
|
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.function.Resolver;
|
import org.apache.hc.core5.function.Resolver;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
import org.apache.hc.core5.http.HttpRequest;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public abstract class TestHttp1RequestReExecution extends AbstractIntegrationTestBase {
|
public abstract class TestHttp1RequestReExecution extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public TestHttp1RequestReExecution(final URIScheme scheme) {
|
public TestHttp1RequestReExecution(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.STANDARD, ServerProtocolLevel.STANDARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected H2TestServer startServer() throws Exception {
|
@BeforeEach
|
||||||
|
public void setup() {
|
||||||
final Resolver<HttpRequest, TimeValue> serviceAvailabilityResolver = new Resolver<HttpRequest, TimeValue>() {
|
final Resolver<HttpRequest, TimeValue> serviceAvailabilityResolver = new Resolver<HttpRequest, TimeValue>() {
|
||||||
|
|
||||||
private final AtomicInteger count = new AtomicInteger(0);
|
private final AtomicInteger count = new AtomicInteger(0);
|
||||||
|
@ -65,18 +67,18 @@ public abstract class TestHttp1RequestReExecution extends AbstractIntegrationTes
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return startServer(Http1Config.DEFAULT, null, handler ->
|
configureServer(bootstrap -> bootstrap
|
||||||
new ServiceUnavailableAsyncDecorator(handler, serviceAvailabilityResolver));
|
.setExchangeHandlerDecorator(handler -> new ServiceUnavailableAsyncDecorator(handler, serviceAvailabilityResolver)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGiveUpAfterOneRetry() throws Exception {
|
public void testGiveUpAfterOneRetry() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(1, TimeValue.ofSeconds(1))));
|
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(1, TimeValue.ofSeconds(1))));
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
@ -90,12 +92,12 @@ public abstract class TestHttp1RequestReExecution extends AbstractIntegrationTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDoNotGiveUpEasily() throws Exception {
|
public void testDoNotGiveUpEasily() throws Exception {
|
||||||
final H2TestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(5, TimeValue.ofSeconds(1))));
|
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(5, TimeValue.ofSeconds(1))));
|
||||||
|
final TestAsyncClient client = startClient();
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
|
|
@ -29,18 +29,17 @@ package org.apache.hc.client5.testing.async;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.ssl.SSLContexts;
|
import org.apache.hc.core5.ssl.SSLContexts;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -48,26 +47,19 @@ import org.junit.jupiter.api.Test;
|
||||||
public class TestHttpAsyncMinimalTlsHandshake extends AbstractIntegrationTestBase {
|
public class TestHttpAsyncMinimalTlsHandshake extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public TestHttpAsyncMinimalTlsHandshake() {
|
public TestHttpAsyncMinimalTlsHandshake() {
|
||||||
super(URIScheme.HTTPS);
|
super(URIScheme.HTTPS, ClientProtocolLevel.MINIMAL, ServerProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
protected MinimalHttpAsyncClient startMinimalClient(
|
|
||||||
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer) throws Exception {
|
|
||||||
return startMinimalClient(
|
|
||||||
Http1Config.DEFAULT,
|
|
||||||
H2Config.DEFAULT,
|
|
||||||
connManagerCustomizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulTlsHandshake() throws Exception {
|
public void testSuccessfulTlsHandshake() throws Exception {
|
||||||
startServer(Http1Config.DEFAULT, null, null);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final int maxConnNo = 2;
|
final int maxConnNo = 2;
|
||||||
final MinimalHttpAsyncClient client = startMinimalClient(builder -> builder
|
final PoolingAsyncClientConnectionManager connectionManager = startClient().getConnectionManager();
|
||||||
.setMaxConnPerRoute(maxConnNo)
|
connectionManager.setDefaultMaxPerRoute(maxConnNo);
|
||||||
.setMaxConnTotal(maxConnNo));
|
connectionManager.setMaxTotal(maxConnNo);
|
||||||
|
|
||||||
|
final MinimalHttpAsyncClient client = startClient().getImplementation();
|
||||||
|
|
||||||
for (int i = 0; i < maxConnNo + 1; i++) {
|
for (int i = 0; i < maxConnNo + 1; i++) {
|
||||||
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
||||||
|
@ -78,14 +70,17 @@ public class TestHttpAsyncMinimalTlsHandshake extends AbstractIntegrationTestBas
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTlsHandshakeFailure() throws Exception {
|
public void testTlsHandshakeFailure() throws Exception {
|
||||||
startServer(Http1Config.DEFAULT, null, null);
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
configureClient(builder ->
|
||||||
|
builder.setTlsStrategy(new DefaultClientTlsStrategy(SSLContexts.createDefault())));
|
||||||
|
|
||||||
final int maxConnNo = 2;
|
final int maxConnNo = 2;
|
||||||
final MinimalHttpAsyncClient client = startMinimalClient(builder -> builder
|
final PoolingAsyncClientConnectionManager connectionManager = startClient().getConnectionManager();
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLContexts.createDefault()))
|
connectionManager.setDefaultMaxPerRoute(maxConnNo);
|
||||||
.setMaxConnPerRoute(maxConnNo)
|
connectionManager.setMaxTotal(maxConnNo);
|
||||||
.setMaxConnTotal(maxConnNo));
|
|
||||||
|
final MinimalHttpAsyncClient client = startClient().getImplementation();
|
||||||
|
|
||||||
for (int i = 0; i < maxConnNo + 1; i++) {
|
for (int i = 0; i < maxConnNo + 1; i++) {
|
||||||
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
||||||
|
|
|
@ -34,15 +34,14 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.config.TlsConfig;
|
import org.apache.hc.client5.http.config.TlsConfig;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.testing.async.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.ServerProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.async.extension.TestAsyncClient;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
import org.apache.hc.core5.http.HttpVersion;
|
||||||
import org.apache.hc.core5.http.ProtocolVersion;
|
import org.apache.hc.core5.http.ProtocolVersion;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -51,31 +50,23 @@ public abstract class TestHttpAsyncProtocolPolicy extends AbstractIntegrationTes
|
||||||
private final HttpVersion version;
|
private final HttpVersion version;
|
||||||
|
|
||||||
public TestHttpAsyncProtocolPolicy(final URIScheme scheme, final HttpVersion version) {
|
public TestHttpAsyncProtocolPolicy(final URIScheme scheme, final HttpVersion version) {
|
||||||
super(scheme);
|
super(scheme, ClientProtocolLevel.STANDARD, version == HttpVersion.HTTP_2 ? ServerProtocolLevel.H2_ONLY : ServerProtocolLevel.STANDARD);
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestContext() throws Exception {
|
public void testRequestContext() throws Exception {
|
||||||
final H2TestServer server;
|
configureServer(bootstrap -> bootstrap.register("/random/*", AsyncRandomHandler::new));
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
final HttpHost target = startServer();
|
||||||
server = startServer(H2Config.DEFAULT, null, null);
|
|
||||||
} else {
|
|
||||||
server = startServer(Http1Config.DEFAULT, null, null);
|
|
||||||
}
|
|
||||||
server.register("/random/*", AsyncRandomHandler::new);
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final AtomicReference<ProtocolVersion> versionRef = new AtomicReference<>();
|
final AtomicReference<ProtocolVersion> versionRef = new AtomicReference<>();
|
||||||
final CloseableHttpAsyncClient client = startClient(
|
configureClient(builder -> builder
|
||||||
builder -> builder
|
.setDefaultTlsConfig(TlsConfig.custom()
|
||||||
.setDefaultTlsConfig(TlsConfig.custom()
|
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2) ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
||||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2) ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
.build())
|
||||||
.build()),
|
.addRequestInterceptorFirst((request, entity, context) ->
|
||||||
builder -> builder
|
versionRef.set(context.getProtocolVersion())));
|
||||||
.addRequestInterceptorFirst((request, entity, context) ->
|
final TestAsyncClient client = startClient();
|
||||||
versionRef.set(context.getProtocolVersion())
|
|
||||||
));
|
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = client.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
public enum ClientProtocolLevel {
|
||||||
|
|
||||||
|
STANDARD, H2_ONLY, MINIMAL, MINIMAL_H2_ONLY
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||||
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
final class H2OnlyMinimalTestClientBuilder implements TestAsyncClientBuilder {
|
||||||
|
|
||||||
|
private Timeout timeout;
|
||||||
|
private TlsStrategy tlsStrategy;
|
||||||
|
private H2Config h2Config;
|
||||||
|
|
||||||
|
public H2OnlyMinimalTestClientBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTlsStrategy(final TlsStrategy tlsStrategy) {
|
||||||
|
this.tlsStrategy = tlsStrategy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientProtocolLevel getProtocolLevel() {
|
||||||
|
return ClientProtocolLevel.MINIMAL_H2_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setH2Config(final H2Config h2Config) {
|
||||||
|
this.h2Config = h2Config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClient build() throws Exception {
|
||||||
|
final CloseableHttpAsyncClient client = HttpAsyncClients.createHttp2Minimal(
|
||||||
|
h2Config,
|
||||||
|
IOReactorConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build(),
|
||||||
|
tlsStrategy != null ? tlsStrategy : new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
||||||
|
return new TestAsyncClient(client, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.AuthenticationStrategy;
|
||||||
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
|
import org.apache.hc.client5.http.impl.async.H2AsyncClientBuilder;
|
||||||
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.http.Header;
|
||||||
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
final class H2OnlyTestClientBuilder implements TestAsyncClientBuilder {
|
||||||
|
|
||||||
|
private final H2AsyncClientBuilder clientBuilder;
|
||||||
|
|
||||||
|
private Timeout timeout;
|
||||||
|
private TlsStrategy tlsStrategy;
|
||||||
|
private H2Config h2Config;
|
||||||
|
|
||||||
|
public H2OnlyTestClientBuilder() {
|
||||||
|
this.clientBuilder = H2AsyncClientBuilder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientProtocolLevel getProtocolLevel() {
|
||||||
|
return ClientProtocolLevel.H2_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addResponseInterceptorFirst(final HttpResponseInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addResponseInterceptorFirst(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addResponseInterceptorLast(final HttpResponseInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addResponseInterceptorLast(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addRequestInterceptorFirst(final HttpRequestInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addRequestInterceptorFirst(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addRequestInterceptorLast(final HttpRequestInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addRequestInterceptorLast(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTlsStrategy(final TlsStrategy tlsStrategy) {
|
||||||
|
this.tlsStrategy = tlsStrategy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setH2Config(final H2Config h2Config) {
|
||||||
|
this.h2Config = h2Config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setDefaultHeaders(final Collection<? extends Header> defaultHeaders) {
|
||||||
|
this.clientBuilder.setDefaultHeaders(defaultHeaders);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
||||||
|
this.clientBuilder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setDefaultAuthSchemeRegistry(final Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
||||||
|
this.clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClient build() throws Exception {
|
||||||
|
final CloseableHttpAsyncClient client = clientBuilder
|
||||||
|
.setTlsStrategy(tlsStrategy != null ? tlsStrategy : new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||||
|
.setIOReactorConfig(IOReactorConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.setH2Config(h2Config)
|
||||||
|
.build();
|
||||||
|
return new TestAsyncClient(client, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||||
|
import org.apache.hc.client5.http.config.TlsConfig;
|
||||||
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||||
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||||
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
final class MinimalTestClientBuilder implements TestAsyncClientBuilder {
|
||||||
|
|
||||||
|
private final PoolingAsyncClientConnectionManagerBuilder connectionManagerBuilder;
|
||||||
|
|
||||||
|
private Timeout timeout;
|
||||||
|
private TlsStrategy tlsStrategy;
|
||||||
|
private Http1Config http1Config;
|
||||||
|
private H2Config h2Config;
|
||||||
|
|
||||||
|
public MinimalTestClientBuilder() {
|
||||||
|
this.connectionManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientProtocolLevel getProtocolLevel() {
|
||||||
|
return ClientProtocolLevel.MINIMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTlsStrategy(final TlsStrategy tlsStrategy) {
|
||||||
|
this.tlsStrategy = tlsStrategy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setDefaultTlsConfig(final TlsConfig tlsConfig) {
|
||||||
|
this.connectionManagerBuilder.setDefaultTlsConfig(tlsConfig);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setHttp1Config(final Http1Config http1Config) {
|
||||||
|
this.http1Config = http1Config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setH2Config(final H2Config h2Config) {
|
||||||
|
this.h2Config = h2Config;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClient build() throws Exception {
|
||||||
|
final PoolingAsyncClientConnectionManager connectionManager = connectionManagerBuilder
|
||||||
|
.setTlsStrategy(tlsStrategy != null ? tlsStrategy : new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||||
|
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
||||||
|
.setSocketTimeout(timeout)
|
||||||
|
.setConnectTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
final CloseableHttpAsyncClient client = HttpAsyncClients.createMinimal(
|
||||||
|
h2Config,
|
||||||
|
http1Config,
|
||||||
|
IOReactorConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build(),
|
||||||
|
connectionManager);
|
||||||
|
return new TestAsyncClient(client, connectionManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
public enum ServerProtocolLevel {
|
||||||
|
|
||||||
|
STANDARD, H2_ONLY
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.AuthenticationStrategy;
|
||||||
|
import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
||||||
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
|
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||||
|
import org.apache.hc.client5.http.config.TlsConfig;
|
||||||
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
||||||
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||||
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.http.Header;
|
||||||
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
final class StandardTestClientBuilder implements TestAsyncClientBuilder {
|
||||||
|
|
||||||
|
private final PoolingAsyncClientConnectionManagerBuilder connectionManagerBuilder;
|
||||||
|
private final HttpAsyncClientBuilder clientBuilder;
|
||||||
|
|
||||||
|
private Timeout timeout;
|
||||||
|
private TlsStrategy tlsStrategy;
|
||||||
|
|
||||||
|
public StandardTestClientBuilder() {
|
||||||
|
this.connectionManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create();
|
||||||
|
this.clientBuilder = HttpAsyncClientBuilder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientProtocolLevel getProtocolLevel() {
|
||||||
|
return ClientProtocolLevel.STANDARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addResponseInterceptorFirst(final HttpResponseInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addResponseInterceptorFirst(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addResponseInterceptorLast(final HttpResponseInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addResponseInterceptorLast(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addRequestInterceptorFirst(final HttpRequestInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addRequestInterceptorFirst(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder addRequestInterceptorLast(final HttpRequestInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addRequestInterceptorLast(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTlsStrategy(final TlsStrategy tlsStrategy) {
|
||||||
|
this.tlsStrategy = tlsStrategy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setDefaultTlsConfig(final TlsConfig tlsConfig) {
|
||||||
|
this.connectionManagerBuilder.setDefaultTlsConfig(tlsConfig);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setHttp1Config(final Http1Config http1Config) {
|
||||||
|
this.clientBuilder.setHttp1Config(http1Config);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setH2Config(final H2Config h2Config) {
|
||||||
|
this.clientBuilder.setH2Config(h2Config);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setUserTokenHandler(final UserTokenHandler userTokenHandler) {
|
||||||
|
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setDefaultHeaders(final Collection<? extends Header> defaultHeaders) {
|
||||||
|
this.clientBuilder.setDefaultHeaders(defaultHeaders);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setRetryStrategy(final HttpRequestRetryStrategy retryStrategy) {
|
||||||
|
this.clientBuilder.setRetryStrategy(retryStrategy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
||||||
|
this.clientBuilder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClientBuilder setDefaultAuthSchemeRegistry(final Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
||||||
|
this.clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestAsyncClient build() throws Exception {
|
||||||
|
final PoolingAsyncClientConnectionManager connectionManager = connectionManagerBuilder
|
||||||
|
.setTlsStrategy(tlsStrategy != null ? tlsStrategy : new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||||
|
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
||||||
|
.setSocketTimeout(timeout)
|
||||||
|
.setConnectTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
final CloseableHttpAsyncClient client = clientBuilder
|
||||||
|
.setIOReactorConfig(IOReactorConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.setConnectionManager(connectionManager)
|
||||||
|
.build();
|
||||||
|
return new TestAsyncClient(client, connectionManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
|
import org.apache.hc.core5.function.Supplier;
|
||||||
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||||
|
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
||||||
|
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
|
||||||
|
import org.apache.hc.core5.http.nio.HandlerFactory;
|
||||||
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
|
import org.apache.hc.core5.reactor.IOReactorStatus;
|
||||||
|
import org.apache.hc.core5.util.Args;
|
||||||
|
import org.apache.hc.core5.util.Asserts;
|
||||||
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
|
|
||||||
|
public class TestAsyncClient extends CloseableHttpAsyncClient {
|
||||||
|
|
||||||
|
private final CloseableHttpAsyncClient client;
|
||||||
|
private final PoolingAsyncClientConnectionManager connectionManager;
|
||||||
|
|
||||||
|
public TestAsyncClient(final CloseableHttpAsyncClient client,
|
||||||
|
final PoolingAsyncClientConnectionManager connectionManager) {
|
||||||
|
this.client = Args.notNull(client, "Client");
|
||||||
|
this.connectionManager = connectionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(final CloseMode closeMode) {
|
||||||
|
client.close(closeMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
client.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IOReactorStatus getStatus() {
|
||||||
|
return client.getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void awaitShutdown(final TimeValue waitTime) throws InterruptedException {
|
||||||
|
client.awaitShutdown(waitTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initiateShutdown() {
|
||||||
|
client.initiateShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <T> Future<T> doExecute(final HttpHost target,
|
||||||
|
final AsyncRequestProducer requestProducer,
|
||||||
|
final AsyncResponseConsumer<T> responseConsumer,
|
||||||
|
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
|
||||||
|
final HttpContext context,
|
||||||
|
final FutureCallback<T> callback) {
|
||||||
|
return client.execute(target, requestProducer, responseConsumer, pushHandlerFactory, context, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(final String hostname,
|
||||||
|
final String uriPattern,
|
||||||
|
final Supplier<AsyncPushConsumer> supplier) {
|
||||||
|
client.register(hostname, uriPattern, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends CloseableHttpAsyncClient> T getImplementation() {
|
||||||
|
return (T) client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PoolingAsyncClientConnectionManager getConnectionManager() {
|
||||||
|
Asserts.check(connectionManager != null, "Connection manager is not available");
|
||||||
|
return connectionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.AuthenticationStrategy;
|
||||||
|
import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
||||||
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
|
import org.apache.hc.client5.http.config.TlsConfig;
|
||||||
|
import org.apache.hc.core5.http.Header;
|
||||||
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
public interface TestAsyncClientBuilder {
|
||||||
|
|
||||||
|
ClientProtocolLevel getProtocolLevel();
|
||||||
|
|
||||||
|
TestAsyncClientBuilder setTimeout(Timeout soTimeout);
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder addResponseInterceptorFirst(final HttpResponseInterceptor interceptor) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder addResponseInterceptorLast(HttpResponseInterceptor interceptor) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder addRequestInterceptorFirst(HttpRequestInterceptor interceptor) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder addRequestInterceptorLast(HttpRequestInterceptor interceptor) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setTlsStrategy(TlsStrategy tlsStrategy) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setDefaultTlsConfig(TlsConfig tlsConfig) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setHttp1Config(Http1Config http1Config) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setH2Config(H2Config http1Config) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setUserTokenHandler(UserTokenHandler userTokenHandler) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setDefaultHeaders(Collection<? extends Header> defaultHeaders) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setRetryStrategy(HttpRequestRetryStrategy retryStrategy) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestAsyncClientBuilder setDefaultAuthSchemeRegistry(Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
TestAsyncClient build() throws Exception;
|
||||||
|
|
||||||
|
}
|
|
@ -27,81 +27,63 @@
|
||||||
|
|
||||||
package org.apache.hc.client5.testing.async.extension;
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.async.H2AsyncClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalH2AsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.util.Asserts;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class TestAsyncResources implements BeforeEachCallback, AfterEachCallback {
|
public class TestAsyncResources implements AfterEachCallback {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(TestClientResources.class);
|
private static final Logger LOG = LoggerFactory.getLogger(TestClientResources.class);
|
||||||
|
|
||||||
private final URIScheme scheme;
|
private final URIScheme scheme;
|
||||||
private final Timeout timeout;
|
private final ClientProtocolLevel clientProtocolLevel;
|
||||||
|
private final ServerProtocolLevel serverProtocolLevel;
|
||||||
|
private final TestAsyncServerBootstrap serverBootstrap;
|
||||||
|
private final TestAsyncClientBuilder clientBuilder;
|
||||||
|
|
||||||
private H2TestServer server;
|
private TestAsyncServer server;
|
||||||
private InetSocketAddress socketAddress;
|
private TestAsyncClient client;
|
||||||
private PoolingAsyncClientConnectionManager connManager;
|
|
||||||
private CloseableHttpAsyncClient client;
|
|
||||||
|
|
||||||
public TestAsyncResources(final URIScheme scheme, final Timeout timeout) {
|
public TestAsyncResources(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final ServerProtocolLevel serverProtocolLevel, final Timeout timeout) {
|
||||||
this.scheme = scheme;
|
this.scheme = scheme != null ? scheme : URIScheme.HTTP;
|
||||||
this.timeout = timeout;
|
this.clientProtocolLevel = clientProtocolLevel != null ? clientProtocolLevel : ClientProtocolLevel.STANDARD;
|
||||||
}
|
this.serverProtocolLevel = serverProtocolLevel != null ? serverProtocolLevel : ServerProtocolLevel.STANDARD;
|
||||||
|
this.serverBootstrap = new TestAsyncServerBootstrap(this.scheme, this.serverProtocolLevel)
|
||||||
@Override
|
.setTimeout(timeout);
|
||||||
public void beforeEach(final ExtensionContext extensionContext) throws Exception {
|
switch (this.clientProtocolLevel) {
|
||||||
LOG.debug("Starting up test server");
|
case STANDARD:
|
||||||
server = new H2TestServer(
|
this.clientBuilder = new StandardTestClientBuilder();
|
||||||
IOReactorConfig.custom()
|
break;
|
||||||
.setSoTimeout(timeout)
|
case H2_ONLY:
|
||||||
.build(),
|
this.clientBuilder = new H2OnlyTestClientBuilder();
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
|
break;
|
||||||
null,
|
case MINIMAL_H2_ONLY:
|
||||||
null);
|
this.clientBuilder = new H2OnlyMinimalTestClientBuilder();
|
||||||
|
break;
|
||||||
|
case MINIMAL:
|
||||||
|
this.clientBuilder = new MinimalTestClientBuilder();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.clientBuilder = new StandardTestClientBuilder();
|
||||||
|
}
|
||||||
|
this.clientBuilder.setTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterEach(final ExtensionContext extensionContext) throws Exception {
|
public void afterEach(final ExtensionContext extensionContext) throws Exception {
|
||||||
LOG.debug("Shutting down test server");
|
LOG.debug("Shutting down test server");
|
||||||
|
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
client.close(CloseMode.GRACEFUL);
|
client.close(CloseMode.GRACEFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close(CloseMode.IMMEDIATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
server.shutdown(TimeValue.ofSeconds(5));
|
server.shutdown(TimeValue.ofSeconds(5));
|
||||||
}
|
}
|
||||||
|
@ -111,125 +93,36 @@ public class TestAsyncResources implements BeforeEachCallback, AfterEachCallback
|
||||||
return this.scheme;
|
return this.scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public H2TestServer startServer(
|
public ServerProtocolLevel getServerProtocolLevel() {
|
||||||
final H2Config h2Config,
|
return serverProtocolLevel;
|
||||||
final HttpProcessor httpProcessor,
|
}
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
Assertions.assertNotNull(server);
|
public ClientProtocolLevel getClientProtocolLevel() {
|
||||||
socketAddress = server.start(httpProcessor, exchangeHandlerDecorator, h2Config);
|
return clientProtocolLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureServer(final Consumer<TestAsyncServerBootstrap> serverCustomizer) {
|
||||||
|
Asserts.check(server == null, "Server is already running and cannot be changed");
|
||||||
|
serverCustomizer.accept(serverBootstrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestAsyncServer server() throws Exception {
|
||||||
|
if (server == null) {
|
||||||
|
server = serverBootstrap.build();
|
||||||
|
}
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
public H2TestServer startServer(
|
public void configureClient(final Consumer<TestAsyncClientBuilder> clientCustomizer) {
|
||||||
final Http1Config http1Config,
|
Asserts.check(client == null, "Client is already running and cannot be changed");
|
||||||
final HttpProcessor httpProcessor,
|
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
Assertions.assertNotNull(server);
|
|
||||||
socketAddress = server.start(httpProcessor, exchangeHandlerDecorator, http1Config);
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
Assertions.assertNotNull(socketAddress);
|
|
||||||
return new HttpHost(scheme.id, "localhost", socketAddress.getPort());
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpAsyncClient startClient(
|
|
||||||
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer,
|
|
||||||
final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
Assertions.assertNull(connManager);
|
|
||||||
Assertions.assertNull(client);
|
|
||||||
|
|
||||||
final PoolingAsyncClientConnectionManagerBuilder connManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create();
|
|
||||||
connManagerBuilder.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
connManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setSocketTimeout(timeout)
|
|
||||||
.setConnectTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
connManagerCustomizer.accept(connManagerBuilder);
|
|
||||||
|
|
||||||
connManager = connManagerBuilder.build();
|
|
||||||
|
|
||||||
final HttpAsyncClientBuilder clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setConnectionManager(connManager)
|
|
||||||
.setIOReactorConfig(IOReactorConfig.custom()
|
|
||||||
.setSoTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
clientCustomizer.accept(clientBuilder);
|
clientCustomizer.accept(clientBuilder);
|
||||||
client = clientBuilder.build();
|
}
|
||||||
client.start();
|
|
||||||
|
public TestAsyncClient client() throws Exception {
|
||||||
|
if (client == null) {
|
||||||
|
client = clientBuilder.build();
|
||||||
|
}
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CloseableHttpAsyncClient startClient(
|
|
||||||
final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
return startClient(b -> {
|
|
||||||
}, clientCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PoolingAsyncClientConnectionManager connManager() {
|
|
||||||
Assertions.assertNotNull(connManager);
|
|
||||||
return connManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpAsyncClient startH2Client(
|
|
||||||
final Consumer<H2AsyncClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
Assertions.assertNull(connManager);
|
|
||||||
Assertions.assertNull(client);
|
|
||||||
|
|
||||||
final H2AsyncClientBuilder clientBuilder = H2AsyncClientBuilder.create();
|
|
||||||
clientBuilder.setIOReactorConfig(IOReactorConfig.custom()
|
|
||||||
.setSoTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
clientBuilder.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
clientCustomizer.accept(clientBuilder);
|
|
||||||
client = clientBuilder.build();
|
|
||||||
client.start();
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinimalHttpAsyncClient startMinimalClient(
|
|
||||||
final Http1Config http1Config,
|
|
||||||
final H2Config h2Config,
|
|
||||||
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer) throws Exception {
|
|
||||||
Assertions.assertNull(connManager);
|
|
||||||
Assertions.assertNull(client);
|
|
||||||
|
|
||||||
final PoolingAsyncClientConnectionManagerBuilder connManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create();
|
|
||||||
connManagerBuilder.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
connManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setSocketTimeout(timeout)
|
|
||||||
.setConnectTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
connManagerCustomizer.accept(connManagerBuilder);
|
|
||||||
|
|
||||||
connManager = connManagerBuilder.build();
|
|
||||||
|
|
||||||
final MinimalHttpAsyncClient minimal = HttpAsyncClients.createMinimal(
|
|
||||||
h2Config,
|
|
||||||
http1Config,
|
|
||||||
IOReactorConfig.custom()
|
|
||||||
.setSoTimeout(timeout)
|
|
||||||
.build(),
|
|
||||||
connManager);
|
|
||||||
client = minimal;
|
|
||||||
client.start();
|
|
||||||
return minimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MinimalH2AsyncClient startMinimalH2Client(final H2Config h2Config) throws Exception {
|
|
||||||
Assertions.assertNull(client);
|
|
||||||
|
|
||||||
final MinimalH2AsyncClient minimal = HttpAsyncClients.createHttp2Minimal(
|
|
||||||
h2Config,
|
|
||||||
IOReactorConfig.custom()
|
|
||||||
.setSoTimeout(timeout)
|
|
||||||
.build(),
|
|
||||||
new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
client = minimal;
|
|
||||||
client.start();
|
|
||||||
return minimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.apache.hc.core5.function.Decorator;
|
||||||
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
||||||
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.reactor.IOReactorStatus;
|
||||||
|
import org.apache.hc.core5.reactor.ListenerEndpoint;
|
||||||
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
|
|
||||||
|
public class TestAsyncServer {
|
||||||
|
|
||||||
|
private final H2TestServer server;
|
||||||
|
private final H2Config h2Config;
|
||||||
|
private final Http1Config http1Config;
|
||||||
|
private final HttpProcessor httpProcessor;
|
||||||
|
private final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator;
|
||||||
|
|
||||||
|
TestAsyncServer(
|
||||||
|
final H2TestServer server,
|
||||||
|
final H2Config h2Config,
|
||||||
|
final Http1Config http1Config,
|
||||||
|
final HttpProcessor httpProcessor,
|
||||||
|
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) {
|
||||||
|
this.server = server;
|
||||||
|
this.h2Config = h2Config;
|
||||||
|
this.http1Config = http1Config;
|
||||||
|
this.httpProcessor = httpProcessor;
|
||||||
|
this.exchangeHandlerDecorator = exchangeHandlerDecorator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<ListenerEndpoint> listen(final InetSocketAddress address) {
|
||||||
|
return server.listen(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<ListenerEndpoint> getEndpoints() {
|
||||||
|
return server.getEndpoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IOReactorStatus getStatus() {
|
||||||
|
return server.getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void awaitShutdown(final TimeValue waitTime) throws InterruptedException {
|
||||||
|
server.awaitShutdown(waitTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initiateShutdown() {
|
||||||
|
server.initiateShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown(final TimeValue graceTime) {
|
||||||
|
server.shutdown(graceTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws Exception {
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InetSocketAddress start() throws Exception {
|
||||||
|
if (http1Config == null) {
|
||||||
|
return server.start(httpProcessor, exchangeHandlerDecorator, h2Config);
|
||||||
|
} else {
|
||||||
|
return server.start(httpProcessor, exchangeHandlerDecorator, http1Config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.async.extension;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.function.Decorator;
|
||||||
|
import org.apache.hc.core5.function.Supplier;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
||||||
|
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
|
||||||
|
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
|
||||||
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
|
import org.apache.hc.core5.util.Args;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
public class TestAsyncServerBootstrap {
|
||||||
|
|
||||||
|
static final class HandlerEntry<T> {
|
||||||
|
|
||||||
|
final String hostname;
|
||||||
|
final String uriPattern;
|
||||||
|
final T handler;
|
||||||
|
|
||||||
|
public HandlerEntry(final String hostname, final String uriPattern, final T handler) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
this.uriPattern = uriPattern;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HandlerEntry(final String uriPattern, final T handler) {
|
||||||
|
this(null, uriPattern, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final URIScheme scheme;
|
||||||
|
private final ServerProtocolLevel serverProtocolLevel;
|
||||||
|
|
||||||
|
private final List<HandlerEntry<Supplier<AsyncServerExchangeHandler>>> handlerList;
|
||||||
|
private Timeout timeout;
|
||||||
|
private HttpProcessor httpProcessor;
|
||||||
|
private Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator;
|
||||||
|
|
||||||
|
public TestAsyncServerBootstrap(final URIScheme scheme, final ServerProtocolLevel serverProtocolLevel) {
|
||||||
|
this.scheme = scheme != null ? scheme : URIScheme.HTTP;
|
||||||
|
this.serverProtocolLevel = serverProtocolLevel != null ? serverProtocolLevel : ServerProtocolLevel.STANDARD;
|
||||||
|
this.handlerList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerProtocolLevel getProtocolLevel() {
|
||||||
|
return serverProtocolLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestAsyncServerBootstrap register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
|
||||||
|
Args.notNull(uriPattern, "URI pattern");
|
||||||
|
Args.notNull(supplier, "Exchange handler supplier");
|
||||||
|
handlerList.add(new HandlerEntry<>(uriPattern, supplier));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestAsyncServerBootstrap register(
|
||||||
|
final String uriPattern,
|
||||||
|
final AsyncServerRequestHandler<AsyncServerExchangeHandler> requestHandler) {
|
||||||
|
return register(uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestAsyncServerBootstrap setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestAsyncServerBootstrap setHttpProcessor(final HttpProcessor httpProcessor) {
|
||||||
|
this.httpProcessor = httpProcessor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestAsyncServerBootstrap setExchangeHandlerDecorator(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) {
|
||||||
|
this.exchangeHandlerDecorator = exchangeHandlerDecorator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestAsyncServer build() throws Exception {
|
||||||
|
final H2TestServer server = new H2TestServer(
|
||||||
|
IOReactorConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build(),
|
||||||
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
for (final HandlerEntry<Supplier<AsyncServerExchangeHandler>> entry: handlerList) {
|
||||||
|
server.register(entry.uriPattern, entry.handler);
|
||||||
|
}
|
||||||
|
return new TestAsyncServer(
|
||||||
|
server,
|
||||||
|
serverProtocolLevel == ServerProtocolLevel.H2_ONLY ? H2Config.DEFAULT : null,
|
||||||
|
serverProtocolLevel == ServerProtocolLevel.STANDARD ? Http1Config.DEFAULT : null,
|
||||||
|
httpProcessor,
|
||||||
|
exchangeHandlerDecorator);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,6 +27,7 @@
|
||||||
package org.apache.hc.client5.testing.fluent;
|
package org.apache.hc.client5.testing.fluent;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
@ -34,7 +35,9 @@ import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
import org.apache.hc.client5.http.HttpResponseException;
|
import org.apache.hc.client5.http.HttpResponseException;
|
||||||
import org.apache.hc.client5.http.fluent.Content;
|
import org.apache.hc.client5.http.fluent.Content;
|
||||||
import org.apache.hc.client5.http.fluent.Request;
|
import org.apache.hc.client5.http.fluent.Request;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestServer;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpEntity;
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
@ -42,7 +45,6 @@ import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -54,52 +56,51 @@ public class TestFluent {
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, ClientProtocolLevel.STANDARD, TIMEOUT);
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
return testResources.targetHost();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
testResources.configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/", (request, response, context) ->
|
.register("/", (request, response, context) ->
|
||||||
response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN)));
|
response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN)))
|
||||||
server.registerHandler("/echo", (request, response, context) -> {
|
.register("/echo", (request, response, context) -> {
|
||||||
HttpEntity responseEntity = null;
|
HttpEntity responseEntity = null;
|
||||||
final HttpEntity requestEntity = request.getEntity();
|
final HttpEntity requestEntity = request.getEntity();
|
||||||
if (requestEntity != null) {
|
if (requestEntity != null) {
|
||||||
final String contentTypeStr = requestEntity.getContentType();
|
final String contentTypeStr = requestEntity.getContentType();
|
||||||
final ContentType contentType = contentTypeStr == null ? ContentType.DEFAULT_TEXT : ContentType.parse(contentTypeStr);
|
final ContentType contentType = contentTypeStr == null ? ContentType.DEFAULT_TEXT : ContentType.parse(contentTypeStr);
|
||||||
if (ContentType.TEXT_PLAIN.getMimeType().equals(contentType.getMimeType())) {
|
if (ContentType.TEXT_PLAIN.getMimeType().equals(contentType.getMimeType())) {
|
||||||
responseEntity = new StringEntity(
|
responseEntity = new StringEntity(
|
||||||
EntityUtils.toString(requestEntity), ContentType.TEXT_PLAIN);
|
EntityUtils.toString(requestEntity), ContentType.TEXT_PLAIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (responseEntity == null) {
|
if (responseEntity == null) {
|
||||||
responseEntity = new StringEntity("echo", ContentType.TEXT_PLAIN);
|
responseEntity = new StringEntity("echo", ContentType.TEXT_PLAIN);
|
||||||
}
|
}
|
||||||
response.setEntity(responseEntity);
|
response.setEntity(responseEntity);
|
||||||
});
|
})
|
||||||
|
// Handler for large content large message
|
||||||
// Handler for large content large message
|
.register("/large-message", (request, response, context) -> {
|
||||||
server.registerHandler("/large-message", (request, response, context) -> {
|
final String largeContent = generateLargeString(10000); // Large content string
|
||||||
final String largeContent = generateLargeString(10000); // Large content string
|
response.setEntity(new StringEntity(largeContent, ContentType.TEXT_PLAIN));
|
||||||
response.setEntity(new StringEntity(largeContent, ContentType.TEXT_PLAIN));
|
})
|
||||||
});
|
// Handler for large content large message with error
|
||||||
|
.register("/large-message-error", (request, response, context) -> {
|
||||||
// Handler for large content large message with error
|
final String largeContent = generateLargeString(10000); // Large content string
|
||||||
server.registerHandler("/large-message-error", (request, response, context) -> {
|
response.setCode(HttpStatus.SC_REDIRECTION);
|
||||||
final String largeContent = generateLargeString(10000); // Large content string
|
response.setEntity(new StringEntity(largeContent, ContentType.TEXT_PLAIN));
|
||||||
response.setCode(HttpStatus.SC_REDIRECTION);
|
}));
|
||||||
response.setEntity(new StringEntity(largeContent, ContentType.TEXT_PLAIN));
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
public HttpHost startServer() throws Exception {
|
||||||
|
final TestServer server = testResources.server();
|
||||||
|
final InetSocketAddress inetSocketAddress = server.start();
|
||||||
|
return new HttpHost(testResources.scheme().id, "localhost", inetSocketAddress.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequest() throws Exception {
|
public void testGetRequest() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
final String message = Request.get(baseURL + "/").execute().returnContent().asString();
|
final String message = Request.get(baseURL + "/").execute().returnContent().asString();
|
||||||
Assertions.assertEquals("All is well", message);
|
Assertions.assertEquals("All is well", message);
|
||||||
|
@ -107,7 +108,7 @@ public class TestFluent {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequestByName() throws Exception {
|
public void testGetRequestByName() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
final String message = Request.create("GET", baseURL + "/").execute().returnContent().asString();
|
final String message = Request.create("GET", baseURL + "/").execute().returnContent().asString();
|
||||||
Assertions.assertEquals("All is well", message);
|
Assertions.assertEquals("All is well", message);
|
||||||
|
@ -115,7 +116,7 @@ public class TestFluent {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequestByNameWithURI() throws Exception {
|
public void testGetRequestByNameWithURI() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
final String message = Request.create("GET", new URI(baseURL + "/")).execute().returnContent().asString();
|
final String message = Request.create("GET", new URI(baseURL + "/")).execute().returnContent().asString();
|
||||||
Assertions.assertEquals("All is well", message);
|
Assertions.assertEquals("All is well", message);
|
||||||
|
@ -123,7 +124,7 @@ public class TestFluent {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequestFailure() throws Exception {
|
public void testGetRequestFailure() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
Assertions.assertThrows(ClientProtocolException.class, () ->
|
Assertions.assertThrows(ClientProtocolException.class, () ->
|
||||||
Request.get(baseURL + "/boom").execute().returnContent().asString());
|
Request.get(baseURL + "/boom").execute().returnContent().asString());
|
||||||
|
@ -131,7 +132,7 @@ public class TestFluent {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRequest() throws Exception {
|
public void testPostRequest() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
final String message1 = Request.post(baseURL + "/echo")
|
final String message1 = Request.post(baseURL + "/echo")
|
||||||
.bodyString("what is up?", ContentType.TEXT_PLAIN)
|
.bodyString("what is up?", ContentType.TEXT_PLAIN)
|
||||||
|
@ -145,7 +146,7 @@ public class TestFluent {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContentAsStringWithCharset() throws Exception {
|
public void testContentAsStringWithCharset() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
final Content content = Request.post(baseURL + "/echo").bodyByteArray("Ü".getBytes(StandardCharsets.UTF_8)).execute()
|
final Content content = Request.post(baseURL + "/echo").bodyByteArray("Ü".getBytes(StandardCharsets.UTF_8)).execute()
|
||||||
.returnContent();
|
.returnContent();
|
||||||
|
@ -156,7 +157,7 @@ public class TestFluent {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionRelease() throws Exception {
|
public void testConnectionRelease() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
Request.get(baseURL + "/").execute().returnContent();
|
Request.get(baseURL + "/").execute().returnContent();
|
||||||
|
@ -183,7 +184,7 @@ public class TestFluent {
|
||||||
@Test
|
@Test
|
||||||
public void testLargeResponse() throws Exception {
|
public void testLargeResponse() throws Exception {
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
|
|
||||||
final Content content = Request.get(baseURL + "/large-message").execute().returnContent();
|
final Content content = Request.get(baseURL + "/large-message").execute().returnContent();
|
||||||
|
@ -192,7 +193,7 @@ public class TestFluent {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLargeResponseError() throws Exception {
|
public void testLargeResponseError() throws Exception {
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
final String baseURL = "http://localhost:" + target.getPort();
|
final String baseURL = "http://localhost:" + target.getPort();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClientBuilder;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestServer;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestServerBootstrap;
|
||||||
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
public abstract class AbstractIntegrationTestBase {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources;
|
||||||
|
|
||||||
|
protected AbstractIntegrationTestBase(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel) {
|
||||||
|
this.testResources = new TestClientResources(scheme, clientProtocolLevel, TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public URIScheme scheme() {
|
||||||
|
return testResources.scheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientProtocolLevel getClientProtocolLevel() {
|
||||||
|
return testResources.getClientProtocolLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureServer(final Consumer<TestServerBootstrap> serverCustomizer) {
|
||||||
|
testResources.configureServer(serverCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHost startServer() throws Exception {
|
||||||
|
final TestServer server = testResources.server();
|
||||||
|
final InetSocketAddress inetSocketAddress = server.start();
|
||||||
|
return new HttpHost(testResources.scheme().id, "localhost", inetSocketAddress.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureClient(final Consumer<TestClientBuilder> clientCustomizer) {
|
||||||
|
testResources.configureClient(clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestClient client() throws Exception {
|
||||||
|
return testResources.client();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,35 +27,31 @@
|
||||||
package org.apache.hc.client5.testing.sync;
|
package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
|
||||||
import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
|
import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.testing.classic.RandomHandler;
|
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
public class TestBasicConnectionManager {
|
public class TestBasicConnectionManager extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
public TestBasicConnectionManager() {
|
||||||
|
super(URIScheme.HTTP, ClientProtocolLevel.STANDARD);
|
||||||
@RegisterExtension
|
}
|
||||||
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasics() throws Exception {
|
public void testBasics() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = testResources.targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setConnectionManager(new BasicHttpClientConnectionManager())
|
.setConnectionManager(new BasicHttpClientConnectionManager()));
|
||||||
);
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet get = new HttpGet("/random/1024");
|
final HttpGet get = new HttpGet("/random/1024");
|
||||||
client.execute(target, get, response -> {
|
client.execute(target, get, response -> {
|
||||||
|
@ -67,13 +63,13 @@ public class TestBasicConnectionManager {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionStillInUse() throws Exception {
|
public void testConnectionStillInUse() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = testResources.targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setConnectionManager(new BasicHttpClientConnectionManager())
|
.setConnectionManager(new BasicHttpClientConnectionManager()));
|
||||||
);
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet get1 = new HttpGet("/random/1024");
|
final HttpGet get1 = new HttpGet("/random/1024");
|
||||||
client.executeOpen(target, get1, null);
|
client.executeOpen(target, get1, null);
|
||||||
|
|
|
@ -58,15 +58,15 @@ import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
|
||||||
import org.apache.hc.client5.http.impl.auth.BasicScheme;
|
import org.apache.hc.client5.http.impl.auth.BasicScheme;
|
||||||
import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
|
import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
|
||||||
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||||
import org.apache.hc.client5.testing.auth.BearerAuthenticationHandler;
|
import org.apache.hc.client5.testing.auth.BearerAuthenticationHandler;
|
||||||
import org.apache.hc.client5.testing.classic.AuthenticatingDecorator;
|
import org.apache.hc.client5.testing.classic.AuthenticatingDecorator;
|
||||||
import org.apache.hc.client5.testing.classic.EchoHandler;
|
import org.apache.hc.client5.testing.classic.EchoHandler;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestServerBootstrap;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.HeaderElements;
|
import org.apache.hc.core5.http.HeaderElements;
|
||||||
|
@ -77,10 +77,8 @@ import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.config.Registry;
|
import org.apache.hc.core5.http.config.Registry;
|
||||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
||||||
|
@ -88,62 +86,42 @@ import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.http.support.BasicResponseBuilder;
|
import org.apache.hc.core5.http.support.BasicResponseBuilder;
|
||||||
import org.apache.hc.core5.net.URIAuthority;
|
import org.apache.hc.core5.net.URIAuthority;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for automatic client authentication.
|
* Unit tests for automatic client authentication.
|
||||||
*/
|
*/
|
||||||
public abstract class TestClientAuthentication {
|
public abstract class TestClientAuthentication extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
private TestClientResources testResources;
|
|
||||||
|
|
||||||
protected TestClientAuthentication(final URIScheme scheme) {
|
protected TestClientAuthentication(final URIScheme scheme) {
|
||||||
this.testResources = new TestClientResources(scheme, TIMEOUT);
|
super(scheme, ClientProtocolLevel.STANDARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URIScheme scheme() {
|
public void configureServerWithBasicAuth(final Authenticator authenticator,
|
||||||
return testResources.scheme();
|
final Consumer<TestServerBootstrap> serverCustomizer) throws IOException {
|
||||||
|
configureServer(bootstrap -> {
|
||||||
|
bootstrap.setExchangeHandlerDecorator(requestHandler ->
|
||||||
|
new AuthenticatingDecorator(requestHandler, authenticator));
|
||||||
|
serverCustomizer.accept(bootstrap);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassicTestServer startServer(final Authenticator authenticator) throws IOException {
|
public void configureServerWithBasicAuth(final Consumer<TestServerBootstrap> serverCustomizer) throws IOException {
|
||||||
return testResources.startServer(
|
configureServerWithBasicAuth(
|
||||||
null,
|
new BasicTestAuthenticator("test:test", "test realm"),
|
||||||
null,
|
serverCustomizer);
|
||||||
requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassicTestServer startServer() throws IOException {
|
|
||||||
return startServer(new BasicTestAuthenticator("test:test", "test realm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
return testResources.startClient(clientCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient() throws Exception {
|
|
||||||
return testResources.startClient(builder -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
return testResources.targetHost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationNoCreds() throws Exception {
|
public void testBasicAuthenticationNoCreds() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -163,11 +141,11 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailure() throws Exception {
|
public void testBasicAuthenticationFailure() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -189,11 +167,11 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccess() throws Exception {
|
public void testBasicAuthenticationSuccess() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -214,11 +192,11 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
|
public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setExpectContinueEnabled(true)
|
.setExpectContinueEnabled(true)
|
||||||
|
@ -227,8 +205,8 @@ public abstract class TestClientAuthentication {
|
||||||
httpput.setConfig(config);
|
httpput.setConfig(config);
|
||||||
httpput.setEntity(new InputStreamEntity(
|
httpput.setEntity(new InputStreamEntity(
|
||||||
new ByteArrayInputStream(
|
new ByteArrayInputStream(
|
||||||
new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
|
new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}),
|
||||||
-1, null));
|
-1, null));
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
|
||||||
|
@ -245,19 +223,19 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
|
public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(false).build();
|
final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(false).build();
|
||||||
final HttpPut httpput = new HttpPut("/");
|
final HttpPut httpput = new HttpPut("/");
|
||||||
httpput.setConfig(config);
|
httpput.setConfig(config);
|
||||||
httpput.setEntity(new InputStreamEntity(
|
httpput.setEntity(new InputStreamEntity(
|
||||||
new ByteArrayInputStream(
|
new ByteArrayInputStream(
|
||||||
new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
|
new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}),
|
||||||
-1, null));
|
-1, null));
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -276,11 +254,11 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
|
public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpPost httppost = new HttpPost("/");
|
final HttpPost httppost = new HttpPost("/");
|
||||||
httppost.setEntity(new StringEntity("some important stuff", StandardCharsets.US_ASCII));
|
httppost.setEntity(new StringEntity("some important stuff", StandardCharsets.US_ASCII));
|
||||||
|
@ -304,16 +282,16 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception {
|
public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpPost httppost = new HttpPost("/");
|
final HttpPost httppost = new HttpPost("/");
|
||||||
httppost.setEntity(new InputStreamEntity(
|
httppost.setEntity(new InputStreamEntity(
|
||||||
new ByteArrayInputStream(
|
new ByteArrayInputStream(
|
||||||
new byte[] { 0,1,2,3,4,5,6,7,8,9 }), -1, null));
|
new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), -1, null));
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setRequestConfig(RequestConfig.custom()
|
context.setRequestConfig(RequestConfig.custom()
|
||||||
|
@ -335,17 +313,18 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setTargetAuthenticationStrategy(authStrategy)
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
.addResponseInterceptorLast((response, entity, context)
|
.addResponseInterceptorLast((response, entity, context)
|
||||||
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
||||||
|
@ -372,17 +351,18 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServerWithBasicAuth(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setTargetAuthenticationStrategy(authStrategy)
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
.addResponseInterceptorLast((response, entity, context)
|
.addResponseInterceptorLast((response, entity, context)
|
||||||
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(target, "test", "test".toCharArray())
|
.add(target, "test", "test".toCharArray())
|
||||||
|
@ -393,7 +373,7 @@ public abstract class TestClientAuthentication {
|
||||||
context.setAuthCache(authCache);
|
context.setAuthCache(authCache);
|
||||||
context.setCredentialsProvider(credentialsProvider);
|
context.setCredentialsProvider(credentialsProvider);
|
||||||
|
|
||||||
for (final String requestPath: new String[] {"/blah/a", "/blah/b?huh", "/blah/c", "/bl%61h/%61"}) {
|
for (final String requestPath : new String[]{"/blah/a", "/blah/b?huh", "/blah/c", "/bl%61h/%61"}) {
|
||||||
final HttpGet httpget = new HttpGet(requestPath);
|
final HttpGet httpget = new HttpGet(requestPath);
|
||||||
client.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
|
@ -415,7 +395,7 @@ public abstract class TestClientAuthentication {
|
||||||
authCache.clear();
|
authCache.clear();
|
||||||
Mockito.reset(authStrategy);
|
Mockito.reset(authStrategy);
|
||||||
|
|
||||||
for (final String requestPath: new String[] {"/blah/a", "/yada/a", "/blah/blah/", "/buh/a"}) {
|
for (final String requestPath : new String[]{"/blah/a", "/yada/a", "/blah/blah/", "/buh/a"}) {
|
||||||
final HttpGet httpget = new HttpGet(requestPath);
|
final HttpGet httpget = new HttpGet(requestPath);
|
||||||
client.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
|
@ -436,7 +416,7 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationCredentialsCachingReAuthenticationOnDifferentRealm() throws Exception {
|
public void testAuthenticationCredentialsCachingReAuthenticationOnDifferentRealm() throws Exception {
|
||||||
final ClassicTestServer server = startServer(new Authenticator() {
|
configureServerWithBasicAuth(new Authenticator() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
||||||
|
@ -460,15 +440,15 @@ public abstract class TestClientAuthentication {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}, bootstrap -> bootstrap.register("*", new EchoHandler()));
|
||||||
server.registerHandler("*", new EchoHandler());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setTargetAuthenticationStrategy(authStrategy)
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
);
|
);
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(new AuthScope(target, "this realm", null), "test", "this".toCharArray())
|
.add(new AuthScope(target, "this realm", null), "test", "this".toCharArray())
|
||||||
|
@ -513,12 +493,12 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRequest() throws Exception {
|
public void testAuthenticationUserinfoInRequest() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpGet httpget = new HttpGet("http://test:test@" + target.toHostString() + "/");
|
final HttpGet httpget = new HttpGet("http://test:test@" + target.toHostString() + "/");
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
Assertions.assertThrows(ClientProtocolException.class, () -> client.execute(target, httpget, context, response -> null));
|
Assertions.assertThrows(ClientProtocolException.class, () -> client.execute(target, httpget, context, response -> null));
|
||||||
|
@ -527,11 +507,12 @@ public abstract class TestClientAuthentication {
|
||||||
@Test
|
@Test
|
||||||
public void testPreemptiveAuthentication() throws Exception {
|
public void testPreemptiveAuthentication() throws Exception {
|
||||||
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
||||||
final ClassicTestServer server = startServer(authenticator);
|
configureServerWithBasicAuth(authenticator,
|
||||||
server.registerHandler("*", new EchoHandler());
|
bootstrap -> bootstrap
|
||||||
final HttpHost target = targetHost();
|
.register("*", new EchoHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final BasicScheme basicScheme = new BasicScheme();
|
final BasicScheme basicScheme = new BasicScheme();
|
||||||
basicScheme.initPreemptive(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
basicScheme.initPreemptive(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
|
@ -555,11 +536,12 @@ public abstract class TestClientAuthentication {
|
||||||
@Test
|
@Test
|
||||||
public void testPreemptiveAuthenticationFailure() throws Exception {
|
public void testPreemptiveAuthenticationFailure() throws Exception {
|
||||||
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
||||||
final ClassicTestServer server = startServer(authenticator);
|
configureServerWithBasicAuth(authenticator,
|
||||||
server.registerHandler("*", new EchoHandler());
|
bootstrap -> bootstrap
|
||||||
final HttpHost target = targetHost();
|
.register("*", new EchoHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final AuthCache authCache = new BasicAuthCache();
|
final AuthCache authCache = new BasicAuthCache();
|
||||||
|
@ -602,11 +584,11 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationTargetAsProxy() throws Exception {
|
public void testAuthenticationTargetAsProxy() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new ProxyAuthHandler());
|
.register("*", new ProxyAuthHandler()));
|
||||||
final HttpHost target = testResources.targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(builder -> {});
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -623,22 +605,22 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
|
public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(
|
configureServer(bootstrap -> bootstrap
|
||||||
Http1Config.DEFAULT,
|
.setExchangeHandlerDecorator(requestHandler ->
|
||||||
HttpProcessors.server(),
|
new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||||
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
||||||
|
@ -701,28 +683,29 @@ public abstract class TestClientAuthentication {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final ClassicTestServer server = testResources.startServer(
|
configureServer(bootstrap -> bootstrap
|
||||||
Http1Config.DEFAULT,
|
.setExchangeHandlerDecorator(requestHandler ->
|
||||||
HttpProcessors.server(),
|
new AuthenticatingDecorator(requestHandler, authenticator) {
|
||||||
requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator) {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||||
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient(builder -> builder
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
configureClient(builder -> builder
|
||||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||||
.setDefaultCredentialsProvider(credsProvider)
|
|
||||||
);
|
);
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
context.setCredentialsProvider(credsProvider);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
httpget.setConfig(config);
|
httpget.setConfig(config);
|
||||||
|
@ -738,22 +721,22 @@ public abstract class TestClientAuthentication {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationFallback() throws Exception {
|
public void testAuthenticationFallback() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(
|
configureServer(bootstrap -> bootstrap
|
||||||
Http1Config.DEFAULT,
|
.setExchangeHandlerDecorator(requestHandler ->
|
||||||
HttpProcessors.server(),
|
new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -784,17 +767,18 @@ public abstract class TestClientAuthentication {
|
||||||
buf.append(CHARS.charAt(secureRandom.nextInt(CHARS.length() - 1)));
|
buf.append(CHARS.charAt(secureRandom.nextInt(CHARS.length() - 1)));
|
||||||
}
|
}
|
||||||
final String token = buf.toString();
|
final String token = buf.toString();
|
||||||
final ClassicTestServer server = testResources.startServer(
|
configureServer(bootstrap -> bootstrap
|
||||||
Http1Config.DEFAULT,
|
.setExchangeHandlerDecorator(requestHandler ->
|
||||||
HttpProcessors.server(),
|
new AuthenticatingDecorator(
|
||||||
requestHandler -> new AuthenticatingDecorator(
|
requestHandler,
|
||||||
requestHandler,
|
new BearerAuthenticationHandler(),
|
||||||
new BearerAuthenticationHandler(),
|
new BasicTestAuthenticator(token, "test realm"))
|
||||||
new BasicTestAuthenticator(token, "test realm")));
|
)
|
||||||
server.registerHandler("*", new EchoHandler());
|
.register("*", new EchoHandler()));
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
|
||||||
|
|
|
@ -33,17 +33,16 @@ import java.util.Random;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.protocol.RedirectLocations;
|
import org.apache.hc.client5.http.protocol.RedirectLocations;
|
||||||
import org.apache.hc.client5.http.utils.URIUtils;
|
import org.apache.hc.client5.http.utils.URIUtils;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
|
@ -64,46 +63,18 @@ import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client protocol handling tests.
|
* Client protocol handling tests.
|
||||||
*/
|
*/
|
||||||
public abstract class TestClientRequestExecution {
|
public abstract class TestClientRequestExecution extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
public TestClientRequestExecution(final URIScheme scheme) {
|
||||||
|
super(scheme, ClientProtocolLevel.STANDARD);
|
||||||
@RegisterExtension
|
|
||||||
private TestClientResources testResources;
|
|
||||||
|
|
||||||
protected TestClientRequestExecution(final URIScheme scheme) {
|
|
||||||
this.testResources = new TestClientResources(scheme, TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public URIScheme scheme() {
|
|
||||||
return testResources.scheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassicTestServer startServer() throws IOException {
|
|
||||||
return testResources.startServer(null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
return testResources.startClient(clientCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient() throws Exception {
|
|
||||||
return testResources.startClient(builder -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
return testResources.targetHost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SimpleService implements HttpRequestHandler {
|
private static class SimpleService implements HttpRequestHandler {
|
||||||
|
@ -161,9 +132,8 @@ public abstract class TestClientRequestExecution {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutoGeneratedHeaders() throws Exception {
|
public void testAutoGeneratedHeaders() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final HttpRequestInterceptor interceptor = (request, entityDetails, context) -> request.addHeader("my-header", "stuff");
|
final HttpRequestInterceptor interceptor = (request, entityDetails, context) -> request.addHeader("my-header", "stuff");
|
||||||
|
|
||||||
|
@ -196,11 +166,12 @@ public abstract class TestClientRequestExecution {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.addRequestInterceptorFirst(interceptor)
|
.addRequestInterceptorFirst(interceptor)
|
||||||
.setRequestExecutor(new FaultyHttpRequestExecutor("Oppsie"))
|
.setRequestExecutor(new FaultyHttpRequestExecutor("Oppsie"))
|
||||||
.setRetryStrategy(requestRetryStrategy)
|
.setRetryStrategy(requestRetryStrategy)
|
||||||
);
|
);
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -221,9 +192,8 @@ public abstract class TestClientRequestExecution {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonRepeatableEntity() throws Exception {
|
public void testNonRepeatableEntity() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
|
final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
|
||||||
|
|
||||||
|
@ -254,10 +224,11 @@ public abstract class TestClientRequestExecution {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setRequestExecutor(new FaultyHttpRequestExecutor("a message showing that this failed"))
|
.setRequestExecutor(new FaultyHttpRequestExecutor("a message showing that this failed"))
|
||||||
.setRetryStrategy(requestRetryStrategy)
|
.setRetryStrategy(requestRetryStrategy)
|
||||||
);
|
);
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -272,11 +243,10 @@ public abstract class TestClientRequestExecution {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonCompliantURI() throws Exception {
|
public void testNonCompliantURI() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "{{|boom|}}");
|
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "{{|boom|}}");
|
||||||
|
@ -293,11 +263,10 @@ public abstract class TestClientRequestExecution {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRequestURIWithFragment() throws Exception {
|
public void testRelativeRequestURIWithFragment() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/stuff#blahblah");
|
final HttpGet httpget = new HttpGet("/stuff#blahblah");
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -314,11 +283,10 @@ public abstract class TestClientRequestExecution {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAbsoluteRequestURIWithFragment() throws Exception {
|
public void testAbsoluteRequestURIWithFragment() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final URI uri = new URIBuilder()
|
final URI uri = new URIBuilder()
|
||||||
.setHost(target.getHostName())
|
.setHost(target.getHostName())
|
||||||
|
@ -347,13 +315,12 @@ public abstract class TestClientRequestExecution {
|
||||||
@Test @Disabled("Fails intermittently with GitHub Actions")
|
@Test @Disabled("Fails intermittently with GitHub Actions")
|
||||||
public void testRequestCancellation() throws Exception {
|
public void testRequestCancellation() throws Exception {
|
||||||
startServer();
|
startServer();
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
final TestClient client = client();
|
||||||
builder -> builder
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
.setMaxConnPerRoute(1)
|
connManager.setMaxTotal(1);
|
||||||
.setMaxConnTotal(1),
|
connManager.setDefaultMaxPerRoute(1);
|
||||||
builder -> {});
|
|
||||||
|
|
||||||
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -32,13 +32,14 @@ import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.HttpRoute;
|
import org.apache.hc.client5.http.HttpRoute;
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
|
||||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||||
import org.apache.hc.client5.http.io.ConnectionEndpoint;
|
import org.apache.hc.client5.http.io.ConnectionEndpoint;
|
||||||
import org.apache.hc.client5.http.io.LeaseRequest;
|
import org.apache.hc.client5.http.io.LeaseRequest;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.classic.RandomHandler;
|
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
|
@ -56,24 +57,21 @@ import org.apache.hc.core5.http.protocol.RequestContent;
|
||||||
import org.apache.hc.core5.http.protocol.RequestTargetHost;
|
import org.apache.hc.core5.http.protocol.RequestTargetHost;
|
||||||
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
||||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@code PoolingHttpClientConnectionManager} that do require a server
|
* Tests for {@code PoolingHttpClientConnectionManager} that do require a server
|
||||||
* to communicate with.
|
* to communicate with.
|
||||||
*/
|
*/
|
||||||
public class TestConnectionManagement {
|
public class TestConnectionManagement extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
public TestConnectionManagement() {
|
||||||
|
super(URIScheme.HTTP, ClientProtocolLevel.STANDARD);
|
||||||
@RegisterExtension
|
}
|
||||||
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
|
||||||
|
|
||||||
ConnectionEndpoint.RequestExecutor exec;
|
ConnectionEndpoint.RequestExecutor exec;
|
||||||
|
|
||||||
|
@ -97,30 +95,17 @@ public class TestConnectionManagement {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassicTestServer startServer() throws IOException {
|
|
||||||
return testResources.startServer(null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient() throws Exception {
|
|
||||||
return testResources.startClient(b -> {}, b -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
return testResources.targetHost();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests releasing and re-using a connection after a response is read.
|
* Tests releasing and re-using a connection after a response is read.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReleaseConnection() throws Exception {
|
public void testReleaseConnection() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
startClient();
|
final TestClient client = client();
|
||||||
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
connManager.setMaxTotal(1);
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
|
@ -178,13 +163,12 @@ public class TestConnectionManagement {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReleaseConnectionWithTimeLimits() throws Exception {
|
public void testReleaseConnectionWithTimeLimits() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
startClient();
|
final TestClient client = client();
|
||||||
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
connManager.setMaxTotal(1);
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
|
@ -250,11 +234,9 @@ public class TestConnectionManagement {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCloseExpiredIdleConnections() throws Exception {
|
public void testCloseExpiredIdleConnections() throws Exception {
|
||||||
startServer();
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = targetHost();
|
final TestClient client = client();
|
||||||
startClient();
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
connManager.setMaxTotal(1);
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
|
@ -292,22 +274,21 @@ public class TestConnectionManagement {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCloseExpiredTTLConnections() throws Exception {
|
public void testCloseExpiredTTLConnections() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
testResources.startClient(
|
configureClient(builder -> builder
|
||||||
builder -> builder
|
.setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
|
||||||
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
|
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
|
||||||
.setConnPoolPolicy(PoolReusePolicy.LIFO)
|
.setConnPoolPolicy(PoolReusePolicy.LIFO)
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
||||||
.setTimeToLive(TimeValue.ofMilliseconds(100))
|
.setTimeToLive(TimeValue.ofMilliseconds(100))
|
||||||
.build())
|
.build())
|
||||||
.setMaxConnTotal(1),
|
.build()));
|
||||||
builder -> {}
|
final TestClient client = client();
|
||||||
);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
connManager.setMaxTotal(1);
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
|
|
|
@ -39,7 +39,8 @@ import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.testing.classic.RandomHandler;
|
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.EntityDetails;
|
import org.apache.hc.core5.http.EntityDetails;
|
||||||
|
@ -55,39 +56,25 @@ import org.apache.hc.core5.http.impl.HttpProcessors;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
public class TestConnectionReuse {
|
public class TestConnectionReuse extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
public TestConnectionReuse() {
|
||||||
|
super(URIScheme.HTTP, ClientProtocolLevel.STANDARD);
|
||||||
@RegisterExtension
|
|
||||||
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
return testResources.targetHost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReuseOfPersistentConnections() throws Exception {
|
public void testReuseOfPersistentConnections() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer( null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
final TestClient client = client();
|
||||||
builder -> builder
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
.setMaxConnTotal(5)
|
connManager.setMaxTotal(5);
|
||||||
.setMaxConnPerRoute(5),
|
connManager.setDefaultMaxPerRoute(5);
|
||||||
builder -> {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
|
|
||||||
final WorkerThread[] workers = new WorkerThread[10];
|
final WorkerThread[] workers = new WorkerThread[10];
|
||||||
for (int i = 0; i < workers.length; i++) {
|
for (int i = 0; i < workers.length; i++) {
|
||||||
|
@ -117,19 +104,14 @@ public class TestConnectionReuse {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReuseOfPersistentConnectionsWithStreamedRequestAndResponse() throws Exception {
|
public void testReuseOfPersistentConnectionsWithStreamedRequestAndResponse() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer( null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
final TestClient client = client();
|
||||||
builder -> builder
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
.setMaxConnTotal(5)
|
connManager.setMaxTotal(5);
|
||||||
.setMaxConnPerRoute(5),
|
connManager.setDefaultMaxPerRoute(5);
|
||||||
builder -> {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
|
|
||||||
final WorkerThread[] workers = new WorkerThread[10];
|
final WorkerThread[] workers = new WorkerThread[10];
|
||||||
for (int i = 0; i < workers.length; i++) {
|
for (int i = 0; i < workers.length; i++) {
|
||||||
|
@ -176,21 +158,16 @@ public class TestConnectionReuse {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReuseOfClosedConnections() throws Exception {
|
public void testReuseOfClosedConnections() throws Exception {
|
||||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
configureServer(bootstrap -> bootstrap
|
||||||
.add(new AlwaysCloseConn())
|
.setHttpProcessor(HttpProcessors.customServer(null)
|
||||||
.build();
|
.add(new AlwaysCloseConn())
|
||||||
final ClassicTestServer server = testResources.startServer( null, httpproc, null);
|
.build()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
final TestClient client = client();
|
||||||
builder -> builder
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
.setMaxConnTotal(5)
|
connManager.setMaxTotal(5);
|
||||||
.setMaxConnPerRoute(5),
|
connManager.setDefaultMaxPerRoute(5);
|
||||||
builder -> {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
|
|
||||||
final WorkerThread[] workers = new WorkerThread[10];
|
final WorkerThread[] workers = new WorkerThread[10];
|
||||||
for (int i = 0; i < workers.length; i++) {
|
for (int i = 0; i < workers.length; i++) {
|
||||||
|
@ -220,19 +197,14 @@ public class TestConnectionReuse {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReuseOfAbortedConnections() throws Exception {
|
public void testReuseOfAbortedConnections() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer( null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
final TestClient client = client();
|
||||||
builder -> builder
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
.setMaxConnTotal(5)
|
connManager.setMaxTotal(5);
|
||||||
.setMaxConnPerRoute(5),
|
connManager.setDefaultMaxPerRoute(5);
|
||||||
builder -> {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
|
|
||||||
final WorkerThread[] workers = new WorkerThread[10];
|
final WorkerThread[] workers = new WorkerThread[10];
|
||||||
for (int i = 0; i < workers.length; i++) {
|
for (int i = 0; i < workers.length; i++) {
|
||||||
|
@ -262,23 +234,17 @@ public class TestConnectionReuse {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testKeepAliveHeaderRespected() throws Exception {
|
public void testKeepAliveHeaderRespected() throws Exception {
|
||||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
configureServer(bootstrap -> bootstrap
|
||||||
.add(new ResponseKeepAlive())
|
.setHttpProcessor(HttpProcessors.customServer(null)
|
||||||
.build();
|
.add(new ResponseKeepAlive())
|
||||||
final ClassicTestServer server = testResources.startServer( null, httpproc, null);
|
.build())
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
|
||||||
builder -> builder
|
|
||||||
.setMaxConnTotal(1)
|
|
||||||
.setMaxConnPerRoute(1),
|
|
||||||
builder -> {
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
|
||||||
|
|
||||||
|
final TestClient client = client();
|
||||||
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
|
connManager.setMaxTotal(1);
|
||||||
|
connManager.setDefaultMaxPerRoute(1);
|
||||||
|
|
||||||
client.execute(target, new HttpGet("/random/2000"), response -> {
|
client.execute(target, new HttpGet("/random/2000"), response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
|
|
|
@ -38,16 +38,15 @@ import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.zip.Deflater;
|
import java.util.zip.Deflater;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
|
import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.HeaderElement;
|
import org.apache.hc.core5.http.HeaderElement;
|
||||||
|
@ -61,46 +60,18 @@ import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.message.MessageSupport;
|
import org.apache.hc.core5.http.message.MessageSupport;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test case for how Content Codings are processed. By default, we want to do the right thing and
|
* Test case for how Content Codings are processed. By default, we want to do the right thing and
|
||||||
* require no intervention from the user of HttpClient, but we still want to let clients do their
|
* require no intervention from the user of HttpClient, but we still want to let clients do their
|
||||||
* own thing if they so wish.
|
* own thing if they so wish.
|
||||||
*/
|
*/
|
||||||
public abstract class TestContentCodings {
|
public abstract class TestContentCodings extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
private TestClientResources testResources;
|
|
||||||
|
|
||||||
protected TestContentCodings(final URIScheme scheme) {
|
protected TestContentCodings(final URIScheme scheme) {
|
||||||
this.testResources = new TestClientResources(scheme, TIMEOUT);
|
super(scheme, ClientProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
public URIScheme scheme() {
|
|
||||||
return testResources.scheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassicTestServer startServer() throws IOException {
|
|
||||||
return testResources.startServer(null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
return testResources.startClient(clientCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient() throws Exception {
|
|
||||||
return testResources.startClient(builder -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
return testResources.targetHost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,24 +83,24 @@ public abstract class TestContentCodings {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testResponseWithNoContent() throws Exception {
|
public void testResponseWithNoContent() throws Exception {
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new HttpRequestHandler() {
|
.register("*", new HttpRequestHandler() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void handle(
|
public void handle(
|
||||||
final ClassicHttpRequest request,
|
final ClassicHttpRequest request,
|
||||||
final ClassicHttpResponse response,
|
final ClassicHttpResponse response,
|
||||||
final HttpContext context) throws HttpException, IOException {
|
final HttpContext context) throws HttpException, IOException {
|
||||||
response.setCode(HttpStatus.SC_NO_CONTENT);
|
response.setCode(HttpStatus.SC_NO_CONTENT);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
client.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
|
@ -149,12 +120,12 @@ public abstract class TestContentCodings {
|
||||||
public void testDeflateSupportForServerReturningRfc1950Stream() throws Exception {
|
public void testDeflateSupportForServerReturningRfc1950Stream() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
.register("*", createDeflateEncodingRequestHandler(entityText, false)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
client.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
|
@ -174,12 +145,12 @@ public abstract class TestContentCodings {
|
||||||
public void testDeflateSupportForServerReturningRfc1951Stream() throws Exception {
|
public void testDeflateSupportForServerReturningRfc1951Stream() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
.register("*", createDeflateEncodingRequestHandler(entityText, true)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
client.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
|
@ -198,12 +169,12 @@ public abstract class TestContentCodings {
|
||||||
public void testGzipSupport() throws Exception {
|
public void testGzipSupport() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
.register("*", createGzipEncodingRequestHandler(entityText)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
client.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
|
@ -223,13 +194,13 @@ public abstract class TestContentCodings {
|
||||||
public void testThreadSafetyOfContentCodings() throws Exception {
|
public void testThreadSafetyOfContentCodings() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
.register("*", createGzipEncodingRequestHandler(entityText)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a load of workers which will access the resource. Half will use the default
|
* Create a load of workers which will access the resource. Half will use the default
|
||||||
|
@ -273,12 +244,12 @@ public abstract class TestContentCodings {
|
||||||
public void testHttpEntityWriteToForGzip() throws Exception {
|
public void testHttpEntityWriteToForGzip() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
.register("*", createGzipEncodingRequestHandler(entityText)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
client.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
|
@ -294,12 +265,12 @@ public abstract class TestContentCodings {
|
||||||
public void testHttpEntityWriteToForDeflate() throws Exception {
|
public void testHttpEntityWriteToForDeflate() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
.register("*", createDeflateEncodingRequestHandler(entityText, true)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
client.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
|
@ -314,12 +285,12 @@ public abstract class TestContentCodings {
|
||||||
public void gzipResponsesWorkWithBasicResponseHandler() throws Exception {
|
public void gzipResponsesWorkWithBasicResponseHandler() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
.register("*", createGzipEncodingRequestHandler(entityText)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
final String response = client.execute(target, request, new BasicHttpClientResponseHandler());
|
final String response = client.execute(target, request, new BasicHttpClientResponseHandler());
|
||||||
|
@ -330,12 +301,12 @@ public abstract class TestContentCodings {
|
||||||
public void deflateResponsesWorkWithBasicResponseHandler() throws Exception {
|
public void deflateResponsesWorkWithBasicResponseHandler() throws Exception {
|
||||||
final String entityText = "Hello, this is some plain text coming back.";
|
final String entityText = "Hello, this is some plain text coming back.";
|
||||||
|
|
||||||
final ClassicTestServer server = startServer();
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
.register("*", createDeflateEncodingRequestHandler(entityText, false)));
|
||||||
|
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
final String response = client.execute(target, request, new BasicHttpClientResponseHandler());
|
final String response = client.execute(target, request, new BasicHttpClientResponseHandler());
|
||||||
|
|
|
@ -33,75 +33,71 @@ import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||||
import org.apache.hc.client5.http.cookie.Cookie;
|
import org.apache.hc.client5.http.cookie.Cookie;
|
||||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.message.BasicHeader;
|
import org.apache.hc.core5.http.message.BasicHeader;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class tests cookie matching when using Virtual Host.
|
* This class tests cookie matching when using Virtual Host.
|
||||||
*/
|
*/
|
||||||
public class TestCookieVirtualHost {
|
public class TestCookieVirtualHost extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
public TestCookieVirtualHost() {
|
||||||
|
super(URIScheme.HTTP, ClientProtocolLevel.STANDARD);
|
||||||
@RegisterExtension
|
}
|
||||||
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCookieMatchingWithVirtualHosts() throws Exception {
|
public void testCookieMatchingWithVirtualHosts() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandlerVirtual("app.mydomain.fr", "*", (request, response, context) -> {
|
.register("app.mydomain.fr", "*", (request, response, context) -> {
|
||||||
|
|
||||||
final int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
|
final int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 1:
|
case 1:
|
||||||
// Assert Host is forwarded from URI
|
// Assert Host is forwarded from URI
|
||||||
Assertions.assertEquals("app.mydomain.fr", request
|
Assertions.assertEquals("app.mydomain.fr", request
|
||||||
.getFirstHeader("Host").getValue());
|
.getFirstHeader("Host").getValue());
|
||||||
|
|
||||||
response.setCode(HttpStatus.SC_OK);
|
response.setCode(HttpStatus.SC_OK);
|
||||||
// Respond with Set-Cookie on virtual host domain. This
|
// Respond with Set-Cookie on virtual host domain. This
|
||||||
// should be valid.
|
// should be valid.
|
||||||
response.addHeader(new BasicHeader("Set-Cookie",
|
response.addHeader(new BasicHeader("Set-Cookie",
|
||||||
"name1=value1; domain=mydomain.fr; path=/"));
|
"name1=value1; domain=mydomain.fr; path=/"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Assert Host is still forwarded from URI
|
// Assert Host is still forwarded from URI
|
||||||
Assertions.assertEquals("app.mydomain.fr", request
|
Assertions.assertEquals("app.mydomain.fr", request
|
||||||
.getFirstHeader("Host").getValue());
|
.getFirstHeader("Host").getValue());
|
||||||
|
|
||||||
// We should get our cookie back.
|
// We should get our cookie back.
|
||||||
Assertions.assertNotNull(request.getFirstHeader("Cookie"), "We must get a cookie header");
|
Assertions.assertNotNull(request.getFirstHeader("Cookie"), "We must get a cookie header");
|
||||||
response.setCode(HttpStatus.SC_OK);
|
response.setCode(HttpStatus.SC_OK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
// Assert Host is forwarded from URI
|
// Assert Host is forwarded from URI
|
||||||
Assertions.assertEquals("app.mydomain.fr", request
|
Assertions.assertEquals("app.mydomain.fr", request
|
||||||
.getFirstHeader("Host").getValue());
|
.getFirstHeader("Host").getValue());
|
||||||
|
|
||||||
response.setCode(HttpStatus.SC_OK);
|
response.setCode(HttpStatus.SC_OK);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Assertions.fail("Unexpected value: " + n);
|
Assertions.fail("Unexpected value: " + n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
final HttpHost target = testResources.targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(b -> {});
|
final TestClient client = client();
|
||||||
|
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
|
@ -35,32 +35,29 @@ import org.apache.hc.client5.http.impl.IdleConnectionEvictor;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.testing.classic.RandomHandler;
|
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
public class TestIdleConnectionEviction {
|
public class TestIdleConnectionEviction extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
public TestIdleConnectionEviction() {
|
||||||
|
super(URIScheme.HTTP, ClientProtocolLevel.STANDARD);
|
||||||
@RegisterExtension
|
}
|
||||||
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIdleConnectionEviction() throws Exception {
|
public void testIdleConnectionEviction() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = testResources.targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(b -> {});
|
final TestClient client = client();
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
final PoolingHttpClientConnectionManager connManager = client.getConnectionManager();
|
||||||
|
|
||||||
connManager.setDefaultMaxPerRoute(10);
|
connManager.setDefaultMaxPerRoute(10);
|
||||||
connManager.setMaxTotal(50);
|
connManager.setMaxTotal(50);
|
||||||
|
|
|
@ -32,9 +32,9 @@ import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.MinimalHttpClient;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
|
@ -47,29 +47,18 @@ import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client protocol handling tests.
|
* Client protocol handling tests.
|
||||||
*/
|
*/
|
||||||
public abstract class TestMinimalClientRequestExecution {
|
public abstract class TestMinimalClientRequestExecution extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
private TestClientResources testResources;
|
|
||||||
|
|
||||||
protected TestMinimalClientRequestExecution(final URIScheme scheme) {
|
protected TestMinimalClientRequestExecution(final URIScheme scheme) {
|
||||||
this.testResources = new TestClientResources(scheme, TIMEOUT);
|
super(scheme, ClientProtocolLevel.MINIMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URIScheme scheme() {
|
|
||||||
return testResources.scheme();
|
|
||||||
}
|
|
||||||
private static class SimpleService implements HttpRequestHandler {
|
private static class SimpleService implements HttpRequestHandler {
|
||||||
|
|
||||||
public SimpleService() {
|
public SimpleService() {
|
||||||
|
@ -89,11 +78,10 @@ public abstract class TestMinimalClientRequestExecution {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonCompliantURIWithContext() throws Exception {
|
public void testNonCompliantURIWithContext() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = testResources.targetHost();
|
|
||||||
|
|
||||||
final MinimalHttpClient client = testResources.startMinimalClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
|
@ -121,11 +109,10 @@ public abstract class TestMinimalClientRequestExecution {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonCompliantURIWithoutContext() throws Exception {
|
public void testNonCompliantURIWithoutContext() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = testResources.targetHost();
|
|
||||||
|
|
||||||
final MinimalHttpClient client = testResources.startMinimalClient();
|
final TestClient client = client();
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
final HttpGet request = new HttpGet("/");
|
final HttpGet request = new HttpGet("/");
|
||||||
|
|
|
@ -33,7 +33,6 @@ import java.net.URI;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.CircularRedirectException;
|
import org.apache.hc.client5.http.CircularRedirectException;
|
||||||
import org.apache.hc.client5.http.ClientProtocolException;
|
import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
|
@ -43,8 +42,6 @@ import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
import org.apache.hc.client5.http.config.RequestConfig;
|
||||||
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
|
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.protocol.RedirectLocations;
|
import org.apache.hc.client5.http.protocol.RedirectLocations;
|
||||||
|
@ -53,7 +50,8 @@ import org.apache.hc.client5.testing.classic.EchoHandler;
|
||||||
import org.apache.hc.client5.testing.classic.RandomHandler;
|
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||||
import org.apache.hc.client5.testing.classic.RedirectingDecorator;
|
import org.apache.hc.client5.testing.classic.RedirectingDecorator;
|
||||||
import org.apache.hc.client5.testing.redirect.Redirect;
|
import org.apache.hc.client5.testing.redirect.Redirect;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
|
@ -69,59 +67,31 @@ import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.message.BasicHeader;
|
import org.apache.hc.core5.http.message.BasicHeader;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirection test cases.
|
* Redirection test cases.
|
||||||
*/
|
*/
|
||||||
public abstract class TestRedirects {
|
public abstract class TestRedirects extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
private TestClientResources testResources;
|
|
||||||
|
|
||||||
protected TestRedirects(final URIScheme scheme) {
|
protected TestRedirects(final URIScheme scheme) {
|
||||||
this.testResources = new TestClientResources(scheme, TIMEOUT);
|
super(scheme, ClientProtocolLevel.STANDARD);
|
||||||
}
|
|
||||||
|
|
||||||
public URIScheme scheme() {
|
|
||||||
return testResources.scheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassicTestServer startServer(final HttpProcessor httpProcessor,
|
|
||||||
final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
|
|
||||||
return testResources.startServer(null, httpProcessor, handlerDecorator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
return testResources.startClient(clientCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient() throws Exception {
|
|
||||||
return testResources.startClient(builder -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
|
||||||
return testResources.targetHost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
requestHandler,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler())
|
||||||
|
);
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
@ -141,14 +111,16 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
requestHandler,
|
||||||
Redirect.ConnControl.CLOSE)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
Redirect.ConnControl.CLOSE)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler())
|
||||||
|
);
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
@ -169,13 +141,14 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301() throws Exception {
|
public void testBasicRedirect301() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
requestHandler,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
@ -200,13 +173,14 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302() throws Exception {
|
public void testBasicRedirect302() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
requestHandler,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/50");
|
final HttpGet httpget = new HttpGet("/oldlocation/50");
|
||||||
|
@ -225,19 +199,20 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302NoLocation() throws Exception {
|
public void testBasicRedirect302NoLocation() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
requestUri -> {
|
requestHandler,
|
||||||
final String path = requestUri.getPath();
|
requestUri -> {
|
||||||
if (path.startsWith("/oldlocation")) {
|
final String path = requestUri.getPath();
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
if (path.startsWith("/oldlocation")) {
|
||||||
}
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
||||||
return null;
|
}
|
||||||
}));
|
return null;
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
}))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
@ -255,13 +230,14 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect303() throws Exception {
|
public void testBasicRedirect303() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
requestHandler,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/123");
|
final HttpGet httpget = new HttpGet("/oldlocation/123");
|
||||||
|
@ -279,16 +255,15 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect304() throws Exception {
|
public void testBasicRedirect304() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null ,null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/oldlocation/*", (request, response, context) -> {
|
.register("/oldlocation/*", (request, response, context) -> {
|
||||||
response.setCode(HttpStatus.SC_NOT_MODIFIED);
|
response.setCode(HttpStatus.SC_NOT_MODIFIED);
|
||||||
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
||||||
});
|
})
|
||||||
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
final TestClient client = client();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
||||||
|
@ -310,16 +285,15 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect305() throws Exception {
|
public void testBasicRedirect305() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null ,null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("/oldlocation/*", (request, response, context) -> {
|
.register("/oldlocation/*", (request, response, context) -> {
|
||||||
response.setCode(HttpStatus.SC_USE_PROXY);
|
response.setCode(HttpStatus.SC_USE_PROXY);
|
||||||
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
||||||
});
|
})
|
||||||
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
final TestClient client = client();
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
||||||
|
@ -341,13 +315,14 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect307() throws Exception {
|
public void testBasicRedirect307() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
requestHandler,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/123");
|
final HttpGet httpget = new HttpGet("/oldlocation/123");
|
||||||
|
@ -365,14 +340,15 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxRedirectCheck() throws Exception {
|
public void testMaxRedirectCheck() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
requestHandler,
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
HttpStatus.SC_MOVED_TEMPORARILY)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(true)
|
.setCircularRedirectsAllowed(true)
|
||||||
.setMaxRedirects(5)
|
.setMaxRedirects(5)
|
||||||
|
@ -387,14 +363,16 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCircularRedirect() throws Exception {
|
public void testCircularRedirect() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
requestHandler,
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
HttpStatus.SC_MOVED_TEMPORARILY)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
final TestClient client = client();
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(false)
|
.setCircularRedirectsAllowed(false)
|
||||||
.build();
|
.build();
|
||||||
|
@ -408,13 +386,14 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirectSeeOther() throws Exception {
|
public void testPostRedirectSeeOther() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
requestHandler,
|
||||||
server.registerHandler("/echo/*", new EchoHandler());
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)))
|
||||||
final HttpHost target = targetHost();
|
.register("/echo/*", new EchoHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpPost httppost = new HttpPost("/oldlocation/stuff");
|
final HttpPost httppost = new HttpPost("/oldlocation/stuff");
|
||||||
|
@ -434,19 +413,21 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect() throws Exception {
|
public void testRelativeRedirect() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
requestUri -> {
|
requestHandler,
|
||||||
final String path = requestUri.getPath();
|
requestUri -> {
|
||||||
if (path.startsWith("/oldlocation")) {
|
final String path = requestUri.getPath();
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
if (path.startsWith("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
})); server.registerHandler("/random/*", new RandomHandler());
|
}))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
||||||
|
@ -464,20 +445,21 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect2() throws Exception {
|
public void testRelativeRedirect2() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
requestUri -> {
|
requestHandler,
|
||||||
final String path = requestUri.getPath();
|
requestUri -> {
|
||||||
if (path.equals("/random/oldlocation")) {
|
final String path = requestUri.getPath();
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
if (path.equals("/random/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}))
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/random/oldlocation");
|
final HttpGet httpget = new HttpGet("/random/oldlocation");
|
||||||
|
@ -495,20 +477,21 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectBogusRedirectLocation() throws Exception {
|
public void testRejectBogusRedirectLocation() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
requestUri -> {
|
requestHandler,
|
||||||
final String path = requestUri.getPath();
|
requestUri -> {
|
||||||
if (path.equals("/oldlocation")) {
|
final String path = requestUri.getPath();
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
if (path.equals("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}))
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation");
|
final HttpGet httpget = new HttpGet("/oldlocation");
|
||||||
|
|
||||||
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
||||||
|
@ -518,20 +501,21 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
requestUri -> {
|
requestHandler,
|
||||||
final String path = requestUri.getPath();
|
requestUri -> {
|
||||||
if (path.equals("/oldlocation")) {
|
final String path = requestUri.getPath();
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
if (path.equals("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}))
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
.register("/random/*", new RandomHandler()));
|
||||||
final HttpHost target = targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation");
|
final HttpGet httpget = new HttpGet("/oldlocation");
|
||||||
|
|
||||||
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
||||||
|
@ -541,13 +525,14 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedirectWithCookie() throws Exception {
|
public void testRedirectWithCookie() throws Exception {
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
requestHandler,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
final TestClient client = client();
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
|
|
||||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||||
|
@ -577,16 +562,18 @@ public abstract class TestRedirects {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultHeadersRedirect() throws Exception {
|
public void testDefaultHeadersRedirect() throws Exception {
|
||||||
final CloseableHttpClient client = startClient(builder -> builder
|
configureClient(builder -> builder
|
||||||
.setDefaultHeaders(Collections.singletonList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")))
|
.setDefaultHeaders(Collections.singletonList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")))
|
||||||
);
|
);
|
||||||
|
|
||||||
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
configureServer(bootstrap -> bootstrap
|
||||||
requestHandler,
|
.setExchangeHandlerDecorator(requestHandler -> new RedirectingDecorator(
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
requestHandler,
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)))
|
||||||
final HttpHost target = targetHost();
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
|
final TestClient client = client();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
@ -608,33 +595,34 @@ public abstract class TestRedirects {
|
||||||
@Test
|
@Test
|
||||||
public void testCompressionHeaderRedirect() throws Exception {
|
public void testCompressionHeaderRedirect() throws Exception {
|
||||||
final Queue<String> values = new ConcurrentLinkedQueue<>();
|
final Queue<String> values = new ConcurrentLinkedQueue<>();
|
||||||
final ClassicTestServer server = startServer(null, new Decorator<HttpServerRequestHandler>() {
|
configureServer(bootstrap -> bootstrap
|
||||||
|
.setExchangeHandlerDecorator(new Decorator<HttpServerRequestHandler>() {
|
||||||
@Override
|
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)) {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(final ClassicHttpRequest request,
|
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
||||||
final ResponseTrigger responseTrigger,
|
return new RedirectingDecorator(
|
||||||
final HttpContext context) throws HttpException, IOException {
|
requestHandler,
|
||||||
final Header header = request.getHeader(HttpHeaders.ACCEPT_ENCODING);
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)) {
|
||||||
if (header != null) {
|
|
||||||
values.add(header.getValue());
|
@Override
|
||||||
}
|
public void handle(final ClassicHttpRequest request,
|
||||||
super.handle(request, responseTrigger, context);
|
final ResponseTrigger responseTrigger,
|
||||||
|
final HttpContext context) throws HttpException, IOException {
|
||||||
|
final Header header = request.getHeader(HttpHeaders.ACCEPT_ENCODING);
|
||||||
|
if (header != null) {
|
||||||
|
values.add(header.getValue());
|
||||||
|
}
|
||||||
|
super.handle(request, responseTrigger, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
})
|
||||||
}
|
.register("/random/*", new RandomHandler()));
|
||||||
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
});
|
final TestClient client = client();
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
|
||||||
final HttpHost target = targetHost();
|
|
||||||
|
|
||||||
final CloseableHttpClient client = startClient();
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
|
|
@ -31,8 +31,10 @@ import java.io.IOException;
|
||||||
import org.apache.hc.client5.http.UserTokenHandler;
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
import org.apache.hc.client5.testing.sync.extension.ClientProtocolLevel;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClient;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.EndpointDetails;
|
import org.apache.hc.core5.http.EndpointDetails;
|
||||||
|
@ -44,22 +46,20 @@ import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test cases for state-ful connections.
|
* Test cases for state-ful connections.
|
||||||
*/
|
*/
|
||||||
public class TestStatefulConnManagement {
|
public class TestStatefulConnManagement extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
|
||||||
public static final Timeout LONG_TIMEOUT = Timeout.ofMinutes(3);
|
public static final Timeout LONG_TIMEOUT = Timeout.ofMinutes(3);
|
||||||
|
|
||||||
@RegisterExtension
|
public TestStatefulConnManagement() {
|
||||||
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
super(URIScheme.HTTP, ClientProtocolLevel.STANDARD);
|
||||||
|
}
|
||||||
|
|
||||||
private static class SimpleService implements HttpRequestHandler {
|
private static class SimpleService implements HttpRequestHandler {
|
||||||
|
|
||||||
|
@ -80,9 +80,9 @@ public class TestStatefulConnManagement {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatefulConnections() throws Exception {
|
public void testStatefulConnections() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap
|
||||||
server.registerHandler("*", new SimpleService());
|
.register("*", new SimpleService()));
|
||||||
final HttpHost target = testResources.targetHost();
|
final HttpHost target = startServer();
|
||||||
|
|
||||||
final int workerCount = 5;
|
final int workerCount = 5;
|
||||||
final int requestCount = 5;
|
final int requestCount = 5;
|
||||||
|
@ -92,13 +92,13 @@ public class TestStatefulConnManagement {
|
||||||
return id;
|
return id;
|
||||||
};
|
};
|
||||||
|
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
configureClient(builder -> builder
|
||||||
builder -> builder
|
.setUserTokenHandler(userTokenHandler));
|
||||||
.setMaxConnTotal(workerCount)
|
final TestClient client = client();
|
||||||
.setMaxConnPerRoute(workerCount),
|
|
||||||
builder -> builder
|
final PoolingHttpClientConnectionManager connectionManager = client.getConnectionManager();
|
||||||
.setUserTokenHandler(userTokenHandler)
|
connectionManager.setMaxTotal(workerCount);
|
||||||
);
|
connectionManager.setDefaultMaxPerRoute(workerCount);
|
||||||
|
|
||||||
final HttpClientContext[] contexts = new HttpClientContext[workerCount];
|
final HttpClientContext[] contexts = new HttpClientContext[workerCount];
|
||||||
final HttpWorker[] workers = new HttpWorker[workerCount];
|
final HttpWorker[] workers = new HttpWorker[workerCount];
|
||||||
|
@ -194,9 +194,8 @@ public class TestStatefulConnManagement {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRouteSpecificPoolRecylcing() throws Exception {
|
public void testRouteSpecificPoolRecylcing() throws Exception {
|
||||||
final ClassicTestServer server = testResources.startServer(null, null, null);
|
configureServer(bootstrap -> bootstrap.register("*", new SimpleService()));
|
||||||
server.registerHandler("*", new SimpleService());
|
final HttpHost target = startServer();
|
||||||
final HttpHost target = testResources.targetHost();
|
|
||||||
|
|
||||||
// This tests what happens when a maxed connection pool needs
|
// This tests what happens when a maxed connection pool needs
|
||||||
// to kill the last idle connection to a route to build a new
|
// to kill the last idle connection to a route to build a new
|
||||||
|
@ -204,16 +203,13 @@ public class TestStatefulConnManagement {
|
||||||
|
|
||||||
final int maxConn = 2;
|
final int maxConn = 2;
|
||||||
|
|
||||||
|
configureClient(builder -> builder
|
||||||
|
.setUserTokenHandler((route, context) -> context.getAttribute("user")));
|
||||||
|
final TestClient client = client();
|
||||||
|
|
||||||
final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
final PoolingHttpClientConnectionManager connectionManager = client.getConnectionManager();
|
||||||
|
connectionManager.setMaxTotal(maxConn);
|
||||||
final CloseableHttpClient client = testResources.startClient(
|
connectionManager.setDefaultMaxPerRoute(maxConn);
|
||||||
builder -> builder
|
|
||||||
.setMaxConnTotal(maxConn)
|
|
||||||
.setMaxConnPerRoute(maxConn),
|
|
||||||
builder -> builder
|
|
||||||
.setUserTokenHandler(userTokenHandler)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bottom of the pool : a *keep alive* connection to Route 1.
|
// Bottom of the pool : a *keep alive* connection to Route 1.
|
||||||
final HttpContext context1 = HttpClientContext.create();
|
final HttpContext context1 = HttpClientContext.create();
|
||||||
|
@ -232,7 +228,7 @@ public class TestStatefulConnManagement {
|
||||||
// Send a very simple HTTP get (it MUST be simple, no auth, no proxy, no 302, no 401, ...)
|
// Send a very simple HTTP get (it MUST be simple, no auth, no proxy, no 302, no 401, ...)
|
||||||
// Send it to another route. Must be a keepalive.
|
// Send it to another route. Must be a keepalive.
|
||||||
final HttpContext context2 = HttpClientContext.create();
|
final HttpContext context2 = HttpClientContext.create();
|
||||||
client.execute(new HttpHost("127.0.0.1", server.getPort()), new HttpGet("/"), context2, response -> {
|
client.execute(new HttpHost("127.0.0.1", target.getPort()), new HttpGet("/"), context2, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
|
public enum ClientProtocolLevel {
|
||||||
|
|
||||||
|
STANDARD, MINIMAL
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.MinimalHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||||
|
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.http.io.SocketConfig;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
final class MinimalTestClientBuilder implements TestClientBuilder {
|
||||||
|
|
||||||
|
private Timeout timeout;
|
||||||
|
|
||||||
|
private HttpClientConnectionManager connectionManager;
|
||||||
|
|
||||||
|
public MinimalTestClientBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientProtocolLevel getProtocolLevel() {
|
||||||
|
return ClientProtocolLevel.MINIMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setConnectionManager(final HttpClientConnectionManager connectionManager) {
|
||||||
|
this.connectionManager = connectionManager;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClient build() throws Exception {
|
||||||
|
final HttpClientConnectionManager connectionManagerCopy = connectionManager != null ? connectionManager :
|
||||||
|
PoolingHttpClientConnectionManagerBuilder.create()
|
||||||
|
.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||||
|
.setDefaultSocketConfig(SocketConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
||||||
|
.setConnectTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final MinimalHttpClient minimalClient = HttpClients.createMinimal(connectionManagerCopy);
|
||||||
|
return new TestClient(minimalClient, connectionManagerCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.AuthenticationStrategy;
|
||||||
|
import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
||||||
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
|
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||||
|
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.http.Header;
|
||||||
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
|
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
||||||
|
import org.apache.hc.core5.http.io.SocketConfig;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
final class StandardTestClientBuilder implements TestClientBuilder {
|
||||||
|
|
||||||
|
private final HttpClientBuilder clientBuilder;
|
||||||
|
|
||||||
|
private Timeout timeout;
|
||||||
|
|
||||||
|
private HttpClientConnectionManager connectionManager;
|
||||||
|
|
||||||
|
public StandardTestClientBuilder() {
|
||||||
|
this.clientBuilder = HttpClientBuilder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientProtocolLevel getProtocolLevel() {
|
||||||
|
return ClientProtocolLevel.STANDARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setConnectionManager(final HttpClientConnectionManager connectionManager) {
|
||||||
|
this.connectionManager = connectionManager;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder addResponseInterceptorFirst(final HttpResponseInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addResponseInterceptorFirst(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder addResponseInterceptorLast(final HttpResponseInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addResponseInterceptorLast(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder addRequestInterceptorFirst(final HttpRequestInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addRequestInterceptorFirst(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder addRequestInterceptorLast(final HttpRequestInterceptor interceptor) {
|
||||||
|
this.clientBuilder.addRequestInterceptorLast(interceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setUserTokenHandler(final UserTokenHandler userTokenHandler) {
|
||||||
|
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setDefaultHeaders(final Collection<? extends Header> defaultHeaders) {
|
||||||
|
this.clientBuilder.setDefaultHeaders(defaultHeaders);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setRetryStrategy(final HttpRequestRetryStrategy retryStrategy) {
|
||||||
|
this.clientBuilder.setRetryStrategy(retryStrategy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
||||||
|
this.clientBuilder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setDefaultAuthSchemeRegistry(final Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
||||||
|
this.clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClientBuilder setRequestExecutor(final HttpRequestExecutor requestExec) {
|
||||||
|
this.clientBuilder.setRequestExecutor(requestExec);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TestClient build() throws Exception {
|
||||||
|
final HttpClientConnectionManager connectionManagerCopy = connectionManager != null ? connectionManager :
|
||||||
|
PoolingHttpClientConnectionManagerBuilder.create()
|
||||||
|
.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
||||||
|
.setDefaultSocketConfig(SocketConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
||||||
|
.setConnectTimeout(timeout)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = clientBuilder
|
||||||
|
.setConnectionManager(connectionManagerCopy)
|
||||||
|
.build();
|
||||||
|
return new TestClient(client, connectionManagerCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||||
|
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||||
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
|
import org.apache.hc.core5.util.Args;
|
||||||
|
|
||||||
|
public class TestClient extends CloseableHttpClient {
|
||||||
|
|
||||||
|
private final CloseableHttpClient client;
|
||||||
|
private final HttpClientConnectionManager connectionManager;
|
||||||
|
|
||||||
|
public TestClient(final CloseableHttpClient client,
|
||||||
|
final HttpClientConnectionManager connectionManager) {
|
||||||
|
this.client = Args.notNull(client, "Client");
|
||||||
|
this.connectionManager = Args.notNull(connectionManager, "Connection manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(final CloseMode closeMode) {
|
||||||
|
client.close(closeMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CloseableHttpResponse doExecute(final HttpHost target, final ClassicHttpRequest request, final HttpContext context) throws IOException {
|
||||||
|
return CloseableHttpResponse.adapt(client.executeOpen(target, request, context));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends CloseableHttpClient> T getImplementation() {
|
||||||
|
return (T) client;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends HttpClientConnectionManager> T getConnectionManager() {
|
||||||
|
return (T) connectionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.AuthenticationStrategy;
|
||||||
|
import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
||||||
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
|
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||||
|
import org.apache.hc.core5.http.Header;
|
||||||
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
|
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
public interface TestClientBuilder {
|
||||||
|
|
||||||
|
ClientProtocolLevel getProtocolLevel();
|
||||||
|
|
||||||
|
TestClientBuilder setTimeout(Timeout soTimeout);
|
||||||
|
|
||||||
|
TestClientBuilder setConnectionManager(HttpClientConnectionManager connManager);
|
||||||
|
|
||||||
|
default TestClientBuilder addResponseInterceptorFirst(final HttpResponseInterceptor interceptor) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder addResponseInterceptorLast(HttpResponseInterceptor interceptor) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder addRequestInterceptorFirst(HttpRequestInterceptor interceptor) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder addRequestInterceptorLast(HttpRequestInterceptor interceptor) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder setUserTokenHandler(UserTokenHandler userTokenHandler) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder setDefaultHeaders(Collection<? extends Header> defaultHeaders) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder setRetryStrategy(HttpRequestRetryStrategy retryStrategy) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder setDefaultAuthSchemeRegistry(Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
default TestClientBuilder setRequestExecutor(HttpRequestExecutor requestExec) {
|
||||||
|
throw new UnsupportedOperationException("Operation not supported by " + getProtocolLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
TestClient build() throws Exception;
|
||||||
|
|
||||||
|
}
|
|
@ -27,59 +27,46 @@
|
||||||
|
|
||||||
package org.apache.hc.client5.testing.sync.extension;
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
|
||||||
import org.apache.hc.client5.http.impl.classic.MinimalHttpClient;
|
|
||||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.io.SocketConfig;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
import org.apache.hc.core5.util.Asserts;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class TestClientResources implements BeforeEachCallback, AfterEachCallback {
|
public class TestClientResources implements AfterEachCallback {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(TestClientResources.class);
|
private static final Logger LOG = LoggerFactory.getLogger(TestClientResources.class);
|
||||||
|
|
||||||
private final URIScheme scheme;
|
private final URIScheme scheme;
|
||||||
private final Timeout timeout;
|
private final Timeout timeout;
|
||||||
|
private final ClientProtocolLevel clientProtocolLevel;
|
||||||
|
private final TestServerBootstrap serverBootstrap;
|
||||||
|
private final TestClientBuilder clientBuilder;
|
||||||
|
|
||||||
private ClassicTestServer server;
|
private TestServer server;
|
||||||
private PoolingHttpClientConnectionManager connManager;
|
private PoolingHttpClientConnectionManager connManager;
|
||||||
private CloseableHttpClient client;
|
private TestClient client;
|
||||||
|
|
||||||
public TestClientResources(final URIScheme scheme, final Timeout timeout) {
|
public TestClientResources(final URIScheme scheme, final ClientProtocolLevel clientProtocolLevel, final Timeout timeout) {
|
||||||
this.scheme = scheme;
|
this.scheme = scheme != null ? scheme : URIScheme.HTTP;
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
}
|
this.clientProtocolLevel = clientProtocolLevel != null ? clientProtocolLevel : ClientProtocolLevel.STANDARD;
|
||||||
|
this.serverBootstrap = new TestServerBootstrap(this.scheme)
|
||||||
@Override
|
.setTimeout(this.timeout);
|
||||||
public void beforeEach(final ExtensionContext extensionContext) throws Exception {
|
switch (this.clientProtocolLevel) {
|
||||||
LOG.debug("Starting up test server");
|
case MINIMAL:
|
||||||
server = new ClassicTestServer(
|
this.clientBuilder = new MinimalTestClientBuilder();
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
|
break;
|
||||||
SocketConfig.custom()
|
default:
|
||||||
.setSoTimeout(timeout)
|
this.clientBuilder = new StandardTestClientBuilder();
|
||||||
.build());
|
}
|
||||||
|
this.clientBuilder.setTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,72 +90,32 @@ public class TestClientResources implements BeforeEachCallback, AfterEachCallbac
|
||||||
return this.scheme;
|
return this.scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassicTestServer startServer(
|
public ClientProtocolLevel getClientProtocolLevel() {
|
||||||
final Http1Config http1Config,
|
return clientProtocolLevel;
|
||||||
final HttpProcessor httpProcessor,
|
}
|
||||||
final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
|
|
||||||
Assertions.assertNotNull(server);
|
public void configureServer(final Consumer<TestServerBootstrap> serverCustomizer) {
|
||||||
server.start(http1Config, httpProcessor, handlerDecorator);
|
Asserts.check(server == null, "Server is already running and cannot be changed");
|
||||||
|
serverCustomizer.accept(serverBootstrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestServer server() throws Exception {
|
||||||
|
if (server == null) {
|
||||||
|
server = serverBootstrap.build();
|
||||||
|
}
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpHost targetHost() {
|
public void configureClient(final Consumer<TestClientBuilder> clientCustomizer) {
|
||||||
Assertions.assertNotNull(server);
|
Asserts.check(client == null, "Client is already running and cannot be changed");
|
||||||
return new HttpHost(scheme.id, "localhost", server.getPort());
|
clientCustomizer.accept(clientBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CloseableHttpClient startClient(
|
public TestClient client() throws Exception {
|
||||||
final Consumer<PoolingHttpClientConnectionManagerBuilder> connManagerCustomizer,
|
if (client == null) {
|
||||||
final Consumer<HttpClientBuilder> clientCustomizer) throws Exception {
|
client = clientBuilder.build();
|
||||||
Assertions.assertNull(connManager);
|
}
|
||||||
Assertions.assertNull(client);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
|
|
||||||
connManagerBuilder.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom()
|
|
||||||
.setSoTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
connManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
connManagerCustomizer.accept(connManagerBuilder);
|
|
||||||
|
|
||||||
connManager = connManagerBuilder.build();
|
|
||||||
|
|
||||||
final HttpClientBuilder clientBuilder = HttpClientBuilder.create()
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
clientCustomizer.accept(clientBuilder);
|
|
||||||
client = clientBuilder.build();
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinimalHttpClient startMinimalClient() throws Exception {
|
|
||||||
Assertions.assertNull(connManager);
|
|
||||||
Assertions.assertNull(client);
|
|
||||||
|
|
||||||
final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
|
|
||||||
connManagerBuilder.setTlsSocketStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
connManagerBuilder.setDefaultSocketConfig(SocketConfig.custom()
|
|
||||||
.setSoTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
connManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(timeout)
|
|
||||||
.build());
|
|
||||||
connManager = connManagerBuilder.build();
|
|
||||||
|
|
||||||
final MinimalHttpClient minimalClient = HttpClients.createMinimal(connManager);
|
|
||||||
client = minimalClient;
|
|
||||||
return minimalClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableHttpClient startClient(
|
|
||||||
final Consumer<HttpClientBuilder> clientCustomizer) throws Exception {
|
|
||||||
return startClient(b -> {}, clientCustomizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PoolingHttpClientConnectionManager connManager() {
|
|
||||||
Assertions.assertNotNull(connManager);
|
|
||||||
return connManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
import org.apache.hc.core5.function.Decorator;
|
||||||
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
||||||
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
|
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
||||||
|
|
||||||
|
public class TestServer {
|
||||||
|
|
||||||
|
private final ClassicTestServer server;
|
||||||
|
private final Http1Config http1Config;
|
||||||
|
private final HttpProcessor httpProcessor;
|
||||||
|
private final Decorator<HttpServerRequestHandler> exchangeHandlerDecorator;
|
||||||
|
|
||||||
|
TestServer(
|
||||||
|
final ClassicTestServer server,
|
||||||
|
final Http1Config http1Config,
|
||||||
|
final HttpProcessor httpProcessor,
|
||||||
|
final Decorator<HttpServerRequestHandler> exchangeHandlerDecorator) {
|
||||||
|
this.server = server;
|
||||||
|
this.http1Config = http1Config;
|
||||||
|
this.httpProcessor = httpProcessor;
|
||||||
|
this.exchangeHandlerDecorator = exchangeHandlerDecorator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown(final CloseMode closeMode) {
|
||||||
|
server.shutdown(closeMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InetSocketAddress start() throws IOException {
|
||||||
|
server.start(http1Config, httpProcessor, exchangeHandlerDecorator);
|
||||||
|
return new InetSocketAddress(server.getInetAddress(), server.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hc.client5.testing.sync.extension;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
|
import org.apache.hc.core5.function.Decorator;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||||
|
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
||||||
|
import org.apache.hc.core5.http.io.SocketConfig;
|
||||||
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
|
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
||||||
|
import org.apache.hc.core5.util.Args;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
|
||||||
|
public class TestServerBootstrap {
|
||||||
|
|
||||||
|
static final class HandlerEntry<T> {
|
||||||
|
|
||||||
|
final String hostname;
|
||||||
|
final String uriPattern;
|
||||||
|
final T handler;
|
||||||
|
|
||||||
|
public HandlerEntry(final String hostname, final String uriPattern, final T handler) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
this.uriPattern = uriPattern;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HandlerEntry(final String uriPattern, final T handler) {
|
||||||
|
this(null, uriPattern, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final URIScheme scheme;
|
||||||
|
|
||||||
|
private final List<HandlerEntry<HttpRequestHandler>> handlerList;
|
||||||
|
private Timeout timeout;
|
||||||
|
private HttpProcessor httpProcessor;
|
||||||
|
private Decorator<HttpServerRequestHandler> exchangeHandlerDecorator;
|
||||||
|
|
||||||
|
public TestServerBootstrap(final URIScheme scheme) {
|
||||||
|
this.scheme = scheme != null ? scheme : URIScheme.HTTP;
|
||||||
|
this.handlerList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestServerBootstrap register(final String uriPattern, final HttpRequestHandler requestHandler) {
|
||||||
|
return register(null, uriPattern, requestHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestServerBootstrap register(final String hostname, final String uriPattern, final HttpRequestHandler requestHandler) {
|
||||||
|
Args.notNull(uriPattern, "URI pattern");
|
||||||
|
Args.notNull(requestHandler, "Exchange handler");
|
||||||
|
handlerList.add(new HandlerEntry<>(hostname, uriPattern, requestHandler));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestServerBootstrap setTimeout(final Timeout timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestServerBootstrap setHttpProcessor(final HttpProcessor httpProcessor) {
|
||||||
|
this.httpProcessor = httpProcessor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestServerBootstrap setExchangeHandlerDecorator(final Decorator<HttpServerRequestHandler> exchangeHandlerDecorator) {
|
||||||
|
this.exchangeHandlerDecorator = exchangeHandlerDecorator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestServer build() throws Exception {
|
||||||
|
final ClassicTestServer server = new ClassicTestServer(
|
||||||
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
|
||||||
|
SocketConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build());
|
||||||
|
for (final HandlerEntry<HttpRequestHandler> entry: handlerList) {
|
||||||
|
if (entry.hostname != null) {
|
||||||
|
server.registerHandlerVirtual(entry.hostname, entry.uriPattern, entry.handler);
|
||||||
|
} else {
|
||||||
|
server.registerHandler(entry.uriPattern, entry.handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TestServer(
|
||||||
|
server,
|
||||||
|
Http1Config.DEFAULT,
|
||||||
|
httpProcessor,
|
||||||
|
exchangeHandlerDecorator);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ import java.util.Iterator;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.classic.ExecRuntime;
|
import org.apache.hc.client5.http.classic.ExecRuntime;
|
||||||
|
import org.apache.hc.core5.annotation.Internal;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpEntity;
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
|
@ -49,7 +50,11 @@ public final class CloseableHttpResponse implements ClassicHttpResponse {
|
||||||
private final ClassicHttpResponse response;
|
private final ClassicHttpResponse response;
|
||||||
private final ExecRuntime execRuntime;
|
private final ExecRuntime execRuntime;
|
||||||
|
|
||||||
static CloseableHttpResponse adapt(final ClassicHttpResponse response) {
|
/**
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
@Internal
|
||||||
|
public static CloseableHttpResponse adapt(final ClassicHttpResponse response) {
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue