Fixed integration tests broken by JUnit 5 upgrade
This commit is contained in:
parent
ba45d80b07
commit
7626230ffd
|
@ -84,7 +84,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-migrationsupport</artifactId>
|
<artifactId>junit-jupiter-params</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* ====================================================================
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
|
||||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
|
||||||
import org.apache.hc.core5.reactor.ListenerEndpoint;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
|
|
||||||
public abstract class AbstractHttp1IntegrationTestBase extends AbstractServerTestBase {
|
|
||||||
|
|
||||||
public AbstractHttp1IntegrationTestBase(final URIScheme scheme) {
|
|
||||||
super(scheme);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractHttp1IntegrationTestBase() {
|
|
||||||
super(URIScheme.HTTP);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpAsyncClientBuilder clientBuilder;
|
|
||||||
protected PoolingAsyncClientConnectionManager connManager;
|
|
||||||
protected CloseableHttpAsyncClient httpclient;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientBuilderResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (httpclient != null) {
|
|
||||||
httpclient.close(CloseMode.GRACEFUL);
|
|
||||||
httpclient = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public HttpHost start(
|
|
||||||
final HttpProcessor httpProcessor,
|
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
|
|
||||||
final Http1Config h1Config) throws Exception {
|
|
||||||
server.start(httpProcessor, exchangeHandlerDecorator, h1Config);
|
|
||||||
final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
|
|
||||||
httpclient = clientBuilder.build();
|
|
||||||
httpclient.start();
|
|
||||||
final ListenerEndpoint endpoint = endpointFuture.get();
|
|
||||||
final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
|
|
||||||
return new HttpHost(scheme.name(), "localhost", address.getPort());
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost start(
|
|
||||||
final HttpProcessor httpProcessor,
|
|
||||||
final Http1Config h1Config) throws Exception {
|
|
||||||
return start(httpProcessor, null, h1Config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost start() throws Exception {
|
|
||||||
return start(HttpProcessors.server(), Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -35,6 +35,7 @@ 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.AuthenticationStrategy;
|
||||||
|
@ -64,71 +65,63 @@ 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.HttpResponseInterceptor;
|
||||||
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.config.Lookup;
|
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.impl.HttpProcessors;
|
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
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.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.http2.impl.H2Processors;
|
|
||||||
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.Test;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase<T> {
|
public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
protected final HttpVersion protocolVersion;
|
public AbstractHttpAsyncClientAuthenticationTest(final URIScheme scheme) {
|
||||||
|
|
||||||
public AbstractHttpAsyncClientAuthentication(final URIScheme scheme, final HttpVersion protocolVersion) {
|
|
||||||
super(scheme);
|
super(scheme);
|
||||||
this.protocolVersion = protocolVersion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
abstract protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception;
|
||||||
public final HttpHost start() throws Exception {
|
|
||||||
return start(requestHandler -> new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")));
|
protected H2TestServer startServer() throws Exception {
|
||||||
|
return startServer(requestHandler -> new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final HttpHost start(
|
interface TestClientBuilder {
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
|
||||||
if (protocolVersion.greaterEquals(HttpVersion.HTTP_2_0)) {
|
TestClientBuilder setDefaultAuthSchemeRegistry(Lookup<AuthSchemeFactory> authSchemeRegistry);
|
||||||
return super.start(
|
|
||||||
H2Processors.server(),
|
TestClientBuilder setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy);
|
||||||
exchangeHandlerDecorator,
|
|
||||||
H2Config.DEFAULT);
|
TestClientBuilder addResponseInterceptor(HttpResponseInterceptor responseInterceptor);
|
||||||
} else {
|
|
||||||
return super.start(
|
TestClientBuilder addRequestInterceptor(HttpRequestInterceptor requestInterceptor);
|
||||||
HttpProcessors.server(),
|
|
||||||
exchangeHandlerDecorator,
|
|
||||||
Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void setDefaultAuthSchemeRegistry(Lookup<AuthSchemeFactory> authSchemeRegistry);
|
abstract protected T startClientCustom(final Consumer<TestClientBuilder> clientCustomizer) throws Exception;
|
||||||
|
|
||||||
abstract void setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy);
|
T startClient() throws Exception {
|
||||||
|
return startClientCustom(c -> {});
|
||||||
abstract void addResponseInterceptor(HttpResponseInterceptor responseInterceptor);
|
}
|
||||||
|
|
||||||
abstract void addRequestInterceptor(final HttpRequestInterceptor requestInterceptor);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationNoCreds() throws Exception {
|
public void testBasicAuthenticationNoCreds() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T 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();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
@ -142,8 +135,11 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailure() throws Exception {
|
public void testBasicAuthenticationFailure() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T 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()))
|
||||||
|
@ -151,7 +147,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
@ -165,8 +161,11 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccess() throws Exception {
|
public void testBasicAuthenticationSuccess() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T 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()))
|
||||||
|
@ -174,7 +173,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
|
@ -189,15 +188,18 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationWithEntitySuccess() throws Exception {
|
public void testBasicAuthenticationWithEntitySuccess() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T 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()))
|
||||||
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.put()
|
SimpleRequestBuilder.put()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
|
@ -213,8 +215,11 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationExpectationFailure() throws Exception {
|
public void testBasicAuthenticationExpectationFailure() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T 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()))
|
||||||
|
@ -222,7 +227,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
context.setRequestConfig(RequestConfig.custom().setExpectContinueEnabled(true).build());
|
context.setRequestConfig(RequestConfig.custom().setExpectContinueEnabled(true).build());
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.put()
|
SimpleRequestBuilder.put()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
|
@ -236,8 +241,11 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationExpectationSuccess() throws Exception {
|
public void testBasicAuthenticationExpectationSuccess() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T 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()))
|
||||||
|
@ -245,7 +253,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
context.setRequestConfig(RequestConfig.custom().setExpectContinueEnabled(true).build());
|
context.setRequestConfig(RequestConfig.custom().setExpectContinueEnabled(true).build());
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.put()
|
SimpleRequestBuilder.put()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
|
@ -261,11 +269,12 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
setTargetAuthenticationStrategy(authStrategy);
|
final T client = startClientCustom(builder -> builder.setTargetAuthenticationStrategy(authStrategy));
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
||||||
|
@ -273,7 +282,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
@ -287,15 +296,17 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
setTargetAuthenticationStrategy(authStrategy);
|
|
||||||
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
||||||
addResponseInterceptor((response, entity, context)
|
|
||||||
-> responseQueue.add(BasicResponseBuilder.copy(response).build()));
|
|
||||||
|
|
||||||
final HttpHost target = start();
|
final T client = startClientCustom(builder -> builder
|
||||||
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
|
.addResponseInterceptor((response, entity, context)
|
||||||
|
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
||||||
|
|
||||||
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(target, "test", "test".toCharArray())
|
.add(target, "test", "test".toCharArray())
|
||||||
|
@ -307,7 +318,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setAuthCache(authCache);
|
context.setAuthCache(authCache);
|
||||||
context.setCredentialsProvider(credentialsProvider);
|
context.setCredentialsProvider(credentialsProvider);
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath(requestPath)
|
.setPath(requestPath)
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
@ -331,7 +342,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credentialsProvider);
|
context.setCredentialsProvider(credentialsProvider);
|
||||||
context.setAuthCache(authCache);
|
context.setAuthCache(authCache);
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath(requestPath)
|
.setPath(requestPath)
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
@ -350,11 +361,14 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRequestFailure() throws Exception {
|
public void testAuthenticationUserinfoInRequestFailure() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", AsyncEchoHandler::new);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setScheme(target.getSchemeName())
|
.setScheme(target.getSchemeName())
|
||||||
.setAuthority(new URIAuthority("test:test", target.getHostName(), target.getPort()))
|
.setAuthority(new URIAuthority("test:test", target.getHostName(), target.getPort()))
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
|
@ -365,7 +379,32 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReauthentication() throws Exception {
|
public void testReauthentication() throws Exception {
|
||||||
|
final Authenticator authenticator = new BasicTestAuthenticator("test:test", "test realm") {
|
||||||
|
|
||||||
|
private final AtomicLong count = new AtomicLong(0);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
||||||
|
final boolean authenticated = super.authenticate(authority, requestUri, credentials);
|
||||||
|
if (authenticated) {
|
||||||
|
return this.count.incrementAndGet() % 4 != 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final H2TestServer server = startServer(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
|
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
||||||
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
server.register("*", AsyncEchoHandler::new);
|
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()))
|
||||||
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
|
@ -382,32 +421,8 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
|
||||||
|
|
||||||
final Authenticator authenticator = new BasicTestAuthenticator("test:test", "test realm") {
|
final T client = startClientCustom(builder -> builder.setDefaultAuthSchemeRegistry(authSchemeRegistry));
|
||||||
|
|
||||||
private final AtomicLong count = new AtomicLong(0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
|
||||||
final boolean authenticated = super.authenticate(authority, requestUri, credentials);
|
|
||||||
if (authenticated) {
|
|
||||||
return this.count.incrementAndGet() % 4 != 0;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
final HttpHost target = start(
|
|
||||||
exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
|
||||||
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setTargetPreferredAuthSchemes(Collections.singletonList("MyBasic"))
|
.setTargetPreferredAuthSchemes(Collections.singletonList("MyBasic"))
|
||||||
|
@ -421,7 +436,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build();
|
.build();
|
||||||
request.setConfig(config);
|
request.setConfig(config);
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(request, context, null);
|
final Future<SimpleHttpResponse> future = client.execute(request, context, null);
|
||||||
final SimpleHttpResponse response = future.get();
|
final SimpleHttpResponse response = future.get();
|
||||||
Assertions.assertNotNull(response);
|
Assertions.assertNotNull(response);
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
|
@ -430,9 +445,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationFallback() throws Exception {
|
public void testAuthenticationFallback() throws Exception {
|
||||||
server.register("*", AsyncEchoHandler::new);
|
final H2TestServer server = startServer(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
final HttpHost target = start(
|
|
||||||
exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
|
@ -440,6 +453,10 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T 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()))
|
||||||
|
@ -447,7 +464,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build(), context, null);
|
.build(), context, null);
|
|
@ -53,20 +53,28 @@ 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.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase<T> {
|
public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public AbstractHttpAsyncFundamentalsTest(final URIScheme scheme) {
|
protected AbstractHttpAsyncFundamentalsTest(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract protected H2TestServer startServer() throws Exception;
|
||||||
|
|
||||||
|
abstract protected T startClient() throws Exception;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSequenctialGetRequests() throws Exception {
|
public void testSequentialGetRequests() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
final T client = startClient();
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -81,10 +89,13 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSequenctialHeadRequests() throws Exception {
|
public void testSequentialHeadRequests() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
final T client = startClient();
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.head()
|
SimpleRequestBuilder.head()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -98,13 +109,16 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSequenctialPostRequests() throws Exception {
|
public void testSequentialPostRequests() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/echo/*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
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());
|
||||||
rnd.nextBytes(b1);
|
rnd.nextBytes(b1);
|
||||||
final Future<Message<HttpResponse, byte[]>> future = httpclient.execute(
|
final Future<Message<HttpResponse, byte[]>> future = client.execute(
|
||||||
new BasicRequestProducer(Method.GET, target, "/echo/",
|
new BasicRequestProducer(Method.GET, target, "/echo/",
|
||||||
AsyncEntityProducers.create(b1, ContentType.APPLICATION_OCTET_STREAM)),
|
AsyncEntityProducers.create(b1, ContentType.APPLICATION_OCTET_STREAM)),
|
||||||
new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
|
new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
|
||||||
|
@ -119,7 +133,10 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConcurrentPostRequests() throws Exception {
|
public void testConcurrentPostRequests() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/echo/*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
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);
|
||||||
|
@ -128,7 +145,7 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
|
final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
|
||||||
for (int i = 0; i < reqCount; i++) {
|
for (int i = 0; i < reqCount; i++) {
|
||||||
final Future<Message<HttpResponse, byte[]>> future = httpclient.execute(
|
final Future<Message<HttpResponse, byte[]>> future = client.execute(
|
||||||
new BasicRequestProducer(Method.POST, target, "/echo/",
|
new BasicRequestProducer(Method.POST, target, "/echo/",
|
||||||
AsyncEntityProducers.create(b1, ContentType.APPLICATION_OCTET_STREAM)),
|
AsyncEntityProducers.create(b1, ContentType.APPLICATION_OCTET_STREAM)),
|
||||||
new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
|
new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
|
||||||
|
@ -148,7 +165,10 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestExecutionFromCallback() throws Exception {
|
public void testRequestExecutionFromCallback() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
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<>();
|
||||||
|
@ -161,7 +181,7 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
try {
|
try {
|
||||||
resultQueue.add(result);
|
resultQueue.add(result);
|
||||||
if (count.decrementAndGet() > 0) {
|
if (count.decrementAndGet() > 0) {
|
||||||
httpclient.execute(
|
client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -188,7 +208,7 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
for (int i = 0; i < threadNum; i++) {
|
for (int i = 0; i < threadNum; i++) {
|
||||||
executorService.execute(() -> {
|
executorService.execute(() -> {
|
||||||
if (!Thread.currentThread().isInterrupted()) {
|
if (!Thread.currentThread().isInterrupted()) {
|
||||||
httpclient.execute(
|
client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -213,8 +233,11 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadRequest() throws Exception {
|
public void testBadRequest() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
final T client = startClient();
|
||||||
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/boom")
|
.setPath("/random/boom")
|
||||||
|
|
|
@ -63,49 +63,43 @@ 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.http2.config.H2Config;
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.apache.hc.core5.testing.reactive.ReactiveRandomProcessor;
|
|
||||||
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.Test;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase<T> {
|
public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
protected final HttpVersion version;
|
private final HttpVersion version;
|
||||||
|
|
||||||
public AbstractHttpAsyncRedirectsTest(final HttpVersion version, final URIScheme scheme) {
|
public AbstractHttpAsyncRedirectsTest(final URIScheme scheme, final HttpVersion version) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
abstract protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception;
|
||||||
public final HttpHost start() throws Exception {
|
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
protected H2TestServer startServer() throws Exception {
|
||||||
return super.start(null, H2Config.DEFAULT);
|
return startServer(null);
|
||||||
} else {
|
|
||||||
return super.start(null, Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final HttpHost start(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
abstract protected T startClient() throws Exception;
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
|
||||||
return super.start(null, exchangeHandlerDecorator, H2Config.DEFAULT);
|
|
||||||
} else {
|
|
||||||
return super.start(null, exchangeHandlerDecorator, Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
||||||
|
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/")
|
.setPath("/oldlocation/")
|
||||||
|
@ -121,11 +115,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301() throws Exception {
|
public void testBasicRedirect301() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/100")
|
.setPath("/oldlocation/100")
|
||||||
|
@ -142,11 +141,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302() throws Exception {
|
public void testBasicRedirect302() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/123")
|
.setPath("/oldlocation/123")
|
||||||
|
@ -163,7 +167,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302NoLocation() throws Exception {
|
public void testBasicRedirect302NoLocation() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -172,8 +176,13 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/100")
|
.setPath("/oldlocation/100")
|
||||||
|
@ -189,11 +198,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect303() throws Exception {
|
public void testBasicRedirect303() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/123")
|
.setPath("/oldlocation/123")
|
||||||
|
@ -210,6 +224,8 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect304() throws Exception {
|
public void testBasicRedirect304() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -218,9 +234,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
|
return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/")
|
.setPath("/oldlocation/")
|
||||||
|
@ -236,6 +255,8 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect305() throws Exception {
|
public void testBasicRedirect305() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -244,9 +265,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
|
return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/")
|
.setPath("/oldlocation/")
|
||||||
|
@ -262,11 +286,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect307() throws Exception {
|
public void testBasicRedirect307() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/123")
|
.setPath("/oldlocation/123")
|
||||||
|
@ -283,16 +312,20 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxRedirectCheck() throws Exception {
|
public void testMaxRedirectCheck() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(true)
|
.setCircularRedirectsAllowed(true)
|
||||||
.setMaxRedirects(5).build();
|
.setMaxRedirects(5).build();
|
||||||
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/circular-oldlocation/")
|
.setPath("/circular-oldlocation/")
|
||||||
.setRequestConfig(config)
|
.setRequestConfig(config)
|
||||||
|
@ -304,16 +337,20 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCircularRedirect() throws Exception {
|
public void testCircularRedirect() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(false)
|
.setCircularRedirectsAllowed(false)
|
||||||
.build();
|
.build();
|
||||||
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/circular-oldlocation/")
|
.setPath("/circular-oldlocation/")
|
||||||
|
@ -326,12 +363,17 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirect() throws Exception {
|
public void testPostRedirect() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
||||||
|
|
||||||
|
server.register("/echo/*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.post()
|
SimpleRequestBuilder.post()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/stuff")
|
.setPath("/oldlocation/stuff")
|
||||||
|
@ -349,12 +391,17 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirectSeeOther() throws Exception {
|
public void testPostRedirectSeeOther() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
||||||
|
|
||||||
|
server.register("/echo/*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.post()
|
SimpleRequestBuilder.post()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/stuff")
|
.setPath("/oldlocation/stuff")
|
||||||
|
@ -372,7 +419,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect() throws Exception {
|
public void testRelativeRedirect() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -383,9 +430,14 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/stuff")
|
.setPath("/oldlocation/stuff")
|
||||||
|
@ -402,7 +454,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect2() throws Exception {
|
public void testRelativeRedirect2() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -413,9 +465,14 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/oldlocation")
|
.setPath("/random/oldlocation")
|
||||||
|
@ -432,7 +489,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectBogusRedirectLocation() throws Exception {
|
public void testRejectBogusRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -442,9 +499,13 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
}
|
}
|
||||||
return null;
|
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 = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/")
|
.setPath("/oldlocation/")
|
||||||
|
@ -456,7 +517,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -466,9 +527,13 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
}
|
}
|
||||||
return null;
|
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 = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/")
|
.setPath("/oldlocation/")
|
||||||
|
@ -480,11 +545,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedirectWithCookie() throws Exception {
|
public void testRedirectWithCookie() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -494,7 +564,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
cookieStore.addCookie(cookie);
|
cookieStore.addCookie(cookie);
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/100")
|
.setPath("/oldlocation/100")
|
||||||
|
@ -513,16 +583,11 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCrossSiteRedirect() throws Exception {
|
public void testCrossSiteRedirect() throws Exception {
|
||||||
|
final URIScheme scheme = scheme();
|
||||||
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
|
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
||||||
try {
|
try {
|
||||||
secondServer.register("/random/*", () -> {
|
secondServer.register("/random/*", AsyncRandomHandler::new);
|
||||||
if (isReactive()) {
|
|
||||||
return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
|
|
||||||
} else {
|
|
||||||
return new AsyncRandomHandler();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
final InetSocketAddress address2;
|
final InetSocketAddress address2;
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
||||||
address2 = secondServer.start(H2Config.DEFAULT);
|
address2 = secondServer.start(H2Config.DEFAULT);
|
||||||
|
@ -531,7 +596,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
}
|
}
|
||||||
final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
|
final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
|
||||||
|
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -545,8 +610,13 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation")
|
.setPath("/oldlocation")
|
||||||
|
@ -560,7 +630,7 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
Assertions.assertEquals("/random/100", request.getRequestUri());
|
Assertions.assertEquals("/random/100", request.getRequestUri());
|
||||||
Assertions.assertEquals(redirectTarget, new HttpHost(request.getScheme(), request.getAuthority()));
|
Assertions.assertEquals(redirectTarget, new HttpHost(request.getScheme(), request.getAuthority()));
|
||||||
} finally {
|
} finally {
|
||||||
server.shutdown(TimeValue.ofSeconds(5));
|
secondServer.shutdown(TimeValue.ofSeconds(5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,34 +63,41 @@ 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.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.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.ReactiveRandomProcessor;
|
||||||
import org.apache.hc.core5.util.TextUtils;
|
import org.apache.hc.core5.util.TextUtils;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
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<T> {
|
public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public AbstractHttpReactiveFundamentalsTest(final URIScheme scheme) {
|
public AbstractHttpReactiveFundamentalsTest(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
abstract protected H2TestServer startServer() throws Exception;
|
||||||
protected final boolean isReactive() {
|
|
||||||
return true;
|
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 HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
final T 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();
|
||||||
|
|
||||||
httpclient.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
client.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
||||||
|
|
||||||
final Message<HttpResponse, Publisher<ByteBuffer>> response = consumer.getResponseFuture().get();
|
final Message<HttpResponse, Publisher<ByteBuffer>> response = consumer.getResponseFuture().get();
|
||||||
assertThat(response, CoreMatchers.notNullValue());
|
assertThat(response, CoreMatchers.notNullValue());
|
||||||
|
@ -105,11 +112,15 @@ 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 HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
final T 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();
|
||||||
|
|
||||||
httpclient.execute(AsyncRequestBuilder.head(target + "/random/2048").build(), consumer, null);
|
client.execute(AsyncRequestBuilder.head(target + "/random/2048").build(), consumer, null);
|
||||||
|
|
||||||
final Message<HttpResponse, Publisher<ByteBuffer>> response = consumer.getResponseFuture().get();
|
final Message<HttpResponse, Publisher<ByteBuffer>> response = consumer.getResponseFuture().get();
|
||||||
assertThat(response, CoreMatchers.notNullValue());
|
assertThat(response, CoreMatchers.notNullValue());
|
||||||
|
@ -123,7 +134,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 HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/echo/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
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());
|
||||||
|
@ -134,7 +149,7 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
.setEntity(new ReactiveEntityProducer(publisher, -1, ContentType.APPLICATION_OCTET_STREAM, null))
|
.setEntity(new ReactiveEntityProducer(publisher, -1, ContentType.APPLICATION_OCTET_STREAM, null))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
httpclient.execute(request, consumer, HttpClientContext.create(), null);
|
client.execute(request, consumer, HttpClientContext.create(), null);
|
||||||
|
|
||||||
final Future<Message<HttpResponse, Publisher<ByteBuffer>>> responseFuture = consumer.getResponseFuture();
|
final Future<Message<HttpResponse, Publisher<ByteBuffer>>> responseFuture = consumer.getResponseFuture();
|
||||||
final Message<HttpResponse, Publisher<ByteBuffer>> responseMessage = responseFuture.get();
|
final Message<HttpResponse, Publisher<ByteBuffer>> responseMessage = responseFuture.get();
|
||||||
|
@ -149,7 +164,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 HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/echo/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
final T client = startClient();
|
||||||
|
|
||||||
final int reqCount = 500;
|
final int reqCount = 500;
|
||||||
final int maxSize = 128 * 1024;
|
final int maxSize = 128 * 1024;
|
||||||
|
@ -175,7 +194,7 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
@Override
|
@Override
|
||||||
public void cancelled() { }
|
public void cancelled() { }
|
||||||
});
|
});
|
||||||
httpclient.execute(request, consumer, HttpClientContext.create(), null);
|
client.execute(request, consumer, HttpClientContext.create(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < reqCount; i++) {
|
for (int i = 0; i < reqCount; i++) {
|
||||||
|
@ -194,7 +213,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 HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
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<Message<HttpResponse, Publisher<ByteBuffer>>> resultQueue = new ConcurrentLinkedQueue<>();
|
final Queue<Message<HttpResponse, Publisher<ByteBuffer>>> resultQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
@ -207,7 +230,7 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
resultQueue.add(result);
|
resultQueue.add(result);
|
||||||
if (count.decrementAndGet() > 0) {
|
if (count.decrementAndGet() > 0) {
|
||||||
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(this);
|
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(this);
|
||||||
httpclient.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
client.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
countDownLatch.countDown();
|
countDownLatch.countDown();
|
||||||
|
@ -231,7 +254,7 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
executorService.execute(() -> {
|
executorService.execute(() -> {
|
||||||
if (!Thread.currentThread().isInterrupted()) {
|
if (!Thread.currentThread().isInterrupted()) {
|
||||||
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(callback);
|
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(callback);
|
||||||
httpclient.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
client.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -252,11 +275,15 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadRequest() throws Exception {
|
public void testBadRequest() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
final T 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();
|
||||||
|
|
||||||
httpclient.execute(request, consumer, null);
|
client.execute(request, consumer, null);
|
||||||
|
|
||||||
final Future<Message<HttpResponse, Publisher<ByteBuffer>>> future = consumer.getResponseFuture();
|
final Future<Message<HttpResponse, Publisher<ByteBuffer>>> future = consumer.getResponseFuture();
|
||||||
final HttpResponse response = future.get().getHead();
|
final HttpResponse response = future.get().getHead();
|
||||||
|
|
|
@ -27,10 +27,16 @@
|
||||||
|
|
||||||
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.concurrent.Future;
|
|
||||||
|
|
||||||
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.H2AsyncClientBuilder;
|
||||||
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
||||||
|
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.testing.async.extension.TestAsyncResources;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
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;
|
||||||
|
@ -38,77 +44,79 @@ import org.apache.hc.core5.http.config.Http1Config;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.apache.hc.core5.reactor.ListenerEndpoint;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.Rule;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
|
|
||||||
public abstract class AbstractIntegrationTestBase<T extends CloseableHttpAsyncClient> extends AbstractServerTestBase {
|
public abstract class AbstractIntegrationTestBase {
|
||||||
|
|
||||||
public AbstractIntegrationTestBase(final URIScheme scheme) {
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
super(scheme);
|
|
||||||
|
@RegisterExtension
|
||||||
|
private final TestAsyncResources testResources;
|
||||||
|
|
||||||
|
protected AbstractIntegrationTestBase(final URIScheme scheme) {
|
||||||
|
this.testResources = new TestAsyncResources(scheme, TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractIntegrationTestBase() {
|
public URIScheme scheme() {
|
||||||
super(URIScheme.HTTP);
|
return testResources.scheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected T httpclient;
|
public H2TestServer startServer(
|
||||||
|
final H2Config h2Config,
|
||||||
protected abstract T createClient() throws Exception;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (httpclient != null) {
|
|
||||||
httpclient.close(CloseMode.GRACEFUL);
|
|
||||||
httpclient = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public abstract HttpHost start() throws Exception;
|
|
||||||
|
|
||||||
public final HttpHost start(
|
|
||||||
final HttpProcessor httpProcessor,
|
final HttpProcessor httpProcessor,
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
|
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
||||||
final Http1Config h1Config) throws Exception {
|
return testResources.startServer(h2Config, httpProcessor, exchangeHandlerDecorator);
|
||||||
server.start(httpProcessor, exchangeHandlerDecorator, h1Config);
|
|
||||||
final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
|
|
||||||
httpclient = createClient();
|
|
||||||
httpclient.start();
|
|
||||||
final ListenerEndpoint endpoint = endpointFuture.get();
|
|
||||||
final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
|
|
||||||
return new HttpHost(scheme.name(), "localhost", address.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final HttpHost start(
|
public H2TestServer startServer(
|
||||||
|
final Http1Config http1Config,
|
||||||
final HttpProcessor httpProcessor,
|
final HttpProcessor httpProcessor,
|
||||||
final Http1Config h1Config) throws Exception {
|
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
||||||
return start(httpProcessor, null, h1Config);
|
return testResources.startServer(http1Config, httpProcessor, exchangeHandlerDecorator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final HttpHost start(
|
public HttpHost targetHost() {
|
||||||
final HttpProcessor httpProcessor,
|
return testResources.targetHost();
|
||||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
|
|
||||||
final H2Config h2Config) throws Exception {
|
|
||||||
server.start(httpProcessor, exchangeHandlerDecorator, h2Config);
|
|
||||||
final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
|
|
||||||
httpclient = createClient();
|
|
||||||
httpclient.start();
|
|
||||||
final ListenerEndpoint endpoint = endpointFuture.get();
|
|
||||||
final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
|
|
||||||
return new HttpHost(scheme.name(), "localhost", address.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CloseableHttpAsyncClient startClient(
|
||||||
|
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer,
|
||||||
|
final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
|
||||||
|
return testResources.startClient(connManagerCustomizer, clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
public final HttpHost start(
|
public CloseableHttpAsyncClient startClient(
|
||||||
final HttpProcessor httpProcessor,
|
final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
|
||||||
final H2Config h2Config) throws Exception {
|
return testResources.startClient(clientCustomizer);
|
||||||
return start(httpProcessor, null, h2Config);
|
}
|
||||||
|
|
||||||
|
public PoolingAsyncClientConnectionManager connManager() {
|
||||||
|
return testResources.connManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* ====================================================================
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
|
||||||
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
|
||||||
import org.apache.hc.core5.testing.reactive.ReactiveEchoProcessor;
|
|
||||||
import org.apache.hc.core5.testing.reactive.ReactiveRandomProcessor;
|
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
|
|
||||||
public abstract class AbstractServerTestBase {
|
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
|
||||||
public static final Timeout LONG_TIMEOUT = Timeout.ofMinutes(3);
|
|
||||||
|
|
||||||
protected final URIScheme scheme;
|
|
||||||
|
|
||||||
public AbstractServerTestBase(final URIScheme scheme) {
|
|
||||||
this.scheme = scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractServerTestBase() {
|
|
||||||
this(URIScheme.HTTP);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected H2TestServer server;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource serverResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
server = new H2TestServer(
|
|
||||||
IOReactorConfig.custom()
|
|
||||||
.setSoTimeout(TIMEOUT)
|
|
||||||
.build(),
|
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
|
||||||
server.register("/echo/*", () -> {
|
|
||||||
if (isReactive()) {
|
|
||||||
return new ReactiveServerExchangeHandler(new ReactiveEchoProcessor());
|
|
||||||
} else {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
server.register("/random/*", () -> {
|
|
||||||
if (isReactive()) {
|
|
||||||
return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
|
|
||||||
} else {
|
|
||||||
return new AsyncRandomHandler();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (server != null) {
|
|
||||||
server.shutdown(TimeValue.ofSeconds(5));
|
|
||||||
server = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
protected boolean isReactive() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.hc.core5.http.HttpVersion;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
|
||||||
|
public class HttpIntegrationTests {
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1)")
|
||||||
|
public class Http1 extends TestHttp1Async {
|
||||||
|
|
||||||
|
public Http1() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1, TLS)")
|
||||||
|
public class Http1Tls extends TestHttp1Async {
|
||||||
|
|
||||||
|
public Http1Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2)")
|
||||||
|
public class H2 extends TestH2Async {
|
||||||
|
|
||||||
|
public H2() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2, TLS)")
|
||||||
|
public class H2Tls extends TestH2Async {
|
||||||
|
|
||||||
|
public H2Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Request re-execution (HTTP/1.1)")
|
||||||
|
public class Http1RequestReExecution extends TestHttp1RequestReExecution {
|
||||||
|
|
||||||
|
public Http1RequestReExecution() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Request re-execution (HTTP/1.1, TLS)")
|
||||||
|
public class Http1RequestReExecutionTls extends TestHttp1RequestReExecution {
|
||||||
|
|
||||||
|
public Http1RequestReExecutionTls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("HTTP protocol policy (HTTP/1.1)")
|
||||||
|
public class Http1ProtocolPolicy extends TestHttpAsyncProtocolPolicy {
|
||||||
|
|
||||||
|
public Http1ProtocolPolicy() throws Exception {
|
||||||
|
super(URIScheme.HTTP, HttpVersion.HTTP_1_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("HTTP protocol policy (HTTP/1.1, TLS)")
|
||||||
|
public class Http1ProtocolPolicyTls extends TestHttpAsyncProtocolPolicy {
|
||||||
|
|
||||||
|
public Http1ProtocolPolicyTls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS, HttpVersion.HTTP_1_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("HTTP protocol policy (HTTP/2)")
|
||||||
|
public class H2ProtocolPolicy extends TestHttpAsyncProtocolPolicy {
|
||||||
|
|
||||||
|
public H2ProtocolPolicy() throws Exception {
|
||||||
|
super(URIScheme.HTTP, HttpVersion.HTTP_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("HTTP protocol policy (HTTP/2, TLS)")
|
||||||
|
public class H2ProtocolPolicyTls extends TestHttpAsyncProtocolPolicy {
|
||||||
|
|
||||||
|
public H2ProtocolPolicyTls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS, HttpVersion.HTTP_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Redirects (HTTP/1.1)")
|
||||||
|
public class RedirectsHttp1 extends TestHttp1AsyncRedirects {
|
||||||
|
|
||||||
|
public RedirectsHttp1() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Redirects (HTTP/1.1, TLS)")
|
||||||
|
public class RedirectsHttp1Tls extends TestHttp1AsyncRedirects {
|
||||||
|
|
||||||
|
public RedirectsHttp1Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Redirects (HTTP/2)")
|
||||||
|
public class RedirectsH2 extends TestH2AsyncRedirect {
|
||||||
|
|
||||||
|
public RedirectsH2() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Redirects (HTTP/2, TLS)")
|
||||||
|
public class RedirectsH2Tls extends TestH2AsyncRedirect {
|
||||||
|
|
||||||
|
public RedirectsH2Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Client authentication (HTTP/1.1)")
|
||||||
|
public class AuthenticationHttp1 extends TestHttp1ClientAuthentication {
|
||||||
|
|
||||||
|
public AuthenticationHttp1() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Client authentication (HTTP/1.1, TLS)")
|
||||||
|
public class AuthenticationHttp1Tls extends TestHttp1ClientAuthentication {
|
||||||
|
|
||||||
|
public AuthenticationHttp1Tls() 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
|
||||||
|
public class HttpMinimalIntegrationTests {
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1)")
|
||||||
|
public class Http1 extends TestHttp1AsyncMinimal {
|
||||||
|
|
||||||
|
public Http1() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1, TLS)")
|
||||||
|
public class Http1Tls extends TestHttp1AsyncMinimal {
|
||||||
|
|
||||||
|
public Http1Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2)")
|
||||||
|
public class H2 extends TestH2AsyncMinimal {
|
||||||
|
|
||||||
|
public H2() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2, TLS)")
|
||||||
|
public class H2Tls extends TestH2AsyncMinimal {
|
||||||
|
|
||||||
|
public H2Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
|
||||||
|
public class ReactiveIntegrationTests {
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1)")
|
||||||
|
public class Http1 extends TestHttp1Reactive {
|
||||||
|
|
||||||
|
public Http1() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1, TLS)")
|
||||||
|
public class Http1Tls extends TestHttp1Reactive {
|
||||||
|
|
||||||
|
public Http1Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2)")
|
||||||
|
public class H2 extends TestH2Reactive {
|
||||||
|
|
||||||
|
public H2() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2, TLS)")
|
||||||
|
public class H2Tls extends TestH2Reactive {
|
||||||
|
|
||||||
|
public H2Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
|
||||||
|
public class ReactiveMinimalIntegrationTests {
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1)")
|
||||||
|
public class Http1 extends TestHttp1ReactiveMinimal {
|
||||||
|
|
||||||
|
public Http1() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/1.1, TLS)")
|
||||||
|
public class Http1Tls extends TestHttp1ReactiveMinimal {
|
||||||
|
|
||||||
|
public Http1Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2)")
|
||||||
|
public class H2 extends TestH2ReactiveMinimal {
|
||||||
|
|
||||||
|
public H2() throws Exception {
|
||||||
|
super(URIScheme.HTTP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@DisplayName("Fundamentals (HTTP/2, TLS)")
|
||||||
|
public class H2Tls extends TestH2ReactiveMinimal {
|
||||||
|
|
||||||
|
public H2Tls() throws Exception {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,161 +0,0 @@
|
||||||
/*
|
|
||||||
* ====================================================================
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
import org.apache.hc.client5.http.config.TlsConfig;
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.async.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.HttpHost;
|
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
|
||||||
import org.apache.hc.core5.http.ProtocolVersion;
|
|
||||||
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.config.H2Config;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestAsyncRequestContext extends AbstractIntegrationTestBase<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "{0} {1}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ HttpVersion.HTTP_1_1, URIScheme.HTTP },
|
|
||||||
{ HttpVersion.HTTP_1_1, URIScheme.HTTPS },
|
|
||||||
{ HttpVersion.HTTP_2, URIScheme.HTTP },
|
|
||||||
{ HttpVersion.HTTP_2, URIScheme.HTTPS }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final HttpVersion version;
|
|
||||||
|
|
||||||
public TestAsyncRequestContext(final HttpVersion version, final URIScheme scheme) {
|
|
||||||
super(scheme);
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpAsyncClientBuilder clientBuilder;
|
|
||||||
PoolingAsyncClientConnectionManager connManager;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientBuilderResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager.setDefaultTlsConfig(TlsConfig.custom()
|
|
||||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2) ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
|
||||||
.build());
|
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final HttpHost start() throws Exception {
|
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
|
||||||
return super.start(null, H2Config.DEFAULT);
|
|
||||||
} else {
|
|
||||||
return super.start(null, Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient createClient() throws Exception {
|
|
||||||
return clientBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRequestContext() throws Exception {
|
|
||||||
final AtomicReference<ProtocolVersion> versionRef = new AtomicReference<>();
|
|
||||||
clientBuilder.addRequestInterceptorFirst((request, entity, context) ->
|
|
||||||
versionRef.set(context.getProtocolVersion()));
|
|
||||||
final HttpHost target = start();
|
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
|
||||||
SimpleRequestBuilder.get()
|
|
||||||
.setHttpHost(target)
|
|
||||||
.setPath("/random/2048")
|
|
||||||
.build(), null);
|
|
||||||
final SimpleHttpResponse response = future.get();
|
|
||||||
assertThat(response, CoreMatchers.notNullValue());
|
|
||||||
assertThat(response.getCode(), CoreMatchers.equalTo(200));
|
|
||||||
final String body = response.getBodyText();
|
|
||||||
assertThat(body, CoreMatchers.notNullValue());
|
|
||||||
assertThat(body.length(), CoreMatchers.equalTo(2048));
|
|
||||||
assertThat(versionRef.get(), CoreMatchers.equalTo(version));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -26,68 +26,25 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.H2AsyncClientBuilder;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
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.nio.ssl.BasicClientTlsStrategy;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
import org.junit.Rule;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestH2Async extends AbstractHttpAsyncFundamentalsTest<CloseableHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestH2Async extends AbstractHttpAsyncFundamentalsTest<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/2 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ URIScheme.HTTP },
|
|
||||||
{ URIScheme.HTTPS }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected H2AsyncClientBuilder clientBuilder;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = H2AsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setTlsStrategy(new BasicClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestH2Async(final URIScheme scheme) {
|
public TestH2Async(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CloseableHttpAsyncClient createClient() {
|
protected H2TestServer startServer() throws Exception {
|
||||||
return clientBuilder.build();
|
return startServer(H2Config.DEFAULT, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHost start() throws Exception {
|
protected CloseableHttpAsyncClient startClient() throws Exception {
|
||||||
return super.start(null, H2Config.DEFAULT);
|
return startH2Client(b -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,49 +26,25 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
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.MinimalH2AsyncClient;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
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.http2.config.H2Config;
|
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.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestH2AsyncMinimal extends AbstractHttpAsyncFundamentalsTest<MinimalH2AsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestH2AsyncMinimal extends AbstractHttpAsyncFundamentalsTest<MinimalH2AsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "{0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ URIScheme.HTTP },
|
|
||||||
{ URIScheme.HTTPS },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestH2AsyncMinimal(final URIScheme scheme) {
|
public TestH2AsyncMinimal(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MinimalH2AsyncClient createClient() throws Exception {
|
protected H2TestServer startServer() throws Exception {
|
||||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
return startServer(H2Config.DEFAULT, null, null);
|
||||||
.setSoTimeout(TIMEOUT)
|
|
||||||
.build();
|
|
||||||
return HttpAsyncClients.createHttp2Minimal(
|
|
||||||
H2Config.DEFAULT, ioReactorConfig, new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHost start() throws Exception {
|
protected MinimalH2AsyncClient startClient() throws Exception {
|
||||||
return super.start(null, H2Config.DEFAULT);
|
return startMinimalH2Client(H2Config.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,62 +26,28 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.H2AsyncClientBuilder;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
import org.apache.hc.core5.http.HttpVersion;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.junit.Rule;
|
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
import org.junit.rules.ExternalResource;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestH2AsyncRedirect extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestH2AsyncRedirect extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/2 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ URIScheme.HTTP },
|
|
||||||
{ URIScheme.HTTPS }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected H2AsyncClientBuilder clientBuilder;
|
|
||||||
|
|
||||||
public TestH2AsyncRedirect(final URIScheme scheme) {
|
public TestH2AsyncRedirect(final URIScheme scheme) {
|
||||||
super(HttpVersion.HTTP_2, scheme);
|
super(scheme, HttpVersion.HTTP_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void before() throws Throwable {
|
protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
||||||
clientBuilder = H2AsyncClientBuilder.create()
|
return startServer(H2Config.DEFAULT, null, exchangeHandlerDecorator);
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CloseableHttpAsyncClient createClient() {
|
protected CloseableHttpAsyncClient startClient() throws Exception {
|
||||||
return clientBuilder.build();
|
return startH2Client(b -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,89 +26,71 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.function.Consumer;
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.AuthenticationStrategy;
|
import org.apache.hc.client5.http.AuthenticationStrategy;
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.H2AsyncClientBuilder;
|
import org.apache.hc.client5.http.impl.async.H2AsyncClientBuilder;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
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.Lookup;
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
import org.junit.Rule;
|
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
import org.junit.rules.ExternalResource;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestH2ClientAuthentication extends AbstractHttpAsyncClientAuthenticationTest<CloseableHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestH2ClientAuthentication extends AbstractHttpAsyncClientAuthentication<CloseableHttpAsyncClient> {
|
public TestH2ClientAuthentication(final URIScheme scheme) {
|
||||||
|
super(scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/2 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{URIScheme.HTTP},
|
|
||||||
{URIScheme.HTTPS},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected H2AsyncClientBuilder clientBuilder;
|
|
||||||
protected PoolingAsyncClientConnectionManager connManager;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = H2AsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestH2ClientAuthentication(final URIScheme scheme) {
|
|
||||||
super(scheme, HttpVersion.HTTP_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void setDefaultAuthSchemeRegistry(final Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
|
||||||
clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
|
||||||
clientBuilder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void addResponseInterceptor(final HttpResponseInterceptor responseInterceptor) {
|
|
||||||
clientBuilder.addResponseInterceptorLast(responseInterceptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void addRequestInterceptor(final HttpRequestInterceptor requestInterceptor) {
|
|
||||||
clientBuilder.addRequestInterceptorLast(requestInterceptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient createClient() throws Exception {
|
|
||||||
return clientBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,66 +26,25 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.H2AsyncClientBuilder;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
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.nio.ssl.BasicClientTlsStrategy;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
import org.junit.Rule;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
public abstract class TestH2Reactive extends AbstractHttpReactiveFundamentalsTest<CloseableHttpAsyncClient> {
|
||||||
public class TestH2Reactive extends AbstractHttpReactiveFundamentalsTest<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/2 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ URIScheme.HTTP },
|
|
||||||
{ URIScheme.HTTPS }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected H2AsyncClientBuilder clientBuilder;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = H2AsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setTlsStrategy(new BasicClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestH2Reactive(final URIScheme scheme) {
|
public TestH2Reactive(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CloseableHttpAsyncClient createClient() {
|
protected H2TestServer startServer() throws Exception {
|
||||||
return clientBuilder.build();
|
return startServer(H2Config.DEFAULT, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHost start() throws Exception {
|
protected CloseableHttpAsyncClient startClient() throws Exception {
|
||||||
return super.start(null, H2Config.DEFAULT);
|
return startH2Client(b -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,47 +26,26 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
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.MinimalH2AsyncClient;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
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.http2.config.H2Config;
|
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.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
public abstract class TestH2ReactiveMinimal extends AbstractHttpReactiveFundamentalsTest<MinimalH2AsyncClient> {
|
||||||
public class TestH2MinimalReactive extends AbstractHttpReactiveFundamentalsTest<MinimalH2AsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "{0}")
|
public TestH2ReactiveMinimal(final URIScheme scheme) {
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ URIScheme.HTTP },
|
|
||||||
{ URIScheme.HTTPS },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestH2MinimalReactive(final URIScheme scheme) {
|
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MinimalH2AsyncClient createClient() throws Exception {
|
protected H2TestServer startServer() throws Exception {
|
||||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
return startServer(H2Config.DEFAULT, null, null);
|
||||||
.setSoTimeout(TIMEOUT)
|
|
||||||
.build();
|
|
||||||
return HttpAsyncClients.createHttp2Minimal(
|
|
||||||
H2Config.DEFAULT, ioReactorConfig, new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHost start() throws Exception {
|
protected MinimalH2AsyncClient startClient() throws Exception {
|
||||||
return super.start(null, H2Config.DEFAULT);
|
return startMinimalH2Client(H2Config.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -28,8 +28,6 @@ package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -39,100 +37,49 @@ import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
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.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.HttpAsyncClientBuilder;
|
|
||||||
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.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.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.http.config.Http1Config;
|
||||||
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/1.1 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ URIScheme.HTTP },
|
|
||||||
{ URIScheme.HTTPS },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpAsyncClientBuilder clientBuilder;
|
|
||||||
protected PoolingAsyncClientConnectionManager connManager;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientBuilderResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestHttp1Async(final URIScheme scheme) {
|
public TestHttp1Async(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CloseableHttpAsyncClient createClient() {
|
protected H2TestServer startServer() throws Exception {
|
||||||
return clientBuilder.build();
|
return startServer(Http1Config.DEFAULT, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHost start() throws Exception {
|
protected CloseableHttpAsyncClient startClient() throws Exception {
|
||||||
return super.start(null, Http1Config.DEFAULT);
|
return startClient(b -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest(name = "{displayName}; concurrent connections: {0}")
|
||||||
public void testSequenctialGetRequestsCloseConnection() throws Exception {
|
@ValueSource(ints = {5, 1, 20})
|
||||||
final HttpHost target = start();
|
public void testSequentialGetRequestsCloseConnection(final int concurrentConns) throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient();
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = connManager();
|
||||||
|
connManager.setDefaultMaxPerRoute(concurrentConns);
|
||||||
|
connManager.setMaxTotal(100);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -147,24 +94,15 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConcurrentPostsOverMultipleConnections() throws Exception {
|
|
||||||
connManager.setDefaultMaxPerRoute(20);
|
|
||||||
connManager.setMaxTotal(100);
|
|
||||||
super.testConcurrentPostRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConcurrentPostsOverSingleConnection() throws Exception {
|
|
||||||
connManager.setDefaultMaxPerRoute(1);
|
|
||||||
connManager.setMaxTotal(100);
|
|
||||||
super.testConcurrentPostRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSharedPool() throws Exception {
|
public void testSharedPool() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
final Future<SimpleHttpResponse> future1 = httpclient.execute(
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient();
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = connManager();
|
||||||
|
final Future<SimpleHttpResponse> future1 = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -195,7 +133,7 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
|
||||||
assertThat(body2.length(), CoreMatchers.equalTo(2048));
|
assertThat(body2.length(), CoreMatchers.equalTo(2048));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Future<SimpleHttpResponse> future3 = httpclient.execute(
|
final Future<SimpleHttpResponse> future3 = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -210,16 +148,20 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestCancellation() throws Exception {
|
public void testRequestCancellation() throws Exception {
|
||||||
this.connManager.setDefaultMaxPerRoute(1);
|
final H2TestServer server = startServer();
|
||||||
this.connManager.setMaxTotal(1);
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpAsyncClient client = startClient();
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = connManager();
|
||||||
|
connManager.setDefaultMaxPerRoute(1);
|
||||||
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/1000")
|
.setPath("/random/1000")
|
||||||
|
@ -243,7 +185,7 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
|
||||||
|
|
||||||
final Random rnd = new Random();
|
final Random rnd = new Random();
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/1000")
|
.setPath("/random/1000")
|
||||||
|
@ -266,7 +208,7 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/1000")
|
.setPath("/random/1000")
|
||||||
|
|
|
@ -28,25 +28,17 @@ package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.TlsConfig;
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
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.HttpVersion;
|
|
||||||
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;
|
||||||
|
@ -56,72 +48,45 @@ 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.HttpVersionPolicy;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
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.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestHttp1AsyncMinimal extends AbstractHttpAsyncFundamentalsTest<MinimalHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestHttpAsyncMinimal extends AbstractHttpAsyncFundamentalsTest<MinimalHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "Minimal {0} {1}")
|
public TestHttp1AsyncMinimal(final URIScheme scheme) {
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ HttpVersion.HTTP_1_1, URIScheme.HTTP },
|
|
||||||
{ HttpVersion.HTTP_1_1, URIScheme.HTTPS },
|
|
||||||
{ HttpVersion.HTTP_2, URIScheme.HTTP },
|
|
||||||
{ HttpVersion.HTTP_2, URIScheme.HTTPS }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final HttpVersion version;
|
|
||||||
|
|
||||||
public TestHttpAsyncMinimal(final HttpVersion version, final URIScheme scheme) {
|
|
||||||
super(scheme);
|
super(scheme);
|
||||||
this.version = version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MinimalHttpAsyncClient createClient() throws Exception {
|
protected H2TestServer startServer() throws Exception {
|
||||||
return HttpAsyncClients.createMinimal(
|
return startServer(Http1Config.DEFAULT, null, null);
|
||||||
H2Config.DEFAULT,
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MinimalHttpAsyncClient startClient() throws Exception {
|
||||||
|
return startMinimalClient(
|
||||||
Http1Config.DEFAULT,
|
Http1Config.DEFAULT,
|
||||||
IOReactorConfig.custom()
|
H2Config.DEFAULT,
|
||||||
.setSoTimeout(TIMEOUT)
|
b -> {});
|
||||||
.build(),
|
|
||||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultTlsConfig(TlsConfig.custom()
|
|
||||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2)
|
|
||||||
? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
|
||||||
.build())
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpHost start() throws Exception {
|
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
|
||||||
return super.start(null, H2Config.DEFAULT);
|
|
||||||
} else {
|
|
||||||
return super.start(null, Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/echo/*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final MinimalHttpAsyncClient 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);
|
||||||
|
|
||||||
final int reqCount = 20;
|
final int reqCount = 20;
|
||||||
|
|
||||||
final Future<AsyncClientEndpoint> endpointLease = httpclient.lease(target, null);
|
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
||||||
final AsyncClientEndpoint endpoint = endpointLease.get(5, TimeUnit.SECONDS);
|
final AsyncClientEndpoint endpoint = endpointLease.get(5, TimeUnit.SECONDS);
|
||||||
try {
|
try {
|
||||||
final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
|
final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
|
|
@ -27,24 +27,16 @@
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Future;
|
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.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.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.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
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.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;
|
||||||
|
@ -53,88 +45,45 @@ 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.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.junit.Test;
|
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.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirection test cases.
|
* Redirection test cases.
|
||||||
*/
|
*/
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/1.1 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{URIScheme.HTTP},
|
|
||||||
{URIScheme.HTTPS},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpAsyncClientBuilder clientBuilder;
|
|
||||||
protected PoolingAsyncClientConnectionManager connManager;
|
|
||||||
|
|
||||||
public TestHttp1AsyncRedirects(final URIScheme scheme) {
|
public TestHttp1AsyncRedirects(final URIScheme scheme) {
|
||||||
super(HttpVersion.HTTP_1_1, scheme);
|
super(scheme, HttpVersion.HTTP_1_1);
|
||||||
}
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void after() {
|
protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
||||||
if (connManager != null) {
|
return startServer(Http1Config.DEFAULT, null, exchangeHandlerDecorator);
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientBuilderResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void before() throws Throwable {
|
protected CloseableHttpAsyncClient startClient() throws Exception {
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
return startClient(b -> {});
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient createClient() throws Exception {
|
|
||||||
return clientBuilder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
||||||
Redirect.ConnControl.CLOSE)));
|
Redirect.ConnControl.CLOSE)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/")
|
.setPath("/oldlocation/")
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
@ -149,12 +98,17 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
||||||
Redirect.ConnControl.CLOSE)));
|
Redirect.ConnControl.CLOSE)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/100")
|
.setPath("/oldlocation/100")
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
@ -170,18 +124,21 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultHeadersRedirect() throws Exception {
|
public void testDefaultHeadersRedirect() throws Exception {
|
||||||
final List<Header> defaultHeaders = new ArrayList<>(1);
|
final H2TestServer server = startServer(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
|
||||||
clientBuilder.setDefaultHeaders(defaultHeaders);
|
|
||||||
|
|
||||||
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
exchangeHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
||||||
Redirect.ConnControl.CLOSE)));
|
Redirect.ConnControl.CLOSE)));
|
||||||
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final List<Header> defaultHeaders = new ArrayList<>(1);
|
||||||
|
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
||||||
|
final CloseableHttpAsyncClient client = startClient(builder -> builder
|
||||||
|
.setDefaultHeaders(defaultHeaders)
|
||||||
|
);
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/oldlocation/123")
|
.setPath("/oldlocation/123")
|
||||||
.build(), context, null);
|
.build(), context, null);
|
||||||
|
|
|
@ -28,90 +28,41 @@ package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.UserTokenHandler;
|
|
||||||
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.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.HttpAsyncClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
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;
|
||||||
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.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
||||||
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.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
|
|
||||||
public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTestBase<CloseableHttpAsyncClient> {
|
public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
protected HttpAsyncClientBuilder clientBuilder;
|
public TestHttp1AsyncStatefulConnManagement() {
|
||||||
protected PoolingAsyncClientConnectionManager connManager;
|
super(URIScheme.HTTP);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected H2TestServer startServer() throws Exception {
|
||||||
protected void after() {
|
return startServer(Http1Config.DEFAULT, null, null);
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientBuilderResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient createClient() throws Exception {
|
|
||||||
return clientBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpHost start() throws Exception {
|
|
||||||
return super.start(null, Http1Config.DEFAULT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatefulConnections() throws Exception {
|
public void testStatefulConnections() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,9 +75,10 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
final HttpHost target = targetHost();
|
||||||
clientBuilder.setUserTokenHandler(userTokenHandler);
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpAsyncClient client = startClient(builer -> builer
|
||||||
|
.setUserTokenHandler((route, context) -> context.getAttribute("user")));
|
||||||
|
|
||||||
final int workerCount = 2;
|
final int workerCount = 2;
|
||||||
final int requestCount = 5;
|
final int requestCount = 5;
|
||||||
|
@ -138,14 +90,14 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
contexts[i] = context;
|
contexts[i] = context;
|
||||||
workers[i] = new HttpWorker(
|
workers[i] = new HttpWorker(
|
||||||
"user" + i,
|
"user" + i,
|
||||||
context, requestCount, target, httpclient);
|
context, requestCount, target, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final HttpWorker worker : workers) {
|
for (final HttpWorker worker : workers) {
|
||||||
worker.start();
|
worker.start();
|
||||||
}
|
}
|
||||||
for (final HttpWorker worker : workers) {
|
for (final HttpWorker worker : workers) {
|
||||||
worker.join(LONG_TIMEOUT.toMilliseconds());
|
worker.join(TIMEOUT.toMilliseconds());
|
||||||
}
|
}
|
||||||
for (final HttpWorker worker : workers) {
|
for (final HttpWorker worker : workers) {
|
||||||
final Exception ex = worker.getException();
|
final Exception ex = worker.getException();
|
||||||
|
@ -226,6 +178,7 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRouteSpecificPoolRecylcing() throws Exception {
|
public void testRouteSpecificPoolRecylcing() throws Exception {
|
||||||
|
final H2TestServer server = startServer();
|
||||||
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -241,10 +194,13 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
// 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 UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
|
||||||
clientBuilder.setUserTokenHandler(userTokenHandler);
|
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient(builer -> builer
|
||||||
|
.setUserTokenHandler((route, context) -> context.getAttribute("user")));
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = connManager();
|
||||||
|
|
||||||
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.
|
||||||
connManager.setMaxTotal(maxConn);
|
connManager.setMaxTotal(maxConn);
|
||||||
|
@ -258,7 +214,7 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build();
|
.build();
|
||||||
final Future<SimpleHttpResponse> future1 = httpclient.execute(request1, context1, null);
|
final Future<SimpleHttpResponse> future1 = client.execute(request1, context1, null);
|
||||||
final HttpResponse response1 = future1.get();
|
final HttpResponse response1 = future1.get();
|
||||||
Assertions.assertNotNull(response1);
|
Assertions.assertNotNull(response1);
|
||||||
Assertions.assertEquals(200, response1.getCode());
|
Assertions.assertEquals(200, response1.getCode());
|
||||||
|
@ -278,7 +234,7 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
.setAuthority(new URIAuthority("127.0.0.1", target.getPort()))
|
.setAuthority(new URIAuthority("127.0.0.1", target.getPort()))
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build();
|
.build();
|
||||||
final Future<SimpleHttpResponse> future2 = httpclient.execute(request2, context2, null);
|
final Future<SimpleHttpResponse> future2 = client.execute(request2, context2, null);
|
||||||
final HttpResponse response2 = future2.get();
|
final HttpResponse response2 = future2.get();
|
||||||
Assertions.assertNotNull(response2);
|
Assertions.assertNotNull(response2);
|
||||||
Assertions.assertEquals(200, response2.getCode());
|
Assertions.assertEquals(200, response2.getCode());
|
||||||
|
@ -300,7 +256,7 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build();
|
.build();
|
||||||
final Future<SimpleHttpResponse> future3 = httpclient.execute(request3, context3, null);
|
final Future<SimpleHttpResponse> future3 = client.execute(request3, context3, null);
|
||||||
final HttpResponse response3 = future3.get();
|
final HttpResponse response3 = future3.get();
|
||||||
Assertions.assertNotNull(response3);
|
Assertions.assertNotNull(response3);
|
||||||
Assertions.assertEquals(200, response3.getCode());
|
Assertions.assertEquals(200, response3.getCode());
|
||||||
|
|
|
@ -26,9 +26,8 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
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.AuthenticationStrategy;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||||
|
@ -38,16 +37,11 @@ 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.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.HttpAsyncClientBuilder;
|
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.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
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;
|
||||||
|
@ -55,115 +49,81 @@ 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.HttpResponseInterceptor;
|
||||||
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.config.Http1Config;
|
||||||
import org.apache.hc.core5.http.config.Lookup;
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
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.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthenticationTest<CloseableHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthentication<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/1.1 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{URIScheme.HTTP},
|
|
||||||
{URIScheme.HTTPS},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpAsyncClientBuilder clientBuilder;
|
|
||||||
protected PoolingAsyncClientConnectionManager connManager;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientBuilderResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestHttp1ClientAuthentication(final URIScheme scheme) {
|
public TestHttp1ClientAuthentication(final URIScheme scheme) {
|
||||||
super(scheme, HttpVersion.HTTP_1_1);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setDefaultAuthSchemeRegistry(final Lookup<AuthSchemeFactory> authSchemeRegistry) {
|
protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
||||||
clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
return startServer(Http1Config.DEFAULT, null, exchangeHandlerDecorator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
protected CloseableHttpAsyncClient startClientCustom(final Consumer<TestClientBuilder> clientCustomizer) throws Exception {
|
||||||
clientBuilder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
|
||||||
|
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
|
@Override
|
||||||
void addResponseInterceptor(final HttpResponseInterceptor responseInterceptor) {
|
public TestClientBuilder setTargetAuthenticationStrategy(final AuthenticationStrategy targetAuthStrategy) {
|
||||||
clientBuilder.addResponseInterceptorLast(responseInterceptor);
|
builder.setTargetAuthenticationStrategy(targetAuthStrategy);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void addRequestInterceptor(final HttpRequestInterceptor requestInterceptor) {
|
public TestClientBuilder addResponseInterceptor(final HttpResponseInterceptor responseInterceptor) {
|
||||||
clientBuilder.addRequestInterceptorLast(requestInterceptor);
|
builder.addResponseInterceptorLast(responseInterceptor);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CloseableHttpAsyncClient createClient() throws Exception {
|
public TestClientBuilder addRequestInterceptor(final HttpRequestInterceptor requestInterceptor) {
|
||||||
return clientBuilder.build();
|
builder.addRequestInterceptorFirst(requestInterceptor);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccessNonPersistentConnection() throws Exception {
|
public void testBasicAuthenticationSuccessNonPersistentConnection() throws Exception {
|
||||||
server.register("*", AsyncEchoHandler::new);
|
final H2TestServer server = startServer(exchangeHandler ->
|
||||||
final HttpHost target = start(
|
new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
HttpProcessors.server(),
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
Http1Config.DEFAULT);
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient 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()))
|
||||||
|
@ -175,7 +135,7 @@ public class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthen
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/")
|
.setPath("/")
|
||||||
.build();
|
.build();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(request, context, null);
|
final Future<SimpleHttpResponse> future = client.execute(request, context, null);
|
||||||
final HttpResponse response = future.get();
|
final HttpResponse response = future.get();
|
||||||
|
|
||||||
Assertions.assertNotNull(response);
|
Assertions.assertNotNull(response);
|
||||||
|
|
|
@ -30,20 +30,12 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
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.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.HttpAsyncClientBuilder;
|
|
||||||
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.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.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;
|
||||||
|
@ -54,85 +46,46 @@ 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.testing.nio.H2TestServer;
|
||||||
|
import org.apache.hc.core5.testing.reactive.ReactiveRandomProcessor;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.jupiter.api.Timeout;
|
import org.junit.jupiter.api.Timeout;
|
||||||
import org.junit.rules.ExternalResource;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
public abstract class TestHttp1Reactive extends AbstractHttpReactiveFundamentalsTest<CloseableHttpAsyncClient> {
|
||||||
public class TestHttp1Reactive extends AbstractHttpReactiveFundamentalsTest<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "HTTP/1.1 {0}")
|
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ URIScheme.HTTP },
|
|
||||||
{ URIScheme.HTTPS },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpAsyncClientBuilder clientBuilder;
|
|
||||||
protected PoolingAsyncClientConnectionManager connManager;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.setSocketTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public TestHttp1Reactive(final URIScheme scheme) {
|
public TestHttp1Reactive(final URIScheme scheme) {
|
||||||
super(scheme);
|
super(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CloseableHttpAsyncClient createClient() {
|
protected H2TestServer startServer() throws Exception {
|
||||||
return clientBuilder.build();
|
return startServer(Http1Config.DEFAULT, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHost start() throws Exception {
|
protected CloseableHttpAsyncClient startClient() throws Exception {
|
||||||
return super.start(null, Http1Config.DEFAULT);
|
return startClient(b -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest(name = "{displayName}; concurrent connections: {0}")
|
||||||
|
@ValueSource(ints = {5, 1, 20})
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
@Timeout(value = 60_000, unit = MILLISECONDS)
|
||||||
public void testSequentialGetRequestsCloseConnection() throws Exception {
|
public void testSequentialGetRequestsCloseConnection(final int concurrentConns) throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient();
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = connManager();
|
||||||
|
connManager.setDefaultMaxPerRoute(concurrentConns);
|
||||||
|
connManager.setMaxTotal(100);
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
final SimpleHttpRequest get = SimpleRequestBuilder.get()
|
final SimpleHttpRequest get = SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
|
@ -142,7 +95,7 @@ public class TestHttp1Reactive extends AbstractHttpReactiveFundamentalsTest<Clos
|
||||||
final AsyncRequestProducer request = AsyncRequestBuilder.get(target + "/random/2048").build();
|
final AsyncRequestProducer request = AsyncRequestBuilder.get(target + "/random/2048").build();
|
||||||
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer();
|
||||||
|
|
||||||
httpclient.execute(request, consumer, null);
|
client.execute(request, consumer, null);
|
||||||
|
|
||||||
final Message<HttpResponse, Publisher<ByteBuffer>> response = consumer.getResponseFuture().get();
|
final Message<HttpResponse, Publisher<ByteBuffer>> response = consumer.getResponseFuture().get();
|
||||||
assertThat(response, CoreMatchers.notNullValue());
|
assertThat(response, CoreMatchers.notNullValue());
|
||||||
|
@ -153,30 +106,21 @@ public class TestHttp1Reactive extends AbstractHttpReactiveFundamentalsTest<Clos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
|
||||||
public void testConcurrentPostsOverMultipleConnections() throws Exception {
|
|
||||||
connManager.setDefaultMaxPerRoute(20);
|
|
||||||
connManager.setMaxTotal(100);
|
|
||||||
super.testConcurrentPostRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Timeout(value = 60_000, unit = MILLISECONDS)
|
|
||||||
public void testConcurrentPostsOverSingleConnection() throws Exception {
|
|
||||||
connManager.setDefaultMaxPerRoute(1);
|
|
||||||
connManager.setMaxTotal(100);
|
|
||||||
super.testConcurrentPostRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/random/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveRandomProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient();
|
||||||
|
final PoolingAsyncClientConnectionManager connManager = connManager();
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
httpclient.execute(request1, consumer1, null);
|
client.execute(request1, consumer1, null);
|
||||||
|
|
||||||
final Message<HttpResponse, Publisher<ByteBuffer>> response1 = consumer1.getResponseFuture().get();
|
final Message<HttpResponse, Publisher<ByteBuffer>> response1 = consumer1.getResponseFuture().get();
|
||||||
assertThat(response1, CoreMatchers.notNullValue());
|
assertThat(response1, CoreMatchers.notNullValue());
|
||||||
|
@ -208,7 +152,7 @@ public class TestHttp1Reactive extends AbstractHttpReactiveFundamentalsTest<Clos
|
||||||
final AsyncRequestProducer request3 = AsyncRequestBuilder.get(target + "/random/2048").build();
|
final AsyncRequestProducer request3 = AsyncRequestBuilder.get(target + "/random/2048").build();
|
||||||
final ReactiveResponseConsumer consumer3 = new ReactiveResponseConsumer();
|
final ReactiveResponseConsumer consumer3 = new ReactiveResponseConsumer();
|
||||||
|
|
||||||
httpclient.execute(request3, consumer3, null);
|
client.execute(request3, consumer3, null);
|
||||||
|
|
||||||
final Message<HttpResponse, Publisher<ByteBuffer>> response3 = consumer3.getResponseFuture().get();
|
final Message<HttpResponse, Publisher<ByteBuffer>> response3 = consumer3.getResponseFuture().get();
|
||||||
assertThat(response3, CoreMatchers.notNullValue());
|
assertThat(response3, CoreMatchers.notNullValue());
|
||||||
|
|
|
@ -28,25 +28,17 @@ package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.TlsConfig;
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
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.HttpVersion;
|
|
||||||
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;
|
||||||
|
@ -56,72 +48,48 @@ 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.HttpVersionPolicy;
|
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
import org.apache.hc.core5.http2.config.H2Config;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
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.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestHttp1ReactiveMinimal extends AbstractHttpReactiveFundamentalsTest<MinimalHttpAsyncClient> {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestHttpMinimalReactive extends AbstractHttpReactiveFundamentalsTest<MinimalHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "Minimal {0} {1}")
|
public TestHttp1ReactiveMinimal(final URIScheme scheme) {
|
||||||
public static Collection<Object[]> protocols() {
|
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ HttpVersion.HTTP_1_1, URIScheme.HTTP },
|
|
||||||
{ HttpVersion.HTTP_1_1, URIScheme.HTTPS },
|
|
||||||
{ HttpVersion.HTTP_2, URIScheme.HTTP },
|
|
||||||
{ HttpVersion.HTTP_2, URIScheme.HTTPS }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final HttpVersion version;
|
|
||||||
|
|
||||||
public TestHttpMinimalReactive(final HttpVersion version, final URIScheme scheme) {
|
|
||||||
super(scheme);
|
super(scheme);
|
||||||
this.version = version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MinimalHttpAsyncClient createClient() throws Exception {
|
protected H2TestServer startServer() throws Exception {
|
||||||
return HttpAsyncClients.createMinimal(
|
return startServer(Http1Config.DEFAULT, null, null);
|
||||||
H2Config.DEFAULT,
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MinimalHttpAsyncClient startClient() throws Exception {
|
||||||
|
return startMinimalClient(
|
||||||
Http1Config.DEFAULT,
|
Http1Config.DEFAULT,
|
||||||
IOReactorConfig.custom()
|
H2Config.DEFAULT,
|
||||||
.setSoTimeout(LONG_TIMEOUT)
|
b -> {});
|
||||||
.build(),
|
|
||||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setDefaultTlsConfig(TlsConfig.custom()
|
|
||||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2)
|
|
||||||
? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
|
||||||
.build())
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpHost start() throws Exception {
|
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
|
||||||
return super.start(null, H2Config.DEFAULT);
|
|
||||||
} else {
|
|
||||||
return super.start(null, Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
public void testConcurrentPostRequestsSameEndpoint() throws Exception {
|
||||||
final HttpHost target = start();
|
final H2TestServer server = startServer();
|
||||||
|
server.register("/echo/*", () ->
|
||||||
|
new ReactiveServerExchangeHandler(new ReactiveEchoProcessor()));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final MinimalHttpAsyncClient 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);
|
||||||
|
|
||||||
final int reqCount = 20;
|
final int reqCount = 20;
|
||||||
|
|
||||||
final Future<AsyncClientEndpoint> endpointLease = httpclient.lease(target, null);
|
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
||||||
final AsyncClientEndpoint endpoint = endpointLease.get(5, TimeUnit.SECONDS);
|
final AsyncClientEndpoint endpoint = endpointLease.get(5, TimeUnit.SECONDS);
|
||||||
try {
|
try {
|
||||||
final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
|
final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
|
|
@ -28,99 +28,31 @@ package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
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.config.RequestConfig;
|
|
||||||
import org.apache.hc.client5.http.config.TlsConfig;
|
|
||||||
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
|
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
|
||||||
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.HttpAsyncClientBuilder;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
|
||||||
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.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.config.Http1Config;
|
||||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
import org.apache.hc.core5.http2.config.H2Config;
|
|
||||||
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.Rule;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
public abstract class TestHttp1RequestReExecution extends AbstractIntegrationTestBase {
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class TestHttp1RequestReExecution extends AbstractIntegrationTestBase<CloseableHttpAsyncClient> {
|
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "{0}")
|
public TestHttp1RequestReExecution(final URIScheme scheme) {
|
||||||
public static Collection<Object[]> protocolVersions() {
|
super(scheme);
|
||||||
return Arrays.asList(new Object[][]{
|
|
||||||
{ HttpVersion.HTTP_1_1 },
|
|
||||||
{ HttpVersion.HTTP_2 }
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final HttpVersion version;
|
protected H2TestServer startServer() throws Exception {
|
||||||
|
|
||||||
public TestHttp1RequestReExecution(final HttpVersion version) {
|
|
||||||
super(URIScheme.HTTP);
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpAsyncClientBuilder clientBuilder;
|
|
||||||
PoolingAsyncClientConnectionManager connManager;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource connManagerResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (connManager != null) {
|
|
||||||
connManager.close();
|
|
||||||
connManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientBuilderResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager.setDefaultTlsConfig(TlsConfig.custom()
|
|
||||||
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2) ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
|
||||||
.build());
|
|
||||||
clientBuilder = HttpAsyncClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final HttpHost start() throws Exception {
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -133,23 +65,20 @@ public class TestHttp1RequestReExecution extends AbstractIntegrationTestBase<Clo
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
return startServer(Http1Config.DEFAULT, null, handler ->
|
||||||
return super.start(null, handler -> new ServiceUnavailableAsyncDecorator(handler, serviceAvailabilityResolver), H2Config.DEFAULT);
|
new ServiceUnavailableAsyncDecorator(handler, serviceAvailabilityResolver));
|
||||||
} else {
|
|
||||||
return super.start(null, handler -> new ServiceUnavailableAsyncDecorator(handler, serviceAvailabilityResolver), Http1Config.DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CloseableHttpAsyncClient createClient() throws Exception {
|
|
||||||
return clientBuilder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGiveUpAfterOneRetry() throws Exception {
|
public void testGiveUpAfterOneRetry() throws Exception {
|
||||||
clientBuilder.setRetryStrategy(new DefaultHttpRequestRetryStrategy(1, TimeValue.ofSeconds(1)));
|
final H2TestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient(builder -> builder
|
||||||
|
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(1, TimeValue.ofSeconds(1))));
|
||||||
|
|
||||||
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
@ -161,9 +90,14 @@ public class TestHttp1RequestReExecution extends AbstractIntegrationTestBase<Clo
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDoNotGiveUpEasily() throws Exception {
|
public void testDoNotGiveUpEasily() throws Exception {
|
||||||
clientBuilder.setRetryStrategy(new DefaultHttpRequestRetryStrategy(5, TimeValue.ofSeconds(1)));
|
final H2TestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.register("/random/*", AsyncRandomHandler::new);
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpAsyncClient client = startClient(builder -> builder
|
||||||
|
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(5, TimeValue.ofSeconds(1))));
|
||||||
|
|
||||||
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
.setPath("/random/2048")
|
.setPath("/random/2048")
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* ====================================================================
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
|
||||||
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
|
||||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
|
||||||
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.http2.config.H2Config;
|
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
|
||||||
import org.apache.hc.core5.reactor.ListenerEndpoint;
|
|
||||||
import org.apache.hc.core5.ssl.SSLContexts;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
|
|
||||||
@EnableRuleMigrationSupport
|
|
||||||
public class TestHttpAsyncMinimalTls extends AbstractServerTestBase {
|
|
||||||
|
|
||||||
public TestHttpAsyncMinimalTls() {
|
|
||||||
super(URIScheme.HTTPS);
|
|
||||||
}
|
|
||||||
|
|
||||||
MinimalHttpAsyncClient httpclient;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (httpclient != null) {
|
|
||||||
httpclient.close(CloseMode.GRACEFUL);
|
|
||||||
httpclient = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccessfulTlsHandshake() throws Exception {
|
|
||||||
final int maxConnNo = 2;
|
|
||||||
|
|
||||||
httpclient = HttpAsyncClients.createMinimal(
|
|
||||||
H2Config.DEFAULT,
|
|
||||||
Http1Config.DEFAULT,
|
|
||||||
IOReactorConfig.custom()
|
|
||||||
.setSoTimeout(TIMEOUT)
|
|
||||||
.build(),
|
|
||||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()))
|
|
||||||
.setMaxConnPerRoute(maxConnNo)
|
|
||||||
.setMaxConnTotal(maxConnNo)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
server.start(Http1Config.DEFAULT);
|
|
||||||
final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
|
|
||||||
|
|
||||||
final ListenerEndpoint listenerEndpoint = endpointFuture.get();
|
|
||||||
final InetSocketAddress address = (InetSocketAddress) listenerEndpoint.getAddress();
|
|
||||||
final HttpHost target = new HttpHost(scheme.name(), "localhost", address.getPort());
|
|
||||||
httpclient.start();
|
|
||||||
|
|
||||||
for (int i = 0; i < maxConnNo + 1; i++) {
|
|
||||||
final Future<AsyncClientEndpoint> endpointLease = httpclient.lease(target, null);
|
|
||||||
final AsyncClientEndpoint endpoint = endpointLease.get(5, TimeUnit.SECONDS);
|
|
||||||
endpoint.releaseAndDiscard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTlsHandshakeFailure() throws Exception {
|
|
||||||
final int maxConnNo = 2;
|
|
||||||
|
|
||||||
httpclient = HttpAsyncClients.createMinimal(
|
|
||||||
H2Config.DEFAULT,
|
|
||||||
Http1Config.DEFAULT,
|
|
||||||
IOReactorConfig.custom()
|
|
||||||
.setSoTimeout(TIMEOUT)
|
|
||||||
.build(),
|
|
||||||
PoolingAsyncClientConnectionManagerBuilder.create()
|
|
||||||
.setTlsStrategy(new DefaultClientTlsStrategy(SSLContexts.createDefault()))
|
|
||||||
.setMaxConnPerRoute(2)
|
|
||||||
.setMaxConnTotal(2)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
server.start(Http1Config.DEFAULT);
|
|
||||||
final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
|
|
||||||
|
|
||||||
final ListenerEndpoint listenerEndpoint = endpointFuture.get();
|
|
||||||
final InetSocketAddress address = (InetSocketAddress) listenerEndpoint.getAddress();
|
|
||||||
final HttpHost target = new HttpHost(scheme.name(), "localhost", address.getPort());
|
|
||||||
httpclient.start();
|
|
||||||
|
|
||||||
for (int i = 0; i < maxConnNo + 1; i++) {
|
|
||||||
final Future<AsyncClientEndpoint> endpointLease = httpclient.lease(target, null);
|
|
||||||
final ExecutionException executionException = Assert.assertThrows(ExecutionException.class,
|
|
||||||
() -> endpointLease.get(5, TimeUnit.SECONDS));
|
|
||||||
Assertions.assertInstanceOf(SSLException.class, executionException.getCause());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
|
||||||
|
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||||
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
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.http2.config.H2Config;
|
||||||
|
import org.apache.hc.core5.ssl.SSLContexts;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class TestHttpAsyncMinimalTlsHandshake extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
|
public TestHttpAsyncMinimalTlsHandshake() {
|
||||||
|
super(URIScheme.HTTPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MinimalHttpAsyncClient startMinimalClient(
|
||||||
|
final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer) throws Exception {
|
||||||
|
return startMinimalClient(
|
||||||
|
Http1Config.DEFAULT,
|
||||||
|
H2Config.DEFAULT,
|
||||||
|
connManagerCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccessfulTlsHandshake() throws Exception {
|
||||||
|
startServer(Http1Config.DEFAULT, null, null);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final int maxConnNo = 2;
|
||||||
|
final MinimalHttpAsyncClient client = startMinimalClient(builder -> builder
|
||||||
|
.setMaxConnPerRoute(maxConnNo)
|
||||||
|
.setMaxConnTotal(maxConnNo));
|
||||||
|
|
||||||
|
for (int i = 0; i < maxConnNo + 1; i++) {
|
||||||
|
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
||||||
|
final AsyncClientEndpoint endpoint = endpointLease.get(5, TimeUnit.SECONDS);
|
||||||
|
endpoint.releaseAndDiscard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTlsHandshakeFailure() throws Exception {
|
||||||
|
startServer(Http1Config.DEFAULT, null, null);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final int maxConnNo = 2;
|
||||||
|
final MinimalHttpAsyncClient client = startMinimalClient(builder -> builder
|
||||||
|
.setTlsStrategy(new DefaultClientTlsStrategy(SSLContexts.createDefault()))
|
||||||
|
.setMaxConnPerRoute(maxConnNo)
|
||||||
|
.setMaxConnTotal(maxConnNo));
|
||||||
|
|
||||||
|
for (int i = 0; i < maxConnNo + 1; i++) {
|
||||||
|
final Future<AsyncClientEndpoint> endpointLease = client.lease(target, null);
|
||||||
|
final ExecutionException executionException = Assertions.assertThrows(ExecutionException.class,
|
||||||
|
() -> endpointLease.get(5, TimeUnit.SECONDS));
|
||||||
|
Assertions.assertInstanceOf(SSLException.class, executionException.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.async;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
|
import org.apache.hc.client5.http.config.TlsConfig;
|
||||||
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
import org.apache.hc.core5.http.HttpVersion;
|
||||||
|
import org.apache.hc.core5.http.ProtocolVersion;
|
||||||
|
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.config.H2Config;
|
||||||
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public abstract class TestHttpAsyncProtocolPolicy extends AbstractIntegrationTestBase {
|
||||||
|
|
||||||
|
private final HttpVersion version;
|
||||||
|
|
||||||
|
public TestHttpAsyncProtocolPolicy(final URIScheme scheme, final HttpVersion version) {
|
||||||
|
super(scheme);
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequestContext() throws Exception {
|
||||||
|
final H2TestServer server;
|
||||||
|
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
||||||
|
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 CloseableHttpAsyncClient client = startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setDefaultTlsConfig(TlsConfig.custom()
|
||||||
|
.setVersionPolicy(version.greaterEquals(HttpVersion.HTTP_2) ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
|
||||||
|
.build()),
|
||||||
|
builder -> builder
|
||||||
|
.addRequestInterceptorFirst((request, entity, context) ->
|
||||||
|
versionRef.set(context.getProtocolVersion())
|
||||||
|
));
|
||||||
|
|
||||||
|
final Future<SimpleHttpResponse> future = client.execute(
|
||||||
|
SimpleRequestBuilder.get()
|
||||||
|
.setHttpHost(target)
|
||||||
|
.setPath("/random/2048")
|
||||||
|
.build(), null);
|
||||||
|
final SimpleHttpResponse response = future.get();
|
||||||
|
assertThat(response, CoreMatchers.notNullValue());
|
||||||
|
assertThat(response.getCode(), CoreMatchers.equalTo(200));
|
||||||
|
final String body = response.getBodyText();
|
||||||
|
assertThat(body, CoreMatchers.notNullValue());
|
||||||
|
assertThat(body.length(), CoreMatchers.equalTo(2048));
|
||||||
|
assertThat(versionRef.get(), CoreMatchers.equalTo(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,235 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.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.core5.function.Decorator;
|
||||||
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
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.reactor.IOReactorConfig;
|
||||||
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
|
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.extension.AfterEachCallback;
|
||||||
|
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TestAsyncResources implements BeforeEachCallback, AfterEachCallback {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(TestClientResources.class);
|
||||||
|
|
||||||
|
private final URIScheme scheme;
|
||||||
|
private final Timeout timeout;
|
||||||
|
|
||||||
|
private H2TestServer server;
|
||||||
|
private InetSocketAddress socketAddress;
|
||||||
|
private PoolingAsyncClientConnectionManager connManager;
|
||||||
|
private CloseableHttpAsyncClient client;
|
||||||
|
|
||||||
|
public TestAsyncResources(final URIScheme scheme, final Timeout timeout) {
|
||||||
|
this.scheme = scheme;
|
||||||
|
this.timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeEach(final ExtensionContext extensionContext) throws Exception {
|
||||||
|
LOG.debug("Starting up test server");
|
||||||
|
server = new H2TestServer(
|
||||||
|
IOReactorConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build(),
|
||||||
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterEach(final ExtensionContext extensionContext) throws Exception {
|
||||||
|
LOG.debug("Shutting down test server");
|
||||||
|
|
||||||
|
if (client != null) {
|
||||||
|
client.close(CloseMode.GRACEFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connManager != null) {
|
||||||
|
connManager.close(CloseMode.IMMEDIATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server != null) {
|
||||||
|
server.shutdown(TimeValue.ofSeconds(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public URIScheme scheme() {
|
||||||
|
return this.scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
public H2TestServer startServer(
|
||||||
|
final H2Config h2Config,
|
||||||
|
final HttpProcessor httpProcessor,
|
||||||
|
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
|
||||||
|
Assertions.assertNotNull(server);
|
||||||
|
socketAddress = server.start(httpProcessor, exchangeHandlerDecorator, h2Config);
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public H2TestServer startServer(
|
||||||
|
final Http1Config http1Config,
|
||||||
|
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);
|
||||||
|
client = clientBuilder.build();
|
||||||
|
client.start();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -33,22 +33,37 @@ import java.nio.charset.StandardCharsets;
|
||||||
import org.apache.hc.client5.http.ClientProtocolException;
|
import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
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.LocalServerTestBase;
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
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;
|
||||||
|
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.junit.Before;
|
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.Test;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
public class TestFluent extends LocalServerTestBase {
|
public class TestFluent {
|
||||||
|
|
||||||
@Before
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
|
public HttpHost targetHost() {
|
||||||
|
return testResources.targetHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
this.server.registerHandler("/", (request, response, context) -> response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN)));
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
this.server.registerHandler("/echo", (request, response, context) -> {
|
server.registerHandler("/", (request, response, context) ->
|
||||||
|
response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN)));
|
||||||
|
server.registerHandler("/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) {
|
||||||
|
@ -68,7 +83,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequest() throws Exception {
|
public void testGetRequest() throws Exception {
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
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);
|
||||||
|
@ -76,7 +91,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequestByName() throws Exception {
|
public void testGetRequestByName() throws Exception {
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
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);
|
||||||
|
@ -84,7 +99,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequestByNameWithURI() throws Exception {
|
public void testGetRequestByNameWithURI() throws Exception {
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
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);
|
||||||
|
@ -92,7 +107,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetRequestFailure() throws Exception {
|
public void testGetRequestFailure() throws Exception {
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
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());
|
||||||
|
@ -100,7 +115,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRequest() throws Exception {
|
public void testPostRequest() throws Exception {
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
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)
|
||||||
|
@ -114,7 +129,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContentAsStringWithCharset() throws Exception {
|
public void testContentAsStringWithCharset() throws Exception {
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
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();
|
||||||
|
@ -125,7 +140,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionRelease() throws Exception {
|
public void testConnectionRelease() throws Exception {
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
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();
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
/*
|
|
||||||
* ====================================================================
|
|
||||||
* 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.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
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.testing.SSLTestContexts;
|
|
||||||
import org.apache.hc.client5.testing.classic.EchoHandler;
|
|
||||||
import org.apache.hc.client5.testing.classic.RandomHandler;
|
|
||||||
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.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.Closer;
|
|
||||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.rules.ExternalResource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for tests using local test server. The server will not be started per default.
|
|
||||||
*/
|
|
||||||
public abstract class LocalServerTestBase {
|
|
||||||
|
|
||||||
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
|
||||||
public static final Timeout LONG_TIMEOUT = Timeout.ofMinutes(3);
|
|
||||||
|
|
||||||
public LocalServerTestBase(final URIScheme scheme) {
|
|
||||||
this.scheme = scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalServerTestBase() {
|
|
||||||
this(URIScheme.HTTP);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final URIScheme scheme;
|
|
||||||
|
|
||||||
protected ClassicTestServer server;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource serverResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
server = new ClassicTestServer(
|
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
|
|
||||||
SocketConfig.custom()
|
|
||||||
.setSoTimeout(TIMEOUT)
|
|
||||||
.build());
|
|
||||||
server.registerHandler("/echo/*", new EchoHandler());
|
|
||||||
server.registerHandler("/random/*", new RandomHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
if (server != null) {
|
|
||||||
try {
|
|
||||||
server.shutdown(CloseMode.IMMEDIATE);
|
|
||||||
server = null;
|
|
||||||
} catch (final Exception ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
protected PoolingHttpClientConnectionManager connManager;
|
|
||||||
protected HttpClientBuilder clientBuilder;
|
|
||||||
protected CloseableHttpClient httpclient;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExternalResource clientResource = new ExternalResource() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void before() throws Throwable {
|
|
||||||
connManager = new PoolingHttpClientConnectionManager();
|
|
||||||
connManager.setDefaultSocketConfig(SocketConfig.custom()
|
|
||||||
.setSoTimeout(TIMEOUT)
|
|
||||||
.build());
|
|
||||||
connManager.setDefaultConnectionConfig(ConnectionConfig.custom()
|
|
||||||
.setConnectTimeout(TIMEOUT)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
clientBuilder = HttpClientBuilder.create()
|
|
||||||
.setDefaultRequestConfig(RequestConfig.custom()
|
|
||||||
.setConnectionRequestTimeout(TIMEOUT)
|
|
||||||
.build())
|
|
||||||
.setConnectionManager(connManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void after() {
|
|
||||||
Closer.closeQuietly(httpclient);
|
|
||||||
httpclient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public HttpHost start(
|
|
||||||
final Http1Config http1Config,
|
|
||||||
final HttpProcessor httpProcessor,
|
|
||||||
final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
|
|
||||||
this.server.start(http1Config, httpProcessor, handlerDecorator);
|
|
||||||
|
|
||||||
if (this.httpclient == null) {
|
|
||||||
this.httpclient = this.clientBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new HttpHost(this.scheme.name(), "localhost", this.server.getPort());
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost start(
|
|
||||||
final HttpProcessor httpProcessor,
|
|
||||||
final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
|
|
||||||
return start(null, httpProcessor, handlerDecorator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHost start() throws Exception {
|
|
||||||
return start(null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -27,21 +27,38 @@
|
||||||
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.sync.extension.TestClientResources;
|
||||||
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.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.junit.Test;
|
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.extension.RegisterExtension;
|
||||||
|
|
||||||
public class TestBasicConnectionManager extends LocalServerTestBase {
|
public class TestBasicConnectionManager {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasics() throws Exception {
|
public void testBasics() throws Exception {
|
||||||
this.clientBuilder.setConnectionManager(new BasicHttpClientConnectionManager());
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = testResources.startClient(builder -> builder
|
||||||
|
.setConnectionManager(new BasicHttpClientConnectionManager())
|
||||||
|
);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpGet get = new HttpGet("/random/1024");
|
final HttpGet get = new HttpGet("/random/1024");
|
||||||
this.httpclient.execute(target, get, response -> {
|
client.execute(target, get, response -> {
|
||||||
Assertions.assertEquals(200, response.getCode());
|
Assertions.assertEquals(200, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -50,14 +67,19 @@ public class TestBasicConnectionManager extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionStillInUse() throws Exception {
|
public void testConnectionStillInUse() throws Exception {
|
||||||
this.clientBuilder.setConnectionManager(new BasicHttpClientConnectionManager());
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = testResources.startClient(builder -> builder
|
||||||
|
.setConnectionManager(new BasicHttpClientConnectionManager())
|
||||||
|
);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpGet get1 = new HttpGet("/random/1024");
|
final HttpGet get1 = new HttpGet("/random/1024");
|
||||||
this.httpclient.executeOpen(target, get1, null);
|
client.executeOpen(target, get1, null);
|
||||||
final HttpGet get2 = new HttpGet("/random/1024");
|
final HttpGet get2 = new HttpGet("/random/1024");
|
||||||
Assertions.assertThrows(IllegalStateException.class, () ->
|
Assertions.assertThrows(IllegalStateException.class, () ->
|
||||||
this.httpclient.executeOpen(target, get2, null));
|
client.executeOpen(target, get2, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ 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.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.ClientProtocolException;
|
import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
|
@ -55,11 +56,14 @@ 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.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.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;
|
||||||
|
@ -69,6 +73,8 @@ 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.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
|
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.impl.HttpProcessors;
|
||||||
|
@ -79,36 +85,61 @@ 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.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 class TestClientAuthentication extends LocalServerTestBase {
|
public class TestClientAuthentication {
|
||||||
|
|
||||||
public HttpHost start(final Authenticator authenticator) throws IOException {
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
return super.start(null, requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator));
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
|
public ClassicTestServer startServer(final Authenticator authenticator) throws IOException {
|
||||||
|
return testResources.startServer(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public ClassicTestServer startServer() throws IOException {
|
||||||
public HttpHost start() throws IOException {
|
return startServer(new BasicTestAuthenticator("test:test", "test realm"));
|
||||||
return start(new BasicTestAuthenticator("test:test", "test realm"));
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) {
|
||||||
|
return testResources.startClient(clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient() {
|
||||||
|
return testResources.startClient(builder -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHost targetHost() {
|
||||||
|
return testResources.targetHost();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationNoCreds() throws Exception {
|
public void testBasicAuthenticationNoCreds() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -121,8 +152,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailure() throws Exception {
|
public void testBasicAuthenticationFailure() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -131,7 +165,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -144,7 +178,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccess() throws Exception {
|
public void testBasicAuthenticationSuccess() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
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);
|
||||||
|
@ -152,9 +190,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
final HttpHost target = start();
|
client.execute(target, httpget, context, response -> {
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -167,8 +203,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
|
public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setExpectContinueEnabled(true)
|
.setExpectContinueEnabled(true)
|
||||||
|
@ -185,7 +224,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
this.httpclient.execute(target, httpput, context, response -> {
|
client.execute(target, httpput, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -195,8 +234,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
|
public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
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("/");
|
||||||
|
@ -212,7 +254,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
.thenReturn(new UsernamePasswordCredentials("test", "boom".toCharArray()));
|
.thenReturn(new UsernamePasswordCredentials("test", "boom".toCharArray()));
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
this.httpclient.execute(target, httpput, context, response -> {
|
client.execute(target, httpput, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(401, response.getCode());
|
Assertions.assertEquals(401, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -223,8 +265,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
|
public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
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));
|
||||||
|
@ -235,7 +280,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
this.httpclient.execute(target, httppost, context, response -> {
|
client.execute(target, httppost, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -248,8 +293,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception {
|
public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpPost httppost = new HttpPost("/");
|
final HttpPost httppost = new HttpPost("/");
|
||||||
httppost.setEntity(new InputStreamEntity(
|
httppost.setEntity(new InputStreamEntity(
|
||||||
|
@ -265,7 +313,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
.thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
this.httpclient.execute(target, httppost, context, response -> {
|
client.execute(target, httppost, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(401, response.getCode());
|
Assertions.assertEquals(401, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -276,14 +324,17 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
server.registerHandler("*", new EchoHandler());
|
||||||
this.clientBuilder.setTargetAuthenticationStrategy(authStrategy);
|
final HttpHost target = targetHost();
|
||||||
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
|
||||||
this.clientBuilder.addResponseInterceptorLast((response, entity, context)
|
|
||||||
-> responseQueue.add(BasicResponseBuilder.copy(response).build()));
|
|
||||||
|
|
||||||
final HttpHost target = start();
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
|
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
|
.addResponseInterceptorLast((response, entity, context)
|
||||||
|
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
||||||
|
@ -292,7 +343,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity1);
|
Assertions.assertNotNull(entity1);
|
||||||
|
@ -310,14 +361,17 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
server.registerHandler("*", new EchoHandler());
|
||||||
this.clientBuilder.setTargetAuthenticationStrategy(authStrategy);
|
final HttpHost target = targetHost();
|
||||||
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
|
||||||
this.clientBuilder.addResponseInterceptorLast((response, entity, context)
|
|
||||||
-> responseQueue.add(BasicResponseBuilder.copy(response).build()));
|
|
||||||
|
|
||||||
final HttpHost target = start();
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
|
final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
|
.addResponseInterceptorLast((response, entity, context)
|
||||||
|
-> responseQueue.add(BasicResponseBuilder.copy(response).build())));
|
||||||
|
|
||||||
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(target, "test", "test".toCharArray())
|
.add(target, "test", "test".toCharArray())
|
||||||
|
@ -330,7 +384,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
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);
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity1);
|
Assertions.assertNotNull(entity1);
|
||||||
|
@ -352,7 +406,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
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);
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity1);
|
Assertions.assertNotNull(entity1);
|
||||||
|
@ -371,8 +425,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationCredentialsCachingReauthenticationOnDifferentRealm() throws Exception {
|
public void testAuthenticationCredentialsCachingReauthenticationOnDifferentRealm() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer(new Authenticator() {
|
||||||
final HttpHost target = start(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) {
|
||||||
|
@ -397,22 +450,26 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
|
.setTargetAuthenticationStrategy(authStrategy)
|
||||||
|
);
|
||||||
|
|
||||||
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())
|
||||||
.add(new AuthScope(target, "that realm", null), "test", "that".toCharArray())
|
.add(new AuthScope(target, "that realm", null), "test", "that".toCharArray())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.clientBuilder.setTargetAuthenticationStrategy(authStrategy);
|
|
||||||
this.httpclient = this.clientBuilder.build();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
final HttpGet httpget1 = new HttpGet("/this");
|
final HttpGet httpget1 = new HttpGet("/this");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget1, context, response -> {
|
client.execute(target, httpget1, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity1);
|
Assertions.assertNotNull(entity1);
|
||||||
|
@ -422,7 +479,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
final HttpGet httpget2 = new HttpGet("/this");
|
final HttpGet httpget2 = new HttpGet("/this");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget2, context, response -> {
|
client.execute(target, httpget2, context, response -> {
|
||||||
final HttpEntity entity2 = response.getEntity();
|
final HttpEntity entity2 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity2);
|
Assertions.assertNotNull(entity2);
|
||||||
|
@ -432,7 +489,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
final HttpGet httpget3 = new HttpGet("/that");
|
final HttpGet httpget3 = new HttpGet("/that");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget3, context, response -> {
|
client.execute(target, httpget3, context, response -> {
|
||||||
final HttpEntity entity3 = response.getEntity();
|
final HttpEntity entity3 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity3);
|
Assertions.assertNotNull(entity3);
|
||||||
|
@ -445,19 +502,25 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRequest() throws Exception {
|
public void testAuthenticationUserinfoInRequest() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = startServer();
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
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, () -> this.httpclient.execute(target, httpget, context, response -> null));
|
Assertions.assertThrows(ClientProtocolException.class, () -> client.execute(target, httpget, context, response -> null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPreemptiveAuthentication() throws Exception {
|
public void testPreemptiveAuthentication() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
|
||||||
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
||||||
final HttpHost target = start(authenticator);
|
final ClassicTestServer server = startServer(authenticator);
|
||||||
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final BasicScheme basicScheme = new BasicScheme();
|
final BasicScheme basicScheme = new BasicScheme();
|
||||||
basicScheme.initPreemptive(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
basicScheme.initPreemptive(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
|
@ -467,7 +530,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
context.setAuthCache(authCache);
|
context.setAuthCache(authCache);
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity1);
|
Assertions.assertNotNull(entity1);
|
||||||
|
@ -480,9 +543,12 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPreemptiveAuthenticationFailure() throws Exception {
|
public void testPreemptiveAuthenticationFailure() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
|
||||||
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
final Authenticator authenticator = Mockito.spy(new BasicTestAuthenticator("test:test", "test realm"));
|
||||||
final HttpHost target = start(authenticator);
|
final ClassicTestServer server = startServer(authenticator);
|
||||||
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final AuthCache authCache = new BasicAuthCache();
|
final AuthCache authCache = new BasicAuthCache();
|
||||||
|
@ -493,7 +559,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity1 = response.getEntity();
|
final HttpEntity entity1 = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
Assertions.assertNotNull(entity1);
|
Assertions.assertNotNull(entity1);
|
||||||
|
@ -525,16 +591,18 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationTargetAsProxy() throws Exception {
|
public void testAuthenticationTargetAsProxy() throws Exception {
|
||||||
this.server.registerHandler("*", new ProxyAuthHandler());
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
|
server.registerHandler("*", new ProxyAuthHandler());
|
||||||
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
final HttpHost target = super.start();
|
final CloseableHttpClient client = testResources.startClient(builder -> {});
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, response.getCode());
|
||||||
EntityUtils.consume(entity);
|
EntityUtils.consume(entity);
|
||||||
|
@ -544,9 +612,8 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
|
public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = testResources.startServer(
|
||||||
|
Http1Config.DEFAULT,
|
||||||
final HttpHost target = start(
|
|
||||||
HttpProcessors.server(),
|
HttpProcessors.server(),
|
||||||
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
|
@ -555,7 +622,12 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
||||||
|
@ -566,7 +638,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
@ -576,8 +648,6 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReauthentication() throws Exception {
|
public void testReauthentication() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
|
||||||
|
|
||||||
final BasicSchemeFactory myBasicAuthSchemeFactory = new BasicSchemeFactory() {
|
final BasicSchemeFactory myBasicAuthSchemeFactory = new BasicSchemeFactory() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -605,10 +675,6 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||||
.register("MyBasic", myBasicAuthSchemeFactory)
|
.register("MyBasic", myBasicAuthSchemeFactory)
|
||||||
.build();
|
.build();
|
||||||
this.httpclient = this.clientBuilder
|
|
||||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
|
||||||
.setDefaultCredentialsProvider(credsProvider)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
final Authenticator authenticator = new BasicTestAuthenticator("test:test", "test realm") {
|
final Authenticator authenticator = new BasicTestAuthenticator("test:test", "test realm") {
|
||||||
|
|
||||||
|
@ -624,7 +690,8 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final HttpHost target = start(
|
final ClassicTestServer server = testResources.startServer(
|
||||||
|
Http1Config.DEFAULT,
|
||||||
HttpProcessors.server(),
|
HttpProcessors.server(),
|
||||||
requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator) {
|
requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator) {
|
||||||
|
|
||||||
|
@ -634,13 +701,21 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
server.registerHandler("*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
|
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||||
|
.setDefaultCredentialsProvider(credsProvider)
|
||||||
|
);
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
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);
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
@ -652,9 +727,8 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationFallback() throws Exception {
|
public void testAuthenticationFallback() throws Exception {
|
||||||
this.server.registerHandler("*", new EchoHandler());
|
final ClassicTestServer server = testResources.startServer(
|
||||||
|
Http1Config.DEFAULT,
|
||||||
final HttpHost target = start(
|
|
||||||
HttpProcessors.server(),
|
HttpProcessors.server(),
|
||||||
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
|
@ -663,7 +737,12 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
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());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
|
||||||
|
@ -672,7 +751,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
context.setCredentialsProvider(credsProvider);
|
context.setCredentialsProvider(credsProvider);
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpEntity entity = response.getEntity();
|
final HttpEntity entity = response.getEntity();
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
Assertions.assertNotNull(entity);
|
Assertions.assertNotNull(entity);
|
||||||
|
|
|
@ -27,30 +27,58 @@
|
||||||
package org.apache.hc.client5.testing.sync;
|
package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||||
import org.apache.hc.client5.http.auth.NTCredentials;
|
import org.apache.hc.client5.http.auth.NTCredentials;
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
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.sync.extension.TestClientResources;
|
||||||
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;
|
||||||
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.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
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.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.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for some of the NTLM auth functionality..
|
* Unit tests for some of the NTLM auth functionality..
|
||||||
*/
|
*/
|
||||||
public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
public class TestClientAuthenticationFakeNTLM {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
|
public ClassicTestServer startServer() throws IOException {
|
||||||
|
return testResources.startServer(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) {
|
||||||
|
return testResources.startClient(clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient() {
|
||||||
|
return testResources.startClient(builder -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHost targetHost() {
|
||||||
|
return testResources.targetHost();
|
||||||
|
}
|
||||||
|
|
||||||
static class NtlmResponseHandler implements HttpRequestHandler {
|
static class NtlmResponseHandler implements HttpRequestHandler {
|
||||||
|
|
||||||
|
@ -67,22 +95,22 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNTLMAuthenticationFailure() throws Exception {
|
public void testNTLMAuthenticationFailure() throws Exception {
|
||||||
this.server.registerHandler("*", new NtlmResponseHandler());
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new NtlmResponseHandler());
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
|
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.httpclient = HttpClients.custom()
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
.setDefaultCredentialsProvider(credsProvider)
|
.setDefaultCredentialsProvider(credsProvider)
|
||||||
.build();
|
);
|
||||||
|
|
||||||
final HttpContext context = HttpClientContext.create();
|
final HttpContext context = HttpClientContext.create();
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
@ -114,23 +142,24 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNTLMv1Type2Message() throws Exception {
|
public void testNTLMv1Type2Message() throws Exception {
|
||||||
this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
||||||
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
||||||
"AGUAcgB2AGUAcgA="));
|
"AGUAcgB2AGUAcgA="));
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
|
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.httpclient = HttpClients.custom()
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
.setDefaultCredentialsProvider(credsProvider)
|
.setDefaultCredentialsProvider(credsProvider)
|
||||||
.build();
|
);
|
||||||
|
|
||||||
final HttpContext context = HttpClientContext.create();
|
final HttpContext context = HttpClientContext.create();
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
@ -139,23 +168,24 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNTLMv2Type2Message() throws Exception {
|
public void testNTLMv2Type2Message() throws Exception {
|
||||||
this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
||||||
"AADAAMADgAAAAzgoriASNFZ4mrze8AAAAAAAAAACQAJABEAAAABgBwFwAAAA9T" +
|
"AADAAMADgAAAAzgoriASNFZ4mrze8AAAAAAAAAACQAJABEAAAABgBwFwAAAA9T" +
|
||||||
"AGUAcgB2AGUAcgACAAwARABvAG0AYQBpAG4AAQAMAFMAZQByAHYAZQByAAAAAAA="));
|
"AGUAcgB2AGUAcgACAAwARABvAG0AYQBpAG4AAQAMAFMAZQByAHYAZQByAAAAAAA="));
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credsProvider = CredentialsProviderBuilder.create()
|
||||||
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
|
.add(target, new NTCredentials("test", "test".toCharArray(), null, null))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
this.httpclient = HttpClients.custom()
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
.setDefaultCredentialsProvider(credsProvider)
|
.setDefaultCredentialsProvider(credsProvider)
|
||||||
.build();
|
);
|
||||||
|
|
||||||
final HttpContext context = HttpClientContext.create();
|
final HttpContext context = HttpClientContext.create();
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
@ -183,11 +213,13 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception {
|
public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception {
|
||||||
this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
||||||
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
||||||
"AGUAcgB2AGUAcgA="));
|
"AGUAcgB2AGUAcgA="));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
||||||
|
@ -195,7 +227,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
||||||
.build());
|
.build());
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
@ -204,11 +236,14 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception {
|
public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception {
|
||||||
this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
||||||
"AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
"AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
||||||
"ZXJ2ZXI="));
|
"ZXJ2ZXI="));
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
context.setCredentialsProvider(CredentialsProviderBuilder.create()
|
||||||
|
@ -216,7 +251,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
||||||
.build());
|
.build());
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -33,13 +33,17 @@ 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.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.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;
|
||||||
|
@ -49,6 +53,7 @@ import org.apache.hc.core5.http.HttpRequest;
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
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.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
||||||
import org.apache.hc.core5.http.io.HttpClientConnection;
|
import org.apache.hc.core5.http.io.HttpClientConnection;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||||
|
@ -58,14 +63,38 @@ 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.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client protocol handling tests.
|
* Client protocol handling tests.
|
||||||
*/
|
*/
|
||||||
public class TestClientRequestExecution extends LocalServerTestBase {
|
public class TestClientRequestExecution {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
|
public ClassicTestServer startServer() throws IOException {
|
||||||
|
return testResources.startServer(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) {
|
||||||
|
return testResources.startClient(clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient() {
|
||||||
|
return testResources.startClient(builder -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHost targetHost() {
|
||||||
|
return testResources.targetHost();
|
||||||
|
}
|
||||||
|
|
||||||
private static class SimpleService implements HttpRequestHandler {
|
private static class SimpleService implements HttpRequestHandler {
|
||||||
|
|
||||||
|
@ -113,7 +142,9 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutoGeneratedHeaders() throws Exception {
|
public void testAutoGeneratedHeaders() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new SimpleService());
|
||||||
|
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");
|
||||||
|
|
||||||
|
@ -146,19 +177,17 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.httpclient = this.clientBuilder
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
.addRequestInterceptorFirst(interceptor)
|
.addRequestInterceptorFirst(interceptor)
|
||||||
.setRequestExecutor(new FaultyHttpRequestExecutor("Oppsie"))
|
.setRequestExecutor(new FaultyHttpRequestExecutor("Oppsie"))
|
||||||
.setRetryStrategy(requestRetryStrategy)
|
.setRetryStrategy(requestRetryStrategy)
|
||||||
.build();
|
);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/");
|
final HttpGet httpget = new HttpGet("/");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
final HttpRequest reqWrapper = context.getRequest();
|
final HttpRequest reqWrapper = context.getRequest();
|
||||||
|
|
||||||
|
@ -173,7 +202,9 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonRepeatableEntity() throws Exception {
|
public void testNonRepeatableEntity() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new SimpleService());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
|
final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
|
||||||
|
|
||||||
|
@ -204,12 +235,10 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.httpclient = this.clientBuilder
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
.setRequestExecutor(new FaultyHttpRequestExecutor("a message showing that this failed"))
|
.setRequestExecutor(new FaultyHttpRequestExecutor("a message showing that this failed"))
|
||||||
.setRetryStrategy(requestRetryStrategy)
|
.setRetryStrategy(requestRetryStrategy)
|
||||||
.build();
|
);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -219,18 +248,20 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
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));
|
||||||
Assertions.assertThrows(IOException.class, () ->
|
Assertions.assertThrows(IOException.class, () ->
|
||||||
this.httpclient.execute(target, httppost, context, response -> null));
|
client.execute(target, httppost, context, response -> null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonCompliantURI() throws Exception {
|
public void testNonCompliantURI() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new SimpleService());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "{{|boom|}}");
|
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "{{|boom|}}");
|
||||||
this.httpclient.execute(target, request, context, response -> {
|
client.execute(target, request, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -243,14 +274,16 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRequestURIWithFragment() throws Exception {
|
public void testRelativeRequestURIWithFragment() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new SimpleService());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/stuff#blahblah");
|
final HttpGet httpget = new HttpGet("/stuff#blahblah");
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -262,9 +295,11 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAbsoluteRequestURIWithFragment() throws Exception {
|
public void testAbsoluteRequestURIWithFragment() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new SimpleService());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final URI uri = new URIBuilder()
|
final URI uri = new URIBuilder()
|
||||||
.setHost(target.getHostName())
|
.setHost(target.getHostName())
|
||||||
|
@ -277,7 +312,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
final HttpGet httpget = new HttpGet(uri);
|
final HttpGet httpget = new HttpGet(uri);
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
this.httpclient.execute(httpget, context, response -> {
|
client.execute(httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -292,10 +327,14 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestCancellation() throws Exception {
|
public void testRequestCancellation() throws Exception {
|
||||||
this.connManager.setDefaultMaxPerRoute(1);
|
startServer();
|
||||||
this.connManager.setMaxTotal(1);
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setMaxConnPerRoute(1)
|
||||||
|
.setMaxConnTotal(1),
|
||||||
|
builder -> {});
|
||||||
|
|
||||||
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
||||||
try {
|
try {
|
||||||
|
@ -306,7 +345,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
executorService.schedule(httpget::cancel, 1, TimeUnit.MILLISECONDS);
|
executorService.schedule(httpget::cancel, 1, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.httpclient.execute(target, httpget, response -> {
|
client.execute(target, httpget, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -322,7 +361,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
executorService.schedule(httpget::cancel, rnd.nextInt(200), TimeUnit.MILLISECONDS);
|
executorService.schedule(httpget::cancel, rnd.nextInt(200), TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.httpclient.execute(target, httpget, response -> {
|
client.execute(target, httpget, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -333,7 +372,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
final HttpGet httpget = new HttpGet("/random/1000");
|
final HttpGet httpget = new HttpGet("/random/1000");
|
||||||
this.httpclient.execute(target, httpget, response -> {
|
client.execute(target, httpget, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,20 +27,22 @@
|
||||||
|
|
||||||
package org.apache.hc.client5.testing.sync;
|
package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.concurrent.TimeoutException;
|
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.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.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.socket.ConnectionSocketFactory;
|
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||||
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
|
||||||
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.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.config.RegistryBuilder;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
||||||
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
||||||
|
@ -52,26 +54,51 @@ 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.Test;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
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 extends LocalServerTestBase {
|
public class TestConnectionManagement {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
|
public ClassicTestServer startServer() throws IOException {
|
||||||
|
return testResources.startServer(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient() {
|
||||||
|
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();
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
this.connManager.setMaxTotal(1);
|
startClient();
|
||||||
|
|
||||||
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
final int rsplen = 8;
|
final int rsplen = 8;
|
||||||
final String uri = "/random/" + rsplen;
|
final String uri = "/random/" + rsplen;
|
||||||
|
@ -79,10 +106,10 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", target, uri);
|
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", target, uri);
|
||||||
final HttpContext context = new BasicHttpContext();
|
final HttpContext context = new BasicHttpContext();
|
||||||
|
|
||||||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
final LeaseRequest leaseRequest1 = connManager.lease("id1", route, null);
|
||||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||||
|
|
||||||
this.connManager.connect(endpoint1, null, context);
|
connManager.connect(endpoint1, null, context);
|
||||||
|
|
||||||
final HttpProcessor httpProcessor = new DefaultHttpProcessor(
|
final HttpProcessor httpProcessor = new DefaultHttpProcessor(
|
||||||
new RequestTargetHost(), new RequestContent(), new RequestConnControl());
|
new RequestTargetHost(), new RequestContent(), new RequestConnControl());
|
||||||
|
@ -95,16 +122,16 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
|
|
||||||
// check that there is no auto-release by default
|
// check that there is no auto-release by default
|
||||||
// this should fail quickly, connection has not been released
|
// this should fail quickly, connection has not been released
|
||||||
final LeaseRequest leaseRequest2 = this.connManager.lease("id2", route,null);
|
final LeaseRequest leaseRequest2 = connManager.lease("id2", route, null);
|
||||||
Assertions.assertThrows(TimeoutException.class, () -> leaseRequest2.get(Timeout.ofMilliseconds(10)));
|
Assertions.assertThrows(TimeoutException.class, () -> leaseRequest2.get(Timeout.ofMilliseconds(10)));
|
||||||
|
|
||||||
endpoint1.close();
|
endpoint1.close();
|
||||||
this.connManager.release(endpoint1, null, TimeValue.NEG_ONE_MILLISECOND);
|
connManager.release(endpoint1, null, TimeValue.NEG_ONE_MILLISECOND);
|
||||||
final LeaseRequest leaseRequest3 = this.connManager.lease("id2", route,null);
|
final LeaseRequest leaseRequest3 = connManager.lease("id2", route, null);
|
||||||
final ConnectionEndpoint endpoint2 = leaseRequest3.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint2 = leaseRequest3.get(Timeout.ZERO_MILLISECONDS);
|
||||||
Assertions.assertFalse(endpoint2.isConnected());
|
Assertions.assertFalse(endpoint2.isConnected());
|
||||||
|
|
||||||
this.connManager.connect(endpoint2, null, context);
|
connManager.connect(endpoint2, null, context);
|
||||||
|
|
||||||
try (final ClassicHttpResponse response2 = endpoint2.execute("id2", request, exec, context)) {
|
try (final ClassicHttpResponse response2 = endpoint2.execute("id2", request, exec, context)) {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
||||||
|
@ -112,9 +139,9 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
|
|
||||||
// release connection after marking it for re-use
|
// release connection after marking it for re-use
|
||||||
// expect the next connection obtained to be open
|
// expect the next connection obtained to be open
|
||||||
this.connManager.release(endpoint2, null, TimeValue.NEG_ONE_MILLISECOND);
|
connManager.release(endpoint2, null, TimeValue.NEG_ONE_MILLISECOND);
|
||||||
|
|
||||||
final LeaseRequest leaseRequest4 = this.connManager.lease("id3", route,null);
|
final LeaseRequest leaseRequest4 = connManager.lease("id3", route, null);
|
||||||
final ConnectionEndpoint endpoint3 = leaseRequest4.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint3 = leaseRequest4.get(Timeout.ZERO_MILLISECONDS);
|
||||||
Assertions.assertTrue(endpoint3.isConnected());
|
Assertions.assertTrue(endpoint3.isConnected());
|
||||||
|
|
||||||
|
@ -123,8 +150,8 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response3.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response3.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connManager.release(endpoint3, null, TimeValue.NEG_ONE_MILLISECOND);
|
connManager.release(endpoint3, null, TimeValue.NEG_ONE_MILLISECOND);
|
||||||
this.connManager.close();
|
connManager.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,10 +159,15 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testReleaseConnectionWithTimeLimits() throws Exception {
|
public void testReleaseConnectionWithTimeLimits() throws Exception {
|
||||||
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
this.connManager.setMaxTotal(1);
|
startClient();
|
||||||
|
|
||||||
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
final int rsplen = 8;
|
final int rsplen = 8;
|
||||||
final String uri = "/random/" + rsplen;
|
final String uri = "/random/" + rsplen;
|
||||||
|
@ -143,9 +175,9 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", target, uri);
|
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", target, uri);
|
||||||
final HttpContext context = new BasicHttpContext();
|
final HttpContext context = new BasicHttpContext();
|
||||||
|
|
||||||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
final LeaseRequest leaseRequest1 = connManager.lease("id1", route, null);
|
||||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||||
this.connManager.connect(endpoint1, null, context);
|
connManager.connect(endpoint1, null, context);
|
||||||
|
|
||||||
final HttpProcessor httpProcessor = new DefaultHttpProcessor(
|
final HttpProcessor httpProcessor = new DefaultHttpProcessor(
|
||||||
new RequestTargetHost(), new RequestContent(), new RequestConnControl());
|
new RequestTargetHost(), new RequestContent(), new RequestConnControl());
|
||||||
|
@ -157,26 +189,26 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that there is no auto-release by default
|
// check that there is no auto-release by default
|
||||||
final LeaseRequest leaseRequest2 = this.connManager.lease("id2", route,null);
|
final LeaseRequest leaseRequest2 = connManager.lease("id2", route, null);
|
||||||
// this should fail quickly, connection has not been released
|
// this should fail quickly, connection has not been released
|
||||||
Assertions.assertThrows(TimeoutException.class, () -> leaseRequest2.get(Timeout.ofMilliseconds(10)));
|
Assertions.assertThrows(TimeoutException.class, () -> leaseRequest2.get(Timeout.ofMilliseconds(10)));
|
||||||
|
|
||||||
endpoint1.close();
|
endpoint1.close();
|
||||||
this.connManager.release(endpoint1, null, TimeValue.ofMilliseconds(100));
|
connManager.release(endpoint1, null, TimeValue.ofMilliseconds(100));
|
||||||
|
|
||||||
final LeaseRequest leaseRequest3 = this.connManager.lease("id2", route,null);
|
final LeaseRequest leaseRequest3 = connManager.lease("id2", route, null);
|
||||||
final ConnectionEndpoint endpoint2 = leaseRequest3.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint2 = leaseRequest3.get(Timeout.ZERO_MILLISECONDS);
|
||||||
Assertions.assertFalse(endpoint2.isConnected());
|
Assertions.assertFalse(endpoint2.isConnected());
|
||||||
|
|
||||||
this.connManager.connect(endpoint2, null, context);
|
connManager.connect(endpoint2, null, context);
|
||||||
|
|
||||||
try (final ClassicHttpResponse response2 = endpoint2.execute("id2", request, exec, context)) {
|
try (final ClassicHttpResponse response2 = endpoint2.execute("id2", request, exec, context)) {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connManager.release(endpoint2, null, TimeValue.ofMilliseconds(100));
|
connManager.release(endpoint2, null, TimeValue.ofMilliseconds(100));
|
||||||
|
|
||||||
final LeaseRequest leaseRequest4 = this.connManager.lease("id3", route,null);
|
final LeaseRequest leaseRequest4 = connManager.lease("id3", route, null);
|
||||||
final ConnectionEndpoint endpoint3 = leaseRequest4.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint3 = leaseRequest4.get(Timeout.ZERO_MILLISECONDS);
|
||||||
Assertions.assertTrue(endpoint3.isConnected());
|
Assertions.assertTrue(endpoint3.isConnected());
|
||||||
|
|
||||||
|
@ -185,109 +217,115 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response3.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response3.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connManager.release(endpoint3, null, TimeValue.ofMilliseconds(100));
|
connManager.release(endpoint3, null, TimeValue.ofMilliseconds(100));
|
||||||
Thread.sleep(150);
|
Thread.sleep(150);
|
||||||
|
|
||||||
final LeaseRequest leaseRequest5 = this.connManager.lease("id4", route,null);
|
final LeaseRequest leaseRequest5 = connManager.lease("id4", route, null);
|
||||||
final ConnectionEndpoint endpoint4 = leaseRequest5.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint4 = leaseRequest5.get(Timeout.ZERO_MILLISECONDS);
|
||||||
Assertions.assertFalse(endpoint4.isConnected());
|
Assertions.assertFalse(endpoint4.isConnected());
|
||||||
|
|
||||||
// repeat the communication, no need to prepare the request again
|
// repeat the communication, no need to prepare the request again
|
||||||
this.connManager.connect(endpoint4, null, context);
|
connManager.connect(endpoint4, null, context);
|
||||||
|
|
||||||
try (final ClassicHttpResponse response4 = endpoint4.execute("id4", request, exec, context)) {
|
try (final ClassicHttpResponse response4 = endpoint4.execute("id4", request, exec, context)) {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response4.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response4.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connManager.close();
|
connManager.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCloseExpiredIdleConnections() throws Exception {
|
public void testCloseExpiredIdleConnections() throws Exception {
|
||||||
|
startServer();
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
startClient();
|
||||||
|
|
||||||
this.connManager.setMaxTotal(1);
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
connManager.setMaxTotal(1);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
final HttpContext context = new BasicHttpContext();
|
final HttpContext context = new BasicHttpContext();
|
||||||
|
|
||||||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
final LeaseRequest leaseRequest1 = connManager.lease("id1", route, null);
|
||||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||||
this.connManager.connect(endpoint1, null, context);
|
connManager.connect(endpoint1, null, context);
|
||||||
|
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getLeased());
|
Assertions.assertEquals(1, connManager.getTotalStats().getLeased());
|
||||||
Assertions.assertEquals(1, this.connManager.getStats(route).getLeased());
|
Assertions.assertEquals(1, connManager.getStats(route).getLeased());
|
||||||
|
|
||||||
this.connManager.release(endpoint1, null, TimeValue.ofMilliseconds(100));
|
connManager.release(endpoint1, null, TimeValue.ofMilliseconds(100));
|
||||||
|
|
||||||
// Released, still active.
|
// Released, still active.
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
Assertions.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
Assertions.assertEquals(1, connManager.getStats(route).getAvailable());
|
||||||
|
|
||||||
this.connManager.closeExpired();
|
connManager.closeExpired();
|
||||||
|
|
||||||
// Time has not expired yet.
|
// Time has not expired yet.
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
Assertions.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
Assertions.assertEquals(1, connManager.getStats(route).getAvailable());
|
||||||
|
|
||||||
Thread.sleep(150);
|
Thread.sleep(150);
|
||||||
|
|
||||||
this.connManager.closeExpired();
|
connManager.closeExpired();
|
||||||
|
|
||||||
// Time expired now, connections are destroyed.
|
// Time expired now, connections are destroyed.
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(0, connManager.getTotalStats().getAvailable());
|
||||||
Assertions.assertEquals(0, this.connManager.getStats(route).getAvailable());
|
Assertions.assertEquals(0, connManager.getStats(route).getAvailable());
|
||||||
|
|
||||||
this.connManager.close();
|
connManager.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test @Disabled
|
||||||
public void testCloseExpiredTTLConnections() throws Exception {
|
public void testCloseExpiredTTLConnections() throws Exception {
|
||||||
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
this.connManager = new PoolingHttpClientConnectionManager(
|
testResources.startClient(
|
||||||
RegistryBuilder.<ConnectionSocketFactory>create()
|
builder -> builder
|
||||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
.setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
|
||||||
.register("https", SSLConnectionSocketFactory.getSocketFactory())
|
.setConnPoolPolicy(PoolReusePolicy.LIFO)
|
||||||
.build(),
|
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
||||||
PoolConcurrencyPolicy.STRICT,
|
.setTimeToLive(TimeValue.ofMilliseconds(100))
|
||||||
PoolReusePolicy.LIFO,
|
.build())
|
||||||
TimeValue.ofMilliseconds(100));
|
.setMaxConnTotal(1),
|
||||||
this.clientBuilder.setConnectionManager(this.connManager);
|
builder -> {}
|
||||||
|
);
|
||||||
|
|
||||||
this.connManager.setMaxTotal(1);
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
final HttpRoute route = new HttpRoute(target, null, false);
|
final HttpRoute route = new HttpRoute(target, null, false);
|
||||||
final HttpContext context = new BasicHttpContext();
|
final HttpContext context = new BasicHttpContext();
|
||||||
|
|
||||||
final LeaseRequest leaseRequest1 = this.connManager.lease("id1", route,null);
|
final LeaseRequest leaseRequest1 = connManager.lease("id1", route, null);
|
||||||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
final ConnectionEndpoint endpoint1 = leaseRequest1.get(Timeout.ZERO_MILLISECONDS);
|
||||||
this.connManager.connect(endpoint1, null, context);
|
connManager.connect(endpoint1, null, context);
|
||||||
|
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getLeased());
|
Assertions.assertEquals(1, connManager.getTotalStats().getLeased());
|
||||||
Assertions.assertEquals(1, this.connManager.getStats(route).getLeased());
|
Assertions.assertEquals(1, connManager.getStats(route).getLeased());
|
||||||
// Release, let remain idle for forever
|
// Release, let remain idle for forever
|
||||||
this.connManager.release(endpoint1, null, TimeValue.NEG_ONE_MILLISECOND);
|
connManager.release(endpoint1, null, TimeValue.NEG_ONE_MILLISECOND);
|
||||||
|
|
||||||
// Released, still active.
|
// Released, still active.
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
Assertions.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
Assertions.assertEquals(1, connManager.getStats(route).getAvailable());
|
||||||
|
|
||||||
this.connManager.closeExpired();
|
connManager.closeExpired();
|
||||||
|
|
||||||
// Time has not expired yet.
|
// Time has not expired yet.
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
Assertions.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
Assertions.assertEquals(1, connManager.getStats(route).getAvailable());
|
||||||
|
|
||||||
Thread.sleep(150);
|
Thread.sleep(150);
|
||||||
|
|
||||||
this.connManager.closeExpired();
|
connManager.closeExpired();
|
||||||
|
|
||||||
// TTL expired now, connections are destroyed.
|
// TTL expired now, connections are destroyed.
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(0, connManager.getTotalStats().getAvailable());
|
||||||
Assertions.assertEquals(0, this.connManager.getStats(route).getAvailable());
|
Assertions.assertEquals(0, connManager.getStats(route).getAvailable());
|
||||||
|
|
||||||
this.connManager.close();
|
connManager.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,9 @@ import java.util.List;
|
||||||
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.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||||
|
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
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;
|
||||||
|
@ -47,27 +50,49 @@ 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.HttpResponseInterceptor;
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
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.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.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
public class TestConnectionReuse extends LocalServerTestBase {
|
public class TestConnectionReuse {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@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 {
|
||||||
this.connManager.setMaxTotal(5);
|
final ClassicTestServer server = testResources.startServer( null, null, null);
|
||||||
this.connManager.setDefaultMaxPerRoute(5);
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setMaxConnTotal(5)
|
||||||
|
.setMaxConnPerRoute(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++) {
|
||||||
workers[i] = new WorkerThread(
|
workers[i] = new WorkerThread(
|
||||||
this.httpclient,
|
client,
|
||||||
target,
|
target,
|
||||||
new URI("/random/2000"),
|
new URI("/random/2000"),
|
||||||
10, false);
|
10, false);
|
||||||
|
@ -85,17 +110,26 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expect leased connections to be returned
|
// Expect leased connections to be returned
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getLeased());
|
Assertions.assertEquals(0, connManager.getTotalStats().getLeased());
|
||||||
// Expect some connection in the pool
|
// Expect some connection in the pool
|
||||||
Assertions.assertTrue(this.connManager.getTotalStats().getAvailable() > 0);
|
Assertions.assertTrue(connManager.getTotalStats().getAvailable() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReuseOfPersistentConnectionsWithStreamedRequestAndResponse() throws Exception {
|
public void testReuseOfPersistentConnectionsWithStreamedRequestAndResponse() throws Exception {
|
||||||
this.connManager.setMaxTotal(5);
|
final ClassicTestServer server = testResources.startServer( null, null, null);
|
||||||
this.connManager.setDefaultMaxPerRoute(5);
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setMaxConnTotal(5)
|
||||||
|
.setMaxConnPerRoute(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++) {
|
||||||
|
@ -108,7 +142,7 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
||||||
ContentType.APPLICATION_OCTET_STREAM));
|
ContentType.APPLICATION_OCTET_STREAM));
|
||||||
requests.add(post);
|
requests.add(post);
|
||||||
}
|
}
|
||||||
workers[i] = new WorkerThread(this.httpclient, target, false, requests);
|
workers[i] = new WorkerThread(client, target, false, requests);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final WorkerThread worker : workers) {
|
for (final WorkerThread worker : workers) {
|
||||||
|
@ -123,9 +157,9 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expect leased connections to be returned
|
// Expect leased connections to be returned
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getLeased());
|
Assertions.assertEquals(0, connManager.getTotalStats().getLeased());
|
||||||
// Expect some connection in the pool
|
// Expect some connection in the pool
|
||||||
Assertions.assertTrue(this.connManager.getTotalStats().getAvailable() > 0);
|
Assertions.assertTrue(connManager.getTotalStats().getAvailable() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AlwaysCloseConn implements HttpResponseInterceptor {
|
private static class AlwaysCloseConn implements HttpResponseInterceptor {
|
||||||
|
@ -142,18 +176,26 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReuseOfClosedConnections() throws Exception {
|
public void testReuseOfClosedConnections() throws Exception {
|
||||||
this.connManager.setMaxTotal(5);
|
|
||||||
this.connManager.setDefaultMaxPerRoute(5);
|
|
||||||
|
|
||||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||||
.add(new AlwaysCloseConn())
|
.add(new AlwaysCloseConn())
|
||||||
.build();
|
.build();
|
||||||
final HttpHost target = start(httpproc, null);
|
final ClassicTestServer server = testResources.startServer( null, httpproc, null);
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setMaxConnTotal(5)
|
||||||
|
.setMaxConnPerRoute(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++) {
|
||||||
workers[i] = new WorkerThread(
|
workers[i] = new WorkerThread(
|
||||||
this.httpclient,
|
client,
|
||||||
target,
|
target,
|
||||||
new URI("/random/2000"),
|
new URI("/random/2000"),
|
||||||
10, false);
|
10, false);
|
||||||
|
@ -171,22 +213,31 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expect leased connections to be returned
|
// Expect leased connections to be returned
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getLeased());
|
Assertions.assertEquals(0, connManager.getTotalStats().getLeased());
|
||||||
// Expect zero connections in the pool
|
// Expect zero connections in the pool
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(0, connManager.getTotalStats().getAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReuseOfAbortedConnections() throws Exception {
|
public void testReuseOfAbortedConnections() throws Exception {
|
||||||
this.connManager.setMaxTotal(5);
|
final ClassicTestServer server = testResources.startServer( null, null, null);
|
||||||
this.connManager.setDefaultMaxPerRoute(5);
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setMaxConnTotal(5)
|
||||||
|
.setMaxConnPerRoute(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++) {
|
||||||
workers[i] = new WorkerThread(
|
workers[i] = new WorkerThread(
|
||||||
this.httpclient,
|
client,
|
||||||
target,
|
target,
|
||||||
new URI("/random/2000"),
|
new URI("/random/2000"),
|
||||||
10, true);
|
10, true);
|
||||||
|
@ -204,55 +255,65 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expect leased connections to be returned
|
// Expect leased connections to be returned
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getLeased());
|
Assertions.assertEquals(0, connManager.getTotalStats().getLeased());
|
||||||
// Expect some connections in the pool
|
// Expect some connections in the pool
|
||||||
Assertions.assertTrue(this.connManager.getTotalStats().getAvailable() > 0);
|
Assertions.assertTrue(connManager.getTotalStats().getAvailable() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testKeepAliveHeaderRespected() throws Exception {
|
public void testKeepAliveHeaderRespected() throws Exception {
|
||||||
this.connManager.setMaxTotal(1);
|
|
||||||
this.connManager.setDefaultMaxPerRoute(1);
|
|
||||||
|
|
||||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||||
.add(new ResponseKeepAlive())
|
.add(new ResponseKeepAlive())
|
||||||
.build();
|
.build();
|
||||||
final HttpHost target = start(httpproc, null);
|
final ClassicTestServer server = testResources.startServer( null, httpproc, null);
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
this.httpclient.execute(target, new HttpGet("/random/2000"), response -> {
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setMaxConnTotal(1)
|
||||||
|
.setMaxConnPerRoute(1),
|
||||||
|
builder -> {
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
|
||||||
|
|
||||||
|
client.execute(target, new HttpGet("/random/2000"), response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
|
|
||||||
this.httpclient.execute(target, new HttpGet("/random/2000"), response -> {
|
client.execute(target, new HttpGet("/random/2000"), response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
|
|
||||||
// Now sleep for 1.1 seconds and let the timeout do its work
|
// Now sleep for 1.1 seconds and let the timeout do its work
|
||||||
Thread.sleep(1100);
|
Thread.sleep(1100);
|
||||||
this.httpclient.execute(target, new HttpGet("/random/2000"), response -> {
|
client.execute(target, new HttpGet("/random/2000"), response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
|
|
||||||
// Do another request just under the 1 second limit & make
|
// Do another request just under the 1 second limit & make
|
||||||
// sure we reuse that connection.
|
// sure we reuse that connection.
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
this.httpclient.execute(target, new HttpGet("/random/2000"), response -> {
|
client.execute(target, new HttpGet("/random/2000"), response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expect leased connections to be returned
|
// Expect leased connections to be returned
|
||||||
Assertions.assertEquals(0, this.connManager.getTotalStats().getLeased());
|
Assertions.assertEquals(0, connManager.getTotalStats().getLeased());
|
||||||
Assertions.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
Assertions.assertEquals(1, connManager.getTotalStats().getAvailable());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class WorkerThread extends Thread {
|
private static class WorkerThread extends Thread {
|
||||||
|
|
|
@ -38,33 +38,62 @@ 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.testing.sync.extension.TestClientResources;
|
||||||
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;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
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.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;
|
||||||
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.junit.Test;
|
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.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 class TestContentCodings extends LocalServerTestBase {
|
public class TestContentCodings {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
|
public ClassicTestServer startServer() throws IOException {
|
||||||
|
return testResources.startServer(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient(final Consumer<HttpClientBuilder> clientCustomizer) {
|
||||||
|
return testResources.startClient(clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient() {
|
||||||
|
return testResources.startClient(builder -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHost targetHost() {
|
||||||
|
return testResources.targetHost();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for when we don't get an entity back; e.g. for a 204 or 304 response; nothing blows
|
* Test for when we don't get an entity back; e.g. for a 204 or 304 response; nothing blows
|
||||||
|
@ -75,7 +104,8 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testResponseWithNoContent() throws Exception {
|
public void testResponseWithNoContent() throws Exception {
|
||||||
this.server.registerHandler("*", new HttpRequestHandler() {
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", new HttpRequestHandler() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
|
@ -89,10 +119,12 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
this.httpclient.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_NO_CONTENT, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_NO_CONTENT, response.getCode());
|
||||||
Assertions.assertNull(response.getEntity());
|
Assertions.assertNull(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -109,12 +141,15 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
this.httpclient.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
Assertions.assertEquals(entityText, EntityUtils.toString(response.getEntity()),
|
Assertions.assertEquals(entityText, EntityUtils.toString(response.getEntity()),
|
||||||
"The entity text is correctly transported");
|
"The entity text is correctly transported");
|
||||||
return null;
|
return null;
|
||||||
|
@ -131,12 +166,15 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
this.httpclient.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
Assertions.assertEquals(entityText, EntityUtils.toString(response.getEntity()),
|
Assertions.assertEquals(entityText, EntityUtils.toString(response.getEntity()),
|
||||||
"The entity text is correctly transported");
|
"The entity text is correctly transported");
|
||||||
return null;
|
return null;
|
||||||
|
@ -152,12 +190,15 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
this.httpclient.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
Assertions.assertEquals(entityText, EntityUtils.toString(response.getEntity()),
|
Assertions.assertEquals(entityText, EntityUtils.toString(response.getEntity()),
|
||||||
"The entity text is correctly transported");
|
"The entity text is correctly transported");
|
||||||
return null;
|
return null;
|
||||||
|
@ -174,7 +215,13 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||||
|
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
@ -182,9 +229,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
*/
|
*/
|
||||||
final int clients = 100;
|
final int clients = 100;
|
||||||
|
|
||||||
this.connManager.setMaxTotal(clients);
|
connManager.setMaxTotal(clients);
|
||||||
|
|
||||||
final HttpHost target = start();
|
|
||||||
|
|
||||||
final ExecutorService executor = Executors.newFixedThreadPool(clients);
|
final ExecutorService executor = Executors.newFixedThreadPool(clients);
|
||||||
|
|
||||||
|
@ -194,7 +239,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
final List<WorkerTask> workers = new ArrayList<>();
|
final List<WorkerTask> workers = new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < clients; ++i) {
|
for (int i = 0; i < clients; ++i) {
|
||||||
workers.add(new WorkerTask(this.httpclient, target, i % 2 == 0, startGate, endGate));
|
workers.add(new WorkerTask(client, target, i % 2 == 0, startGate, endGate));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final WorkerTask workerTask : workers) {
|
for (final WorkerTask workerTask : workers) {
|
||||||
|
@ -220,12 +265,15 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
this.httpclient.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
response.getEntity().writeTo(out);
|
response.getEntity().writeTo(out);
|
||||||
Assertions.assertEquals(entityText, out.toString("utf-8"));
|
Assertions.assertEquals(entityText, out.toString("utf-8"));
|
||||||
|
@ -238,12 +286,15 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
this.httpclient.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
response.getEntity().writeTo(out);
|
response.getEntity().writeTo(out);
|
||||||
Assertions.assertEquals(entityText, out.toString("utf-8"));
|
Assertions.assertEquals(entityText, out.toString("utf-8"));
|
||||||
|
@ -255,12 +306,15 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
final String response = this.httpclient.execute(target, request, new BasicHttpClientResponseHandler());
|
final String response = client.execute(target, request, new BasicHttpClientResponseHandler());
|
||||||
Assertions.assertEquals(entityText, response, "The entity text is correctly transported");
|
Assertions.assertEquals(entityText, response, "The entity text is correctly transported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,12 +322,15 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
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.";
|
||||||
|
|
||||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
final ClassicTestServer server = startServer();
|
||||||
|
server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
|
|
||||||
final HttpGet request = new HttpGet("/some-resource");
|
final HttpGet request = new HttpGet("/some-resource");
|
||||||
final String response = this.httpclient.execute(target, request, new BasicHttpClientResponseHandler());
|
final String response = client.execute(target, request, new BasicHttpClientResponseHandler());
|
||||||
Assertions.assertEquals(entityText, response, "The entity text is correctly transported");
|
Assertions.assertEquals(entityText, response, "The entity text is correctly transported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +494,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
||||||
try {
|
try {
|
||||||
startGate.await();
|
startGate.await();
|
||||||
try {
|
try {
|
||||||
text = httpclient.execute(target, request, response ->
|
text = client.execute(target, request, response ->
|
||||||
EntityUtils.toString(response.getEntity()));
|
EntityUtils.toString(response.getEntity()));
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
failed = true;
|
failed = true;
|
||||||
|
|
|
@ -33,22 +33,34 @@ 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.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.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.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 extends LocalServerTestBase {
|
public class TestCookieVirtualHost {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCookieMatchingWithVirtualHosts() throws Exception {
|
public void testCookieMatchingWithVirtualHosts() throws Exception {
|
||||||
this.server.registerHandlerVirtual("app.mydomain.fr", "*", (request, response, context) -> {
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
|
server.registerHandlerVirtual("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) {
|
||||||
|
@ -87,7 +99,9 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = testResources.startClient(b -> {});
|
||||||
|
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -96,7 +110,7 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
|
||||||
// First request : retrieve a domain cookie from remote server.
|
// First request : retrieve a domain cookie from remote server.
|
||||||
final HttpGet request1 = new HttpGet(new URI("http://app.mydomain.fr"));
|
final HttpGet request1 = new HttpGet(new URI("http://app.mydomain.fr"));
|
||||||
request1.addHeader("X-Request", "1");
|
request1.addHeader("X-Request", "1");
|
||||||
this.httpclient.execute(target, request1, context, response -> {
|
client.execute(target, request1, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -110,7 +124,7 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
|
||||||
// Second request : send the cookie back.
|
// Second request : send the cookie back.
|
||||||
final HttpGet request2 = new HttpGet(new URI("http://app.mydomain.fr"));
|
final HttpGet request2 = new HttpGet(new URI("http://app.mydomain.fr"));
|
||||||
request2.addHeader("X-Request", "2");
|
request2.addHeader("X-Request", "2");
|
||||||
this.httpclient.execute(target, request2, context, response -> {
|
client.execute(target, request2, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -118,7 +132,7 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
|
||||||
// Third request : Host header
|
// Third request : Host header
|
||||||
final HttpGet request3 = new HttpGet(new URI("http://app.mydomain.fr"));
|
final HttpGet request3 = new HttpGet(new URI("http://app.mydomain.fr"));
|
||||||
request3.addHeader("X-Request", "3");
|
request3.addHeader("X-Request", "3");
|
||||||
this.httpclient.execute(target, request3, context, response -> {
|
client.execute(target, request3, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,27 +33,45 @@ import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
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.IdleConnectionEvictor;
|
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.testing.classic.RandomHandler;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
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.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.junit.Test;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
public class TestIdleConnectionEviction extends LocalServerTestBase {
|
public class TestIdleConnectionEviction {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIdleConnectionEviction() throws Exception {
|
public void testIdleConnectionEviction() throws Exception {
|
||||||
this.connManager.setDefaultMaxPerRoute(10);
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
this.connManager.setMaxTotal(50);
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = testResources.startClient(b -> {});
|
||||||
|
|
||||||
final IdleConnectionEvictor idleConnectionMonitor = new IdleConnectionEvictor(this.connManager, TimeValue.ofMilliseconds(50));
|
final PoolingHttpClientConnectionManager connManager = testResources.connManager();
|
||||||
|
|
||||||
|
connManager.setDefaultMaxPerRoute(10);
|
||||||
|
connManager.setMaxTotal(50);
|
||||||
|
|
||||||
|
final IdleConnectionEvictor idleConnectionMonitor = new IdleConnectionEvictor(connManager, TimeValue.ofMilliseconds(50));
|
||||||
idleConnectionMonitor.start();
|
idleConnectionMonitor.start();
|
||||||
|
|
||||||
final URI requestUri = new URI("/random/1024");
|
final URI requestUri = new URI("/random/1024");
|
||||||
final WorkerThread[] workers = new WorkerThread[5];
|
final WorkerThread[] workers = new WorkerThread[5];
|
||||||
for (int i = 0; i < workers.length; i++) {
|
for (int i = 0; i < workers.length; i++) {
|
||||||
workers[i] = new WorkerThread(httpclient, target, requestUri, 200);
|
workers[i] = new WorkerThread(client, target, requestUri, 200);
|
||||||
}
|
}
|
||||||
for (final WorkerThread worker : workers) {
|
for (final WorkerThread worker : workers) {
|
||||||
worker.start();
|
worker.start();
|
||||||
|
|
|
@ -32,8 +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.HttpClients;
|
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.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;
|
||||||
|
@ -41,17 +42,26 @@ import org.apache.hc.core5.http.HttpException;
|
||||||
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.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.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.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client protocol handling tests.
|
* Client protocol handling tests.
|
||||||
*/
|
*/
|
||||||
public class TestMinimalClientRequestExecution extends LocalServerTestBase {
|
public class TestMinimalClientRequestExecution {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
private static class SimpleService implements HttpRequestHandler {
|
private static class SimpleService implements HttpRequestHandler {
|
||||||
|
|
||||||
|
@ -72,14 +82,16 @@ public class TestMinimalClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonCompliantURIWithContext() throws Exception {
|
public void testNonCompliantURIWithContext() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
this.httpclient = HttpClients.createMinimal();
|
server.registerHandler("*", new SimpleService());
|
||||||
final HttpHost target = start();
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
|
final MinimalHttpClient client = testResources.startMinimalClient();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
final HttpGet request = new HttpGet("/");
|
final HttpGet request = new HttpGet("/");
|
||||||
this.httpclient.execute(target, request, context, response -> {
|
client.execute(target, request, context, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
@ -102,13 +114,15 @@ public class TestMinimalClientRequestExecution extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonCompliantURIWithoutContext() throws Exception {
|
public void testNonCompliantURIWithoutContext() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
this.httpclient = HttpClients.createMinimal();
|
server.registerHandler("*", new SimpleService());
|
||||||
final HttpHost target = start();
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
|
final MinimalHttpClient client = testResources.startMinimalClient();
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
final HttpGet request = new HttpGet("/");
|
final HttpGet request = new HttpGet("/");
|
||||||
this.httpclient.execute(target, request, response -> {
|
client.execute(target, request, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -33,6 +33,7 @@ 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;
|
||||||
|
@ -42,12 +43,17 @@ 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;
|
||||||
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
||||||
|
import org.apache.hc.client5.testing.classic.EchoHandler;
|
||||||
|
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.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;
|
||||||
|
@ -57,30 +63,61 @@ 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.ProtocolException;
|
import org.apache.hc.core5.http.ProtocolException;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
||||||
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.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.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirection test cases.
|
* Redirection test cases.
|
||||||
*/
|
*/
|
||||||
public class TestRedirects extends LocalServerTestBase {
|
public class TestRedirects {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return testResources.startClient(clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient() {
|
||||||
|
return testResources.startClient(builder -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHost targetHost() {
|
||||||
|
return testResources.targetHost();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
||||||
|
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");
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -96,14 +133,18 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
||||||
Redirect.ConnControl.CLOSE)));
|
Redirect.ConnControl.CLOSE)));
|
||||||
|
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");
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -120,15 +161,18 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301() throws Exception {
|
public void testBasicRedirect301() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
||||||
|
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");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -148,15 +192,18 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302() throws Exception {
|
public void testBasicRedirect302() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
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/50");
|
final HttpGet httpget = new HttpGet("/oldlocation/50");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -170,7 +217,7 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302NoLocation() throws Exception {
|
public void testBasicRedirect302NoLocation() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -179,12 +226,15 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
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");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
final HttpRequest reqWrapper = context.getRequest();
|
final HttpRequest reqWrapper = context.getRequest();
|
||||||
|
|
||||||
Assertions.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_MOVED_TEMPORARILY, response.getCode());
|
||||||
|
@ -197,15 +247,18 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect303() throws Exception {
|
public void testBasicRedirect303() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
||||||
|
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/123");
|
final HttpGet httpget = new HttpGet("/oldlocation/123");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -218,18 +271,21 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect304() throws Exception {
|
public void testBasicRedirect304() throws Exception {
|
||||||
this.server.registerHandler("/oldlocation/*", (request, response, context) -> {
|
final ClassicTestServer server = startServer(null ,null);
|
||||||
|
server.registerHandler("/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");
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
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/stuff");
|
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_NOT_MODIFIED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_NOT_MODIFIED, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -246,18 +302,21 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect305() throws Exception {
|
public void testBasicRedirect305() throws Exception {
|
||||||
this.server.registerHandler("/oldlocation/*", (request, response, context) -> {
|
final ClassicTestServer server = startServer(null ,null);
|
||||||
|
server.registerHandler("/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");
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
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/stuff");
|
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_USE_PROXY, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_USE_PROXY, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -274,15 +333,18 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect307() throws Exception {
|
public void testBasicRedirect307() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
||||||
|
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/123");
|
final HttpGet httpget = new HttpGet("/oldlocation/123");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -295,11 +357,14 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxRedirectCheck() throws Exception {
|
public void testMaxRedirectCheck() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(true)
|
.setCircularRedirectsAllowed(true)
|
||||||
.setMaxRedirects(5)
|
.setMaxRedirects(5)
|
||||||
|
@ -308,17 +373,20 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
final HttpGet httpget = new HttpGet("/circular-oldlocation/123");
|
final HttpGet httpget = new HttpGet("/circular-oldlocation/123");
|
||||||
httpget.setConfig(config);
|
httpget.setConfig(config);
|
||||||
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
||||||
this.httpclient.execute(target, httpget, response -> null));
|
client.execute(target, httpget, response -> null));
|
||||||
Assertions.assertTrue(exception.getCause() instanceof RedirectException);
|
Assertions.assertTrue(exception.getCause() instanceof RedirectException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCircularRedirect() throws Exception {
|
public void testCircularRedirect() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY)));
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(false)
|
.setCircularRedirectsAllowed(false)
|
||||||
.build();
|
.build();
|
||||||
|
@ -326,22 +394,25 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
final HttpGet httpget = new HttpGet("/circular-oldlocation/123");
|
final HttpGet httpget = new HttpGet("/circular-oldlocation/123");
|
||||||
httpget.setConfig(config);
|
httpget.setConfig(config);
|
||||||
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
final ClientProtocolException exception = Assertions.assertThrows(ClientProtocolException.class, () ->
|
||||||
this.httpclient.execute(target, httpget, response -> null));
|
client.execute(target, httpget, response -> null));
|
||||||
Assertions.assertTrue(exception.getCause() instanceof CircularRedirectException);
|
Assertions.assertTrue(exception.getCause() instanceof CircularRedirectException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirectSeeOther() throws Exception {
|
public void testPostRedirectSeeOther() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
||||||
|
server.registerHandler("/echo/*", new EchoHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpPost httppost = new HttpPost("/oldlocation/stuff");
|
final HttpPost httppost = new HttpPost("/oldlocation/stuff");
|
||||||
httppost.setEntity(new StringEntity("stuff"));
|
httppost.setEntity(new StringEntity("stuff"));
|
||||||
|
|
||||||
this.httpclient.execute(target, httppost, context, response -> {
|
client.execute(target, httppost, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -355,7 +426,7 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect() throws Exception {
|
public void testRelativeRedirect() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -364,12 +435,15 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
})); 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/stuff");
|
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -382,7 +456,7 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect2() throws Exception {
|
public void testRelativeRedirect2() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -392,12 +466,15 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
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("/random/oldlocation");
|
final HttpGet httpget = new HttpGet("/random/oldlocation");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -410,7 +487,7 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectBogusRedirectLocation() throws Exception {
|
public void testRejectBogusRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -420,17 +497,20 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
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, () ->
|
||||||
this.httpclient.execute(target, httpget, response -> null));
|
client.execute(target, httpget, response -> null));
|
||||||
assertThat(exception.getCause(), CoreMatchers.instanceOf(HttpException.class));
|
assertThat(exception.getCause(), CoreMatchers.instanceOf(HttpException.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
requestUri -> {
|
requestUri -> {
|
||||||
final String path = requestUri.getPath();
|
final String path = requestUri.getPath();
|
||||||
|
@ -440,20 +520,26 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
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, () ->
|
||||||
this.httpclient.execute(target, httpget, response -> null));
|
client.execute(target, httpget, response -> null));
|
||||||
assertThat(exception.getCause(), CoreMatchers.instanceOf(ProtocolException.class));
|
assertThat(exception.getCause(), CoreMatchers.instanceOf(ProtocolException.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedirectWithCookie() throws Exception {
|
public void testRedirectWithCookie() throws Exception {
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
|
final CloseableHttpClient client = startClient();
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
|
|
||||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||||
|
@ -463,10 +549,11 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
cookieStore.addCookie(cookie);
|
cookieStore.addCookie(cookie);
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
context.setCookieStore(cookieStore);
|
context.setCookieStore(cookieStore);
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -482,17 +569,21 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultHeadersRedirect() throws Exception {
|
public void testDefaultHeadersRedirect() throws Exception {
|
||||||
this.clientBuilder.setDefaultHeaders(Collections.singletonList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")));
|
final CloseableHttpClient client = startClient(builder -> builder
|
||||||
|
.setDefaultHeaders(Collections.singletonList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")))
|
||||||
|
);
|
||||||
|
|
||||||
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
final ClassicTestServer server = startServer(null, requestHandler -> new RedirectingDecorator(
|
||||||
requestHandler,
|
requestHandler,
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
|
server.registerHandler("/random/*", new RandomHandler());
|
||||||
|
final HttpHost target = targetHost();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
@ -509,7 +600,7 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
@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 HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final ClassicTestServer server = startServer(null, new Decorator<HttpServerRequestHandler>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
||||||
|
@ -532,12 +623,15 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
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");
|
||||||
|
|
||||||
this.httpclient.execute(target, httpget, context, response -> {
|
client.execute(target, httpget, context, response -> {
|
||||||
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -40,12 +40,14 @@ import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
|
||||||
import org.apache.hc.client5.http.impl.auth.SPNegoScheme;
|
import org.apache.hc.client5.http.impl.auth.SPNegoScheme;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
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;
|
||||||
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.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.io.HttpRequestHandler;
|
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||||
|
@ -53,18 +55,26 @@ 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.testing.classic.ClassicTestServer;
|
||||||
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.ietf.jgss.GSSContext;
|
import org.ietf.jgss.GSSContext;
|
||||||
import org.ietf.jgss.GSSManager;
|
import org.ietf.jgss.GSSManager;
|
||||||
import org.ietf.jgss.GSSName;
|
import org.ietf.jgss.GSSName;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link SPNegoScheme}.
|
* Tests for {@link SPNegoScheme}.
|
||||||
*/
|
*/
|
||||||
public class TestSPNegoScheme extends LocalServerTestBase {
|
public class TestSPNegoScheme {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service will continue to ask for authentication.
|
* This service will continue to ask for authentication.
|
||||||
|
@ -150,8 +160,9 @@ public class TestSPNegoScheme extends LocalServerTestBase {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDontTryToAuthenticateEndlessly() throws Exception {
|
public void testDontTryToAuthenticateEndlessly() throws Exception {
|
||||||
this.server.registerHandler("*", new PleaseNegotiateService());
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new PleaseNegotiateService());
|
||||||
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
final AuthSchemeFactory nsf = new NegotiateSchemeFactoryWithMockGssManager();
|
final AuthSchemeFactory nsf = new NegotiateSchemeFactoryWithMockGssManager();
|
||||||
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
|
||||||
|
@ -161,14 +172,15 @@ public class TestSPNegoScheme extends LocalServerTestBase {
|
||||||
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||||
.register(StandardAuthScheme.SPNEGO, nsf)
|
.register(StandardAuthScheme.SPNEGO, nsf)
|
||||||
.build();
|
.build();
|
||||||
this.httpclient = HttpClients.custom()
|
|
||||||
|
final CloseableHttpClient client = testResources.startClient(builder -> builder
|
||||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||||
.setDefaultCredentialsProvider(credentialsProvider)
|
.setDefaultCredentialsProvider(credentialsProvider)
|
||||||
.build();
|
);
|
||||||
|
|
||||||
final String s = "/path";
|
final String s = "/path";
|
||||||
final HttpGet httpget = new HttpGet(s);
|
final HttpGet httpget = new HttpGet(s);
|
||||||
this.httpclient.execute(target, httpget, response -> {
|
client.execute(target, httpget, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
@ -181,8 +193,9 @@ public class TestSPNegoScheme extends LocalServerTestBase {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNoTokenGeneratedError() throws Exception {
|
public void testNoTokenGeneratedError() throws Exception {
|
||||||
this.server.registerHandler("*", new PleaseNegotiateService());
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
final HttpHost target = start();
|
server.registerHandler("*", new PleaseNegotiateService());
|
||||||
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
final AuthSchemeFactory nsf = new NegotiateSchemeFactoryWithMockGssManager();
|
final AuthSchemeFactory nsf = new NegotiateSchemeFactoryWithMockGssManager();
|
||||||
|
|
||||||
|
@ -193,14 +206,15 @@ public class TestSPNegoScheme extends LocalServerTestBase {
|
||||||
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||||
.register(StandardAuthScheme.SPNEGO, nsf)
|
.register(StandardAuthScheme.SPNEGO, nsf)
|
||||||
.build();
|
.build();
|
||||||
this.httpclient = HttpClients.custom()
|
|
||||||
|
final CloseableHttpClient client = testResources.startClient(builder -> builder
|
||||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||||
.setDefaultCredentialsProvider(credentialsProvider)
|
.setDefaultCredentialsProvider(credentialsProvider)
|
||||||
.build();
|
);
|
||||||
|
|
||||||
final String s = "/path";
|
final String s = "/path";
|
||||||
final HttpGet httpget = new HttpGet(s);
|
final HttpGet httpget = new HttpGet(s);
|
||||||
this.httpclient.execute(target, httpget, response -> {
|
client.execute(target, httpget, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -32,24 +32,35 @@ 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.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
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;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
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.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.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
||||||
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.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 extends LocalServerTestBase {
|
public class TestStatefulConnManagement {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
public static final Timeout LONG_TIMEOUT = Timeout.ofMinutes(3);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
private static class SimpleService implements HttpRequestHandler {
|
private static class SimpleService implements HttpRequestHandler {
|
||||||
|
|
||||||
|
@ -70,22 +81,25 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatefulConnections() throws Exception {
|
public void testStatefulConnections() throws Exception {
|
||||||
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
|
server.registerHandler("*", new SimpleService());
|
||||||
|
final HttpHost target = testResources.targetHost();
|
||||||
|
|
||||||
final int workerCount = 5;
|
final int workerCount = 5;
|
||||||
final int requestCount = 5;
|
final int requestCount = 5;
|
||||||
|
|
||||||
this.server.registerHandler("*", new SimpleService());
|
|
||||||
|
|
||||||
this.connManager.setMaxTotal(workerCount);
|
|
||||||
this.connManager.setDefaultMaxPerRoute(workerCount);
|
|
||||||
|
|
||||||
final UserTokenHandler userTokenHandler = (route, context) -> {
|
final UserTokenHandler userTokenHandler = (route, context) -> {
|
||||||
final String id = (String) context.getAttribute("user");
|
final String id = (String) context.getAttribute("user");
|
||||||
return id;
|
return id;
|
||||||
};
|
};
|
||||||
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
|
.setMaxConnTotal(workerCount)
|
||||||
|
.setMaxConnPerRoute(workerCount),
|
||||||
|
builder -> builder
|
||||||
|
.setUserTokenHandler(userTokenHandler)
|
||||||
|
);
|
||||||
|
|
||||||
final HttpClientContext[] contexts = new HttpClientContext[workerCount];
|
final HttpClientContext[] contexts = new HttpClientContext[workerCount];
|
||||||
final HttpWorker[] workers = new HttpWorker[workerCount];
|
final HttpWorker[] workers = new HttpWorker[workerCount];
|
||||||
|
@ -94,7 +108,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
||||||
contexts[i] = context;
|
contexts[i] = context;
|
||||||
workers[i] = new HttpWorker(
|
workers[i] = new HttpWorker(
|
||||||
"user" + i,
|
"user" + i,
|
||||||
context, requestCount, target, this.httpclient);
|
context, requestCount, target, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final HttpWorker worker : workers) {
|
for (final HttpWorker worker : workers) {
|
||||||
|
@ -181,27 +195,31 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRouteSpecificPoolRecylcing() throws Exception {
|
public void testRouteSpecificPoolRecylcing() throws Exception {
|
||||||
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
|
server.registerHandler("*", new SimpleService());
|
||||||
|
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
|
||||||
// one to the same route.
|
// one to the same route.
|
||||||
|
|
||||||
final int maxConn = 2;
|
final int maxConn = 2;
|
||||||
|
|
||||||
this.server.registerHandler("*", new SimpleService());
|
|
||||||
|
|
||||||
this.connManager.setMaxTotal(maxConn);
|
|
||||||
this.connManager.setDefaultMaxPerRoute(maxConn);
|
|
||||||
|
|
||||||
final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
||||||
|
|
||||||
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
final CloseableHttpClient client = testResources.startClient(
|
||||||
|
builder -> builder
|
||||||
final HttpHost target = start();
|
.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 = new BasicHttpContext();
|
final HttpContext context1 = new BasicHttpContext();
|
||||||
context1.setAttribute("user", "stuff");
|
context1.setAttribute("user", "stuff");
|
||||||
this.httpclient.execute(target, new HttpGet("/"), context1, response -> {
|
client.execute(target, new HttpGet("/"), context1, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -215,7 +233,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
||||||
// 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 = new BasicHttpContext();
|
final HttpContext context2 = new BasicHttpContext();
|
||||||
this.httpclient.execute(new HttpHost("127.0.0.1", this.server.getPort()), new HttpGet("/"), context2, response -> {
|
client.execute(new HttpHost("127.0.0.1", server.getPort()), new HttpGet("/"), context2, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -231,7 +249,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
||||||
// The killed conn is the oldest, which means the first HTTPGet ([localhost][stuff]).
|
// The killed conn is the oldest, which means the first HTTPGet ([localhost][stuff]).
|
||||||
// When this happens, the RouteSpecificPool becomes empty.
|
// When this happens, the RouteSpecificPool becomes empty.
|
||||||
final HttpContext context3 = new BasicHttpContext();
|
final HttpContext context3 = new BasicHttpContext();
|
||||||
this.httpclient.execute(target, new HttpGet("/"), context3, response -> {
|
client.execute(target, new HttpGet("/"), context3, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,32 +32,42 @@ import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.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.win.WinHttpClients;
|
import org.apache.hc.client5.http.impl.win.WinHttpClients;
|
||||||
import org.apache.hc.client5.http.impl.win.WindowsNegotiateSchemeGetTokenFail;
|
import org.apache.hc.client5.http.impl.win.WindowsNegotiateSchemeGetTokenFail;
|
||||||
|
import org.apache.hc.client5.testing.sync.extension.TestClientResources;
|
||||||
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.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
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.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.junit.Assume;
|
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
||||||
import org.junit.Test;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.junit.jupiter.api.Timeout;
|
import org.junit.jupiter.api.Assumptions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for Windows negotiate authentication.
|
* Unit tests for Windows negotiate authentication.
|
||||||
*/
|
*/
|
||||||
public class TestWindowsNegotiateScheme extends LocalServerTestBase {
|
public class TestWindowsNegotiateScheme {
|
||||||
|
|
||||||
|
public static final Timeout TIMEOUT = Timeout.ofMinutes(1);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
private TestClientResources testResources = new TestClientResources(URIScheme.HTTP, TIMEOUT);
|
||||||
|
|
||||||
@Test // this timeout (in ms) needs to be extended if you're actively debugging the code
|
@Test // this timeout (in ms) needs to be extended if you're actively debugging the code
|
||||||
@Timeout(value = 30000, unit = MILLISECONDS)
|
@org.junit.jupiter.api.Timeout(value = 30000, unit = MILLISECONDS)
|
||||||
public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
|
public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
|
||||||
this.server.registerHandler("/", (request, response, context) -> {
|
final ClassicTestServer server = testResources.startServer(null, null, null);
|
||||||
|
server.registerHandler("/", (request, response, context) -> {
|
||||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.SPNEGO);
|
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.SPNEGO);
|
||||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||||
});
|
});
|
||||||
Assume.assumeTrue("Test can only be run on Windows", WinHttpClients.isWinAuthAvailable());
|
final HttpHost target = testResources.targetHost();
|
||||||
|
Assumptions.assumeTrue(WinHttpClients.isWinAuthAvailable(), "Test can only be run on Windows");
|
||||||
|
|
||||||
// HTTPCLIENT-1545
|
// HTTPCLIENT-1545
|
||||||
// If a service principal name (SPN) from outside your Windows domain tree (e.g., HTTP/example.com) is used,
|
// If a service principal name (SPN) from outside your Windows domain tree (e.g., HTTP/example.com) is used,
|
||||||
|
@ -69,12 +79,13 @@ public class TestWindowsNegotiateScheme extends LocalServerTestBase {
|
||||||
|
|
||||||
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||||
.register(StandardAuthScheme.SPNEGO, context -> new WindowsNegotiateSchemeGetTokenFail(StandardAuthScheme.SPNEGO, "HTTP/example.com")).build();
|
.register(StandardAuthScheme.SPNEGO, context -> new WindowsNegotiateSchemeGetTokenFail(StandardAuthScheme.SPNEGO, "HTTP/example.com")).build();
|
||||||
final CloseableHttpClient customClient = HttpClientBuilder.create()
|
|
||||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry).build();
|
|
||||||
|
|
||||||
final HttpHost target = start();
|
final CloseableHttpClient client = testResources.startClient(builder -> builder
|
||||||
|
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||||
|
);
|
||||||
|
|
||||||
final HttpGet httpGet = new HttpGet("/");
|
final HttpGet httpGet = new HttpGet("/");
|
||||||
customClient.execute(target, httpGet, response -> {
|
client.execute(target, httpGet, response -> {
|
||||||
EntityUtils.consume(response.getEntity());
|
EntityUtils.consume(response.getEntity());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.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.PoolingHttpClientConnectionManagerBuilder;
|
||||||
|
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.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.testing.classic.ClassicTestServer;
|
||||||
|
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.BeforeEachCallback;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TestClientResources implements BeforeEachCallback, AfterEachCallback {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(TestClientResources.class);
|
||||||
|
|
||||||
|
private final URIScheme scheme;
|
||||||
|
private final Timeout timeout;
|
||||||
|
|
||||||
|
private ClassicTestServer server;
|
||||||
|
private PoolingHttpClientConnectionManager connManager;
|
||||||
|
private CloseableHttpClient client;
|
||||||
|
|
||||||
|
public TestClientResources(final URIScheme scheme, final Timeout timeout) {
|
||||||
|
this.scheme = scheme;
|
||||||
|
this.timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeEach(final ExtensionContext extensionContext) throws Exception {
|
||||||
|
LOG.debug("Starting up test server");
|
||||||
|
server = new ClassicTestServer(
|
||||||
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
|
||||||
|
SocketConfig.custom()
|
||||||
|
.setSoTimeout(timeout)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterEach(final ExtensionContext extensionContext) throws Exception {
|
||||||
|
LOG.debug("Shutting down test server");
|
||||||
|
|
||||||
|
if (client != null) {
|
||||||
|
client.close(CloseMode.GRACEFUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connManager != null) {
|
||||||
|
connManager.close(CloseMode.IMMEDIATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server != null) {
|
||||||
|
server.shutdown(CloseMode.IMMEDIATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassicTestServer startServer(
|
||||||
|
final Http1Config http1Config,
|
||||||
|
final HttpProcessor httpProcessor,
|
||||||
|
final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
|
||||||
|
Assertions.assertNotNull(server);
|
||||||
|
server.start(http1Config, httpProcessor, handlerDecorator);
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpHost targetHost() {
|
||||||
|
Assertions.assertNotNull(server);
|
||||||
|
return new HttpHost(scheme.id, "localhost", server.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CloseableHttpClient startClient(
|
||||||
|
final Consumer<PoolingHttpClientConnectionManagerBuilder> connManagerCustomizer,
|
||||||
|
final Consumer<HttpClientBuilder> clientCustomizer) {
|
||||||
|
Assertions.assertNull(connManager);
|
||||||
|
Assertions.assertNull(client);
|
||||||
|
|
||||||
|
final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinimalHttpClient startMinimalClient() {
|
||||||
|
Assertions.assertNull(connManager);
|
||||||
|
Assertions.assertNull(client);
|
||||||
|
|
||||||
|
final PoolingHttpClientConnectionManagerBuilder connManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
|
||||||
|
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) {
|
||||||
|
return startClient(b -> {}, clientCustomizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PoolingHttpClientConnectionManager connManager() {
|
||||||
|
Assertions.assertNotNull(connManager);
|
||||||
|
return connManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -38,7 +38,6 @@ 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.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.io.SocketConfig;
|
|
||||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
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;
|
||||||
|
@ -84,7 +83,6 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
||||||
private int maxConnTotal;
|
private int maxConnTotal;
|
||||||
private int maxConnPerRoute;
|
private int maxConnPerRoute;
|
||||||
|
|
||||||
private Resolver<HttpRoute, SocketConfig> socketConfigResolver;
|
|
||||||
private Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver;
|
private Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver;
|
||||||
private Resolver<HttpHost, TlsConfig> tlsConfigResolver;
|
private Resolver<HttpHost, TlsConfig> tlsConfigResolver;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue