Upgraded HttpCore to version 5.0-alpha4
This commit is contained in:
parent
272ea1fa83
commit
b58e7d46d7
|
@ -33,10 +33,10 @@ import java.io.IOException;
|
|||
import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheStorage;
|
||||
import org.apache.hc.client5.http.cache.ResourceFactory;
|
||||
import org.apache.hc.client5.http.impl.NamedElementChain;
|
||||
import org.apache.hc.client5.http.impl.sync.ChainElements;
|
||||
import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
|
||||
import org.apache.hc.client5.http.sync.ExecChainHandler;
|
||||
import org.apache.hc.core5.http.config.NamedElementChain;
|
||||
|
||||
/**
|
||||
* Builder for {@link org.apache.hc.client5.http.impl.sync.CloseableHttpClient}
|
||||
|
|
|
@ -47,7 +47,6 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import org.apache.hc.client5.http.HttpRoute;
|
||||
import org.apache.hc.client5.http.cache.CacheResponseStatus;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheContext;
|
||||
|
@ -71,7 +70,7 @@ import org.apache.hc.core5.http.HttpRequest;
|
|||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.HttpVersion;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
||||
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
||||
|
@ -85,6 +84,8 @@ import org.junit.Assert;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
@SuppressWarnings("boxing") // test code
|
||||
public abstract class TestCachingExecChain {
|
||||
|
||||
|
@ -100,7 +101,7 @@ public abstract class TestCachingExecChain {
|
|||
protected ResponseCachingPolicy mockResponsePolicy;
|
||||
protected HttpCacheEntry mockCacheEntry;
|
||||
protected CachedHttpResponseGenerator mockResponseGenerator;
|
||||
private ResponseHandler<Object> mockHandler;
|
||||
private HttpClientResponseHandler<Object> mockHandler;
|
||||
private ClassicHttpRequest mockUriRequest;
|
||||
private ClassicHttpResponse mockCachedResponse;
|
||||
protected ConditionalRequestBuilder mockConditionalRequestBuilder;
|
||||
|
@ -126,7 +127,7 @@ public abstract class TestCachingExecChain {
|
|||
mockCache = createNiceMock(HttpCache.class);
|
||||
mockSuitabilityChecker = createNiceMock(CachedResponseSuitabilityChecker.class);
|
||||
mockResponsePolicy = createNiceMock(ResponseCachingPolicy.class);
|
||||
mockHandler = createNiceMock(ResponseHandler.class);
|
||||
mockHandler = createNiceMock(HttpClientResponseHandler.class);
|
||||
mockUriRequest = createNiceMock(ClassicHttpRequest.class);
|
||||
mockCacheEntry = createNiceMock(HttpCacheEntry.class);
|
||||
mockResponseGenerator = createNiceMock(CachedHttpResponseGenerator.class);
|
||||
|
|
|
@ -81,7 +81,7 @@ public class TestStaleWhileRevalidationReleasesConnection {
|
|||
.setSocketConfig(SocketConfig.custom()
|
||||
.setSoTimeout(5, TimeUnit.SECONDS)
|
||||
.build())
|
||||
.registerHandler(url + "*", new EchoViaHeaderHandler())
|
||||
.register(url + "*", new EchoViaHeaderHandler())
|
||||
.create();
|
||||
this.localServer.start();
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.apache.hc.client5.http.fluent.Request;
|
|||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpVersion;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates how the he HttpClient fluent API can be used to execute multiple
|
||||
|
@ -52,8 +52,8 @@ public class FluentExecutor {
|
|||
|
||||
// Execute a GET with timeout settings and return response content as String.
|
||||
executor.execute(Request.Get("http://somehost/")
|
||||
.connectTimeout(TimeValue.ofSeconds(1))
|
||||
.socketTimeout(TimeValue.ofSeconds(1))
|
||||
.connectTimeout(Timeout.ofSeconds(1))
|
||||
.socketTimeout(Timeout.ofSeconds(1))
|
||||
).returnContent().asString();
|
||||
|
||||
// Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.apache.hc.client5.http.fluent.Request;
|
|||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpVersion;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates basics of request execution with the HttpClient fluent API.
|
||||
|
@ -43,8 +43,8 @@ public class FluentRequests {
|
|||
public static void main(String[] args)throws Exception {
|
||||
// Execute a GET with timeout settings and return response content as String.
|
||||
Request.Get("http://somehost/")
|
||||
.connectTimeout(TimeValue.ofSeconds(1))
|
||||
.socketTimeout(TimeValue.ofSeconds(1))
|
||||
.connectTimeout(Timeout.ofSeconds(1))
|
||||
.socketTimeout(Timeout.ofSeconds(1))
|
||||
.execute().returnContent().asString();
|
||||
|
||||
// Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
|
|||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.SAXException;
|
||||
|
@ -54,7 +54,7 @@ public class FluentResponseHandling {
|
|||
|
||||
public static void main(String[] args)throws Exception {
|
||||
Document result = Request.Get("http://somehost/content")
|
||||
.execute().handleResponse(new ResponseHandler<Document>() {
|
||||
.execute().handleResponse(new HttpClientResponseHandler<Document>() {
|
||||
|
||||
@Override
|
||||
public Document handleResponse(final ClassicHttpResponse response) throws IOException {
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.concurrent.Future;
|
|||
|
||||
import org.apache.hc.core5.concurrent.BasicFuture;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
|
||||
public class Async {
|
||||
|
||||
|
@ -60,13 +60,13 @@ public class Async {
|
|||
private final BasicFuture<T> future;
|
||||
private final Request request;
|
||||
private final Executor executor;
|
||||
private final ResponseHandler<T> handler;
|
||||
private final HttpClientResponseHandler<T> handler;
|
||||
|
||||
ExecRunnable(
|
||||
final BasicFuture<T> future,
|
||||
final Request request,
|
||||
final Executor executor,
|
||||
final ResponseHandler<T> handler) {
|
||||
final HttpClientResponseHandler<T> handler) {
|
||||
super();
|
||||
this.future = future;
|
||||
this.request = request;
|
||||
|
@ -88,7 +88,7 @@ public class Async {
|
|||
}
|
||||
|
||||
public <T> Future<T> execute(
|
||||
final Request request, final ResponseHandler<T> handler, final FutureCallback<T> callback) {
|
||||
final Request request, final HttpClientResponseHandler<T> handler, final FutureCallback<T> callback) {
|
||||
final BasicFuture<T> future = new BasicFuture<>(callback);
|
||||
final ExecRunnable<T> runnable = new ExecRunnable<>(
|
||||
future,
|
||||
|
@ -105,7 +105,7 @@ public class Async {
|
|||
return future;
|
||||
}
|
||||
|
||||
public <T> Future<T> execute(final Request request, final ResponseHandler<T> handler) {
|
||||
public <T> Future<T> execute(final Request request, final HttpClientResponseHandler<T> handler) {
|
||||
return execute(request, handler, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,20 +28,20 @@ package org.apache.hc.client5.http.fluent;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.hc.client5.http.impl.sync.AbstractResponseHandler;
|
||||
import org.apache.hc.client5.http.impl.sync.AbstractHttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
|
||||
/**
|
||||
* {@link org.apache.hc.core5.http.io.ResponseHandler} implementation that converts
|
||||
* {@link org.apache.hc.core5.http.HttpResponse} messages to {@link Content}
|
||||
* instances.
|
||||
* {@link org.apache.hc.core5.http.io.HttpClientResponseHandler} implementation
|
||||
* that converts {@link org.apache.hc.core5.http.HttpResponse} messages
|
||||
* to {@link Content} instances.
|
||||
*
|
||||
* @see Content
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
public class ContentResponseHandler extends AbstractResponseHandler<Content> {
|
||||
public class ContentResponseHandler extends AbstractHttpClientResponseHandler<Content> {
|
||||
|
||||
@Override
|
||||
public Content handleEntity(final HttpEntity entity) throws IOException {
|
||||
|
|
|
@ -225,7 +225,7 @@ public class Executor {
|
|||
* or discarded using {@link Response#discardContent()}, otherwise the
|
||||
* connection used for the request might not be released to the pool.
|
||||
*
|
||||
* @see Response#handleResponse(org.apache.hc.core5.http.io.ResponseHandler)
|
||||
* @see Response#handleResponse(org.apache.hc.core5.http.io.HttpClientResponseHandler)
|
||||
* @see Response#discardContent()
|
||||
*/
|
||||
public Response execute(
|
||||
|
|
|
@ -66,7 +66,7 @@ import org.apache.hc.core5.http.io.entity.FileEntity;
|
|||
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.net.URLEncodedUtils;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
public class Request {
|
||||
|
||||
|
@ -76,8 +76,8 @@ public class Request {
|
|||
|
||||
private final HttpUriRequestBase request;
|
||||
private Boolean useExpectContinue;
|
||||
private TimeValue socketTmeout;
|
||||
private TimeValue connectTimeout;
|
||||
private Timeout socketTmeout;
|
||||
private Timeout connectTimeout;
|
||||
private HttpHost proxy;
|
||||
|
||||
private SimpleDateFormat dateFormatter;
|
||||
|
@ -283,12 +283,12 @@ public class Request {
|
|||
|
||||
//// HTTP connection parameter operations
|
||||
|
||||
public Request socketTimeout(final TimeValue timeout) {
|
||||
public Request socketTimeout(final Timeout timeout) {
|
||||
this.socketTmeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request connectTimeout(final TimeValue timeout) {
|
||||
public Request connectTimeout(final Timeout timeout) {
|
||||
this.connectTimeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.apache.hc.core5.http.HttpEntity;
|
|||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
|
||||
|
@ -83,10 +83,9 @@ public class Response {
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles the response using the specified {@link ResponseHandler}
|
||||
* Handles the response using the specified {@link HttpClientResponseHandler}
|
||||
*/
|
||||
public <T> T handleResponse(
|
||||
final ResponseHandler<T> handler) throws IOException {
|
||||
public <T> T handleResponse(final HttpClientResponseHandler<T> handler) throws IOException {
|
||||
assertNotConsumed();
|
||||
try {
|
||||
return handler.handleResponse(this.response);
|
||||
|
|
|
@ -34,12 +34,12 @@ import org.apache.hc.core5.http.ContentType;
|
|||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
|
||||
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
|
||||
import org.apache.hc.core5.http.nio.BasicResponseProducer;
|
||||
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
|
||||
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
|
||||
import org.apache.hc.core5.http.nio.support.AbstractAsyncRequesterConsumer;
|
||||
import org.apache.hc.core5.http.nio.support.AbstractServerExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.support.BasicAsyncResponseProducer;
|
||||
import org.apache.hc.core5.http.nio.support.ResponseTrigger;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
||||
|
||||
|
@ -67,10 +67,10 @@ public abstract class AbstractSimpleServerExchangeHandler extends AbstractServer
|
|||
@Override
|
||||
protected final void handle(
|
||||
final SimpleHttpRequest request,
|
||||
final ResponseTrigger responseTrigger,
|
||||
final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final SimpleHttpResponse response = handle(request, HttpCoreContext.adapt(context));
|
||||
responseTrigger.submitResponse(new BasicAsyncResponseProducer(
|
||||
responseTrigger.submitResponse(new BasicResponseProducer(
|
||||
response,
|
||||
response.getBody() != null ? new StringAsyncEntityProducer(response.getBody(), response.getContentType()) : null));
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.hc.core5.http.nio.DataStreamChannel;
|
|||
import org.apache.hc.core5.http.nio.ResponseChannel;
|
||||
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
|
||||
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.Asserts;
|
||||
|
||||
/**
|
||||
|
@ -76,7 +77,8 @@ public class AsyncEchoHandler implements AsyncServerExchangeHandler {
|
|||
public void handleRequest(
|
||||
final HttpRequest request,
|
||||
final EntityDetails entityDetails,
|
||||
final ResponseChannel responseChannel) throws HttpException, IOException {
|
||||
final ResponseChannel responseChannel,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String method = request.getMethod();
|
||||
if (!"GET".equalsIgnoreCase(method) &&
|
||||
!"HEAD".equalsIgnoreCase(method) &&
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.apache.hc.core5.http.nio.DataStreamChannel;
|
|||
import org.apache.hc.core5.http.nio.ResponseChannel;
|
||||
import org.apache.hc.core5.http.nio.StreamChannel;
|
||||
import org.apache.hc.core5.http.nio.entity.AbstractBinAsyncEntityProducer;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.Asserts;
|
||||
|
||||
/**
|
||||
|
@ -77,7 +78,8 @@ public class AsyncRandomHandler implements AsyncServerExchangeHandler {
|
|||
public void handleRequest(
|
||||
final HttpRequest request,
|
||||
final EntityDetails entityDetails,
|
||||
final ResponseChannel responseChannel) throws HttpException, IOException {
|
||||
final ResponseChannel responseChannel,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String method = request.getMethod();
|
||||
if (!"GET".equalsIgnoreCase(method) &&
|
||||
!"HEAD".equalsIgnoreCase(method) &&
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||
import org.apache.hc.client5.testing.auth.BasicAuthTokenExtractor;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.message.BasicHttpResponse;
|
||||
import org.apache.hc.core5.http.nio.AsyncResponseProducer;
|
||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.BasicResponseProducer;
|
||||
import org.apache.hc.core5.http.nio.CapacityChannel;
|
||||
import org.apache.hc.core5.http.nio.DataStreamChannel;
|
||||
import org.apache.hc.core5.http.nio.ResponseChannel;
|
||||
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.net.URIAuthority;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
|
||||
public class AuthenticatingAsyncDecorator implements AsyncServerExchangeHandler {
|
||||
|
||||
private final AsyncServerExchangeHandler exchangeHandler;
|
||||
private final Authenticator authenticator;
|
||||
private final AtomicReference<AsyncResponseProducer> responseProducerRef;
|
||||
private final BasicAuthTokenExtractor authTokenExtractor;
|
||||
|
||||
public AuthenticatingAsyncDecorator(final AsyncServerExchangeHandler exchangeHandler, final Authenticator authenticator) {
|
||||
this.exchangeHandler = Args.notNull(exchangeHandler, "Request handler");
|
||||
this.authenticator = Args.notNull(authenticator, "Authenticator");
|
||||
this.responseProducerRef = new AtomicReference<>(null);
|
||||
this.authTokenExtractor = new BasicAuthTokenExtractor();
|
||||
}
|
||||
|
||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRequest(
|
||||
final HttpRequest request,
|
||||
final EntityDetails entityDetails,
|
||||
final ResponseChannel responseChannel,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final Header h = request.getFirstHeader(HttpHeaders.AUTHORIZATION);
|
||||
final String challengeResponse = h != null ? authTokenExtractor.extract(h.getValue()) : null;
|
||||
|
||||
final URIAuthority authority = request.getAuthority();
|
||||
final String requestUri = request.getRequestUri();
|
||||
|
||||
final boolean authenticated = authenticator.authenticate(authority, requestUri, challengeResponse);
|
||||
final Header expect = request.getFirstHeader(HttpHeaders.EXPECT);
|
||||
final boolean expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
|
||||
|
||||
if (authenticated) {
|
||||
if (expectContinue) {
|
||||
responseChannel.sendInformation(new BasicClassicHttpResponse(HttpStatus.SC_CONTINUE));
|
||||
}
|
||||
exchangeHandler.handleRequest(request, entityDetails, responseChannel, context);
|
||||
} else {
|
||||
final HttpResponse unauthorized = new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
|
||||
final String realm = authenticator.getRealm(authority, requestUri);
|
||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + realm + "\"");
|
||||
|
||||
customizeUnauthorizedResponse(unauthorized);
|
||||
|
||||
final AsyncResponseProducer responseProducer = new BasicResponseProducer(
|
||||
unauthorized,
|
||||
new BasicAsyncEntityProducer("Unauthorized", ContentType.TEXT_PLAIN));
|
||||
responseProducerRef.set(responseProducer);
|
||||
responseProducer.sendResponse(responseChannel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
|
||||
final AsyncResponseProducer responseProducer = responseProducerRef.get();
|
||||
if (responseProducer == null) {
|
||||
exchangeHandler.updateCapacity(capacityChannel);
|
||||
} else {
|
||||
capacityChannel.update(Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int consume(final ByteBuffer src) throws IOException {
|
||||
final AsyncResponseProducer responseProducer = responseProducerRef.get();
|
||||
if (responseProducer == null) {
|
||||
return exchangeHandler.consume(src);
|
||||
} else {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
|
||||
final AsyncResponseProducer responseProducer = responseProducerRef.get();
|
||||
if (responseProducer == null) {
|
||||
exchangeHandler.streamEnd(trailers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int available() {
|
||||
final AsyncResponseProducer responseProducer = responseProducerRef.get();
|
||||
if (responseProducer == null) {
|
||||
return exchangeHandler.available();
|
||||
} else {
|
||||
return responseProducer.available();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void produce(final DataStreamChannel channel) throws IOException {
|
||||
final AsyncResponseProducer responseProducer = responseProducerRef.get();
|
||||
if (responseProducer == null) {
|
||||
exchangeHandler.produce(channel);
|
||||
} else {
|
||||
responseProducer.produce(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void failed(final Exception cause) {
|
||||
try {
|
||||
exchangeHandler.failed(cause);
|
||||
final AsyncResponseProducer dataProducer = responseProducerRef.getAndSet(null);
|
||||
if (dataProducer != null) {
|
||||
dataProducer.failed(cause);
|
||||
}
|
||||
} finally {
|
||||
releaseResources();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void releaseResources() {
|
||||
exchangeHandler.releaseResources();
|
||||
final AsyncResponseProducer dataProducer = responseProducerRef.getAndSet(null);
|
||||
if (dataProducer != null) {
|
||||
dataProducer.releaseResources();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -27,29 +27,12 @@
|
|||
|
||||
package org.apache.hc.client5.testing.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.hc.core5.net.URIAuthority;
|
||||
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
public interface Authenticator {
|
||||
|
||||
public class RequestBasicAuth implements HttpRequestInterceptor {
|
||||
boolean authenticate(URIAuthority authority, String requestUri, String credentials);
|
||||
|
||||
private final BasicAuthTokenExtractor authTokenExtractor;
|
||||
|
||||
public RequestBasicAuth() {
|
||||
super();
|
||||
this.authTokenExtractor = new BasicAuthTokenExtractor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(
|
||||
final HttpRequest request,
|
||||
final EntityDetails entityDetails,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
context.setAttribute("creds", this.authTokenExtractor.extract(request));
|
||||
}
|
||||
String getRealm(URIAuthority authority, String requestUri);
|
||||
|
||||
}
|
|
@ -32,43 +32,30 @@ import java.nio.charset.StandardCharsets;
|
|||
import org.apache.commons.codec.BinaryDecoder;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.ProtocolException;
|
||||
|
||||
public class BasicAuthTokenExtractor {
|
||||
|
||||
public String extract(final HttpRequest request) throws HttpException {
|
||||
String auth = null;
|
||||
|
||||
final Header h = request.getFirstHeader(HttpHeaders.AUTHORIZATION);
|
||||
if (h != null) {
|
||||
final String s = h.getValue();
|
||||
if (s != null) {
|
||||
auth = s.trim();
|
||||
}
|
||||
}
|
||||
|
||||
if (auth != null) {
|
||||
final int i = auth.indexOf(' ');
|
||||
public String extract(final String challengeResponse) throws HttpException {
|
||||
if (challengeResponse != null) {
|
||||
final int i = challengeResponse.indexOf(' ');
|
||||
if (i == -1) {
|
||||
throw new ProtocolException("Invalid Authorization header: " + auth);
|
||||
throw new ProtocolException("Invalid challenge response: " + challengeResponse);
|
||||
}
|
||||
final String authscheme = auth.substring(0, i);
|
||||
final String authscheme = challengeResponse.substring(0, i);
|
||||
if (authscheme.equalsIgnoreCase("basic")) {
|
||||
final String s = auth.substring(i + 1).trim();
|
||||
final String s = challengeResponse.substring(i + 1).trim();
|
||||
try {
|
||||
final byte[] credsRaw = s.getBytes(StandardCharsets.US_ASCII);
|
||||
final BinaryDecoder codec = new Base64();
|
||||
auth = new String(codec.decode(credsRaw), StandardCharsets.US_ASCII);
|
||||
return new String(codec.decode(credsRaw), StandardCharsets.US_ASCII);
|
||||
} catch (final DecoderException ex) {
|
||||
throw new ProtocolException("Malformed BASIC credentials");
|
||||
}
|
||||
}
|
||||
}
|
||||
return auth;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* 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.classic;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||
import org.apache.hc.client5.testing.auth.BasicAuthTokenExtractor;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
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.StringEntity;
|
||||
import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.net.URIAuthority;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
|
||||
public class AuthenticatingDecorator implements HttpServerRequestHandler {
|
||||
|
||||
private final HttpServerRequestHandler requestHandler;
|
||||
private final Authenticator authenticator;
|
||||
private final BasicAuthTokenExtractor authTokenExtractor;
|
||||
|
||||
public AuthenticatingDecorator(final HttpServerRequestHandler requestHandler, final Authenticator authenticator) {
|
||||
this.requestHandler = Args.notNull(requestHandler, "Request handler");
|
||||
this.authenticator = Args.notNull(authenticator, "Authenticator");
|
||||
this.authTokenExtractor = new BasicAuthTokenExtractor();
|
||||
}
|
||||
|
||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ResponseTrigger responseTrigger,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final Header h = request.getFirstHeader(HttpHeaders.AUTHORIZATION);
|
||||
final String challengeResponse = h != null ? authTokenExtractor.extract(h.getValue()) : null;
|
||||
|
||||
final URIAuthority authority = request.getAuthority();
|
||||
final String requestUri = request.getRequestUri();
|
||||
|
||||
final boolean authenticated = authenticator.authenticate(authority, requestUri, challengeResponse);
|
||||
final Header expect = request.getFirstHeader(HttpHeaders.EXPECT);
|
||||
final boolean expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
|
||||
|
||||
if (authenticated) {
|
||||
if (expectContinue) {
|
||||
responseTrigger.sendInformation(new BasicClassicHttpResponse(HttpStatus.SC_CONTINUE));
|
||||
}
|
||||
requestHandler.handle(request, responseTrigger, context);
|
||||
} else {
|
||||
final ClassicHttpResponse unauthorized = new BasicClassicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
|
||||
final String realm = authenticator.getRealm(authority, requestUri);
|
||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + realm + "\"");
|
||||
customizeUnauthorizedResponse(unauthorized);
|
||||
if (unauthorized.getEntity() == null) {
|
||||
unauthorized.setEntity(new StringEntity("Unauthorized"));
|
||||
}
|
||||
if (expectContinue || request.getEntity() == null) {
|
||||
// Respond immediately
|
||||
responseTrigger.submitResponse(unauthorized);
|
||||
// Consume request body later
|
||||
EntityUtils.consume(request.getEntity());
|
||||
} else {
|
||||
// Consume request body first
|
||||
EntityUtils.consume(request.getEntity());
|
||||
// Respond later
|
||||
responseTrigger.submitResponse(unauthorized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -25,30 +25,30 @@
|
|||
*
|
||||
*/
|
||||
|
||||
package org.apache.hc.client5.testing.auth;
|
||||
package org.apache.hc.client5.testing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||
import org.apache.hc.core5.net.URIAuthority;
|
||||
|
||||
public class ResponseBasicUnauthorized implements HttpResponseInterceptor {
|
||||
public class BasicTestAuthenticator implements Authenticator {
|
||||
|
||||
private final String userToken;
|
||||
private final String realm;
|
||||
|
||||
public BasicTestAuthenticator(final String userToken, final String realm) {
|
||||
this.userToken = userToken;
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
||||
return Objects.equals(userToken, credentials);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(
|
||||
final HttpResponse response,
|
||||
final EntityDetails entityDetails,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
|
||||
if (!response.containsHeader(HttpHeaders.WWW_AUTHENTICATE)) {
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"test realm\"");
|
||||
}
|
||||
}
|
||||
public String getRealm(final URIAuthority authority, final String requestUri) {
|
||||
return realm;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,13 +28,16 @@
|
|||
package org.apache.hc.client5.testing.async;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
||||
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.H1Config;
|
||||
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.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.ListenerEndpoint;
|
||||
|
@ -72,16 +75,25 @@ public abstract class IntegrationTestBase extends LocalAsyncServerTestBase {
|
|||
|
||||
};
|
||||
|
||||
public HttpHost start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
|
||||
server.start(httpProcessor, h1Config);
|
||||
final ListenerEndpoint listener = server.listen(new InetSocketAddress(0));
|
||||
public HttpHost start(
|
||||
final HttpProcessor httpProcessor,
|
||||
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
|
||||
final H1Config h1Config) throws Exception {
|
||||
server.start(httpProcessor, exchangeHandlerDecorator, h1Config);
|
||||
final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
|
||||
httpclient = clientBuilder.build();
|
||||
httpclient.start();
|
||||
listener.waitFor();
|
||||
final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
|
||||
final ListenerEndpoint endpoint = endpointFuture.get();
|
||||
final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
|
||||
return new HttpHost("localhost", address.getPort(), scheme.name());
|
||||
}
|
||||
|
||||
public HttpHost start(
|
||||
final HttpProcessor httpProcessor,
|
||||
final H1Config h1Config) throws Exception {
|
||||
return start(httpProcessor, null, h1Config);
|
||||
}
|
||||
|
||||
public HttpHost start() throws Exception {
|
||||
return start(HttpProcessors.server(), H1Config.DEFAULT);
|
||||
}
|
||||
|
|
|
@ -763,8 +763,8 @@ public class TestAsyncRedirects extends IntegrationTestBase {
|
|||
});
|
||||
|
||||
secondServer.start();
|
||||
final ListenerEndpoint endpoint2 = secondServer.listen(new InetSocketAddress(0));
|
||||
endpoint2.waitFor();
|
||||
final Future<ListenerEndpoint> endpointFuture = secondServer.listen(new InetSocketAddress(0));
|
||||
final ListenerEndpoint endpoint2 = endpointFuture.get();
|
||||
|
||||
final InetSocketAddress address2 = (InetSocketAddress) endpoint2.getAddress();
|
||||
final HttpHost initialTarget = new HttpHost("localhost", address2.getPort(), scheme.name());
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
*/
|
||||
package org.apache.hc.client5.testing.async;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -52,18 +51,16 @@ import org.apache.hc.client5.http.impl.protocol.DefaultAuthenticationStrategy;
|
|||
import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.client5.testing.auth.RequestBasicAuth;
|
||||
import org.apache.hc.client5.testing.auth.ResponseBasicUnauthorized;
|
||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||
import org.apache.hc.core5.function.Decorator;
|
||||
import org.apache.hc.core5.function.Supplier;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.HeaderElements;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.URIScheme;
|
||||
import org.apache.hc.core5.http.config.H1Config;
|
||||
|
@ -71,13 +68,10 @@ import org.apache.hc.core5.http.config.Registry;
|
|||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.apache.hc.core5.http.message.BasicHttpResponse;
|
||||
import org.apache.hc.core5.http.nio.AsyncResponseProducer;
|
||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
|
||||
import org.apache.hc.core5.http.nio.support.BasicAsyncResponseProducer;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
||||
import org.apache.hc.core5.net.URIAuthority;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -100,43 +94,19 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public HttpHost start() throws Exception {
|
||||
return super.start(HttpProcessors.customServer(null)
|
||||
.add(new RequestBasicAuth())
|
||||
.add(new ResponseBasicUnauthorized())
|
||||
.build(),
|
||||
return super.start(
|
||||
HttpProcessors.server(),
|
||||
new Decorator<AsyncServerExchangeHandler>() {
|
||||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler requestHandler) {
|
||||
return new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm"));
|
||||
}
|
||||
|
||||
},
|
||||
H1Config.DEFAULT);
|
||||
}
|
||||
|
||||
static class AuthHandler extends AbstractSimpleServerExchangeHandler {
|
||||
|
||||
private final boolean keepAlive;
|
||||
|
||||
AuthHandler(final boolean keepAlive) {
|
||||
super();
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
AuthHandler() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SimpleHttpResponse handle(
|
||||
final SimpleHttpRequest request,
|
||||
final HttpCoreContext context) throws HttpException {
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
final SimpleHttpResponse response;
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
response = new SimpleHttpResponse(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
response = new SimpleHttpResponse(HttpStatus.SC_OK, "success", ContentType.TEXT_PLAIN);
|
||||
}
|
||||
response.setHeader(HttpHeaders.CONNECTION, this.keepAlive ? HeaderElements.KEEP_ALIVE : HeaderElements.CLOSE);
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestCredentialsProvider implements CredentialsStore {
|
||||
|
||||
private final Credentials creds;
|
||||
|
@ -173,7 +143,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -199,7 +169,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -226,7 +196,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -253,11 +223,27 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler(false);
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
final HttpHost target = start();
|
||||
final HttpHost target = start(
|
||||
HttpProcessors.server(),
|
||||
new Decorator<AsyncServerExchangeHandler>() {
|
||||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||
return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||
|
||||
@Override
|
||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
H1Config.DEFAULT);
|
||||
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
|
@ -280,23 +266,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler() {
|
||||
|
||||
@Override
|
||||
protected AsyncResponseProducer verify(
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws IOException, HttpException {
|
||||
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
return new BasicAsyncResponseProducer(new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED),
|
||||
new StringAsyncEntityProducer("Unauthorized"));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -321,23 +291,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler() {
|
||||
|
||||
@Override
|
||||
protected AsyncResponseProducer verify(
|
||||
final HttpRequest request,
|
||||
final HttpContext context) throws IOException, HttpException {
|
||||
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
return new BasicAsyncResponseProducer(new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED),
|
||||
new StringAsyncEntityProducer("Unauthorized"));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -365,7 +319,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -409,7 +363,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -422,7 +376,6 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||
Assert.assertEquals("success", response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -431,7 +384,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -452,7 +405,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -482,42 +435,18 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||
Assert.assertEquals("success", response.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReauthentication() throws Exception {
|
||||
final AtomicLong count = new AtomicLong(0);
|
||||
|
||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
||||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
|
||||
return new AbstractSimpleServerExchangeHandler() {
|
||||
|
||||
@Override
|
||||
protected SimpleHttpResponse handle(
|
||||
final SimpleHttpRequest request,
|
||||
final HttpCoreContext context) throws HttpException {
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
return new SimpleHttpResponse(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
// Make client re-authenticate on each fourth request
|
||||
if (count.incrementAndGet() % 4 == 0) {
|
||||
return new SimpleHttpResponse(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
return new SimpleHttpResponse(HttpStatus.SC_OK, "success", ContentType.TEXT_PLAIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
|
||||
|
@ -540,23 +469,43 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
.build();
|
||||
this.clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
|
||||
|
||||
final HttpHost target = start(HttpProcessors.customServer(null)
|
||||
.add(new RequestBasicAuth())
|
||||
.add(new HttpResponseInterceptor() {
|
||||
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) {
|
||||
if (this.count.incrementAndGet() % 4 != 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final HttpHost target = start(
|
||||
HttpProcessors.server(),
|
||||
new Decorator<AsyncServerExchangeHandler>() {
|
||||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||
return new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
|
||||
|
||||
@Override
|
||||
public void process(
|
||||
final HttpResponse response,
|
||||
final EntityDetails entityDetails,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||
}
|
||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||
}
|
||||
|
||||
})
|
||||
.build(),
|
||||
H1Config.DEFAULT);
|
||||
};
|
||||
}
|
||||
|
||||
}, H1Config.DEFAULT);
|
||||
|
||||
final RequestConfig config = RequestConfig.custom()
|
||||
.setTargetPreferredAuthSchemes(Arrays.asList("MyBasic"))
|
||||
|
@ -583,31 +532,27 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
|
||||
@Override
|
||||
public AsyncServerExchangeHandler get() {
|
||||
|
||||
return new AuthHandler();
|
||||
return new AsyncEchoHandler();
|
||||
}
|
||||
|
||||
});
|
||||
final HttpHost target = start(
|
||||
HttpProcessors.server(),
|
||||
new Decorator<AsyncServerExchangeHandler>() {
|
||||
|
||||
final HttpHost target = start(HttpProcessors.customServer(null)
|
||||
.add(new RequestBasicAuth())
|
||||
.add(new HttpResponseInterceptor() {
|
||||
@Override
|
||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
||||
return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||
|
||||
@Override
|
||||
public void process(
|
||||
final HttpResponse response,
|
||||
final EntityDetails entityDetails,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"test realm\"");
|
||||
}
|
||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
|
||||
}
|
||||
|
||||
})
|
||||
.build(),
|
||||
H1Config.DEFAULT);
|
||||
};
|
||||
}
|
||||
|
||||
}, H1Config.DEFAULT);
|
||||
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
|
@ -618,7 +563,6 @@ public class TestClientAuthentication extends IntegrationTestBase {
|
|||
final SimpleHttpResponse response = future.get();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||
Assert.assertEquals("success", response.getBody());
|
||||
final AuthScope authscope = credsProvider.getAuthScope();
|
||||
Assert.assertNotNull(authscope);
|
||||
Assert.assertEquals("test realm", authscope.getRealm());
|
||||
|
|
|
@ -168,10 +168,10 @@ public class TestHttpAsyncMinimal {
|
|||
} else {
|
||||
server.start(H1Config.DEFAULT);
|
||||
}
|
||||
final ListenerEndpoint listener = server.listen(new InetSocketAddress(0));
|
||||
final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
|
||||
httpclient.start();
|
||||
listener.waitFor();
|
||||
final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
|
||||
final ListenerEndpoint endpoint = endpointFuture.get();
|
||||
final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
|
||||
return new HttpHost("localhost", address.getPort(), scheme.name());
|
||||
}
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ import org.apache.hc.core5.http.ContentType;
|
|||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
|
@ -52,10 +52,9 @@ import org.junit.Test;
|
|||
|
||||
public class TestFluent extends LocalServerTestBase {
|
||||
|
||||
@Before @Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.serverBootstrap.registerHandler("/", new HttpRequestHandler() {
|
||||
this.server.registerHandler("/", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
|
@ -66,7 +65,7 @@ public class TestFluent extends LocalServerTestBase {
|
|||
}
|
||||
|
||||
});
|
||||
this.serverBootstrap.registerHandler("/echo", new HttpRequestHandler() {
|
||||
this.server.registerHandler("/echo", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
|
@ -155,7 +154,7 @@ public class TestFluent extends LocalServerTestBase {
|
|||
Request.Get(baseURL + "/").execute().returnContent();
|
||||
Request.Get(baseURL + "/").execute().returnResponse();
|
||||
Request.Get(baseURL + "/").execute().discardContent();
|
||||
Request.Get(baseURL + "/").execute().handleResponse(new ResponseHandler<Object>() {
|
||||
Request.Get(baseURL + "/").execute().handleResponse(new HttpClientResponseHandler<Object>() {
|
||||
|
||||
@Override
|
||||
public Object handleResponse(
|
||||
|
|
|
@ -27,35 +27,31 @@
|
|||
|
||||
package org.apache.hc.client5.testing.sync;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||
import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
|
||||
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.SocketConfig;
|
||||
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
||||
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
||||
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.apache.hc.core5.testing.classic.ClassicTestServer;
|
||||
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 {
|
||||
|
||||
protected final URIScheme scheme;
|
||||
|
||||
protected ServerBootstrap serverBootstrap;
|
||||
protected HttpServer server;
|
||||
protected PoolingHttpClientConnectionManager connManager;
|
||||
protected HttpClientBuilder clientBuilder;
|
||||
protected CloseableHttpClient httpclient;
|
||||
|
||||
public LocalServerTestBase(final URIScheme scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
@ -64,48 +60,81 @@ public abstract class LocalServerTestBase {
|
|||
this(URIScheme.HTTP);
|
||||
}
|
||||
|
||||
public String getSchemeName() {
|
||||
return this.scheme.name();
|
||||
}
|
||||
protected final URIScheme scheme;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
final SocketConfig socketConfig = SocketConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(15))
|
||||
.build();
|
||||
this.serverBootstrap = ServerBootstrap.bootstrap()
|
||||
.setSocketConfig(socketConfig)
|
||||
.registerHandler("/echo/*", new EchoHandler())
|
||||
.registerHandler("/random/*", new RandomHandler());
|
||||
if (this.scheme.equals(URIScheme.HTTPS)) {
|
||||
this.serverBootstrap.setSslContext(SSLTestContexts.createServerSSLContext());
|
||||
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(5, TimeUnit.SECONDS)
|
||||
.build());
|
||||
server.registerHandler("/echo/*", new EchoHandler());
|
||||
server.registerHandler("/random/*", new RandomHandler());
|
||||
}
|
||||
|
||||
this.connManager = new PoolingHttpClientConnectionManager();
|
||||
this.connManager.setDefaultSocketConfig(socketConfig);
|
||||
this.clientBuilder = HttpClientBuilder.create()
|
||||
.setConnectionManager(this.connManager);
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutDown() throws Exception {
|
||||
if (this.httpclient != null) {
|
||||
this.httpclient.close();
|
||||
@Override
|
||||
protected void after() {
|
||||
if (server != null) {
|
||||
try {
|
||||
server.shutdown(ShutdownType.IMMEDIATE);
|
||||
server = null;
|
||||
} catch (final Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.server != null) {
|
||||
this.server.shutdown(ShutdownType.IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpHost start() throws Exception {
|
||||
this.server = this.serverBootstrap.create();
|
||||
this.server.start();
|
||||
};
|
||||
|
||||
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(5, TimeUnit.SECONDS)
|
||||
.build());
|
||||
clientBuilder = HttpClientBuilder.create()
|
||||
.setConnectionManager(connManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void after() {
|
||||
if (httpclient != null) {
|
||||
try {
|
||||
httpclient.close();
|
||||
httpclient = null;
|
||||
} catch (final Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public HttpHost start(
|
||||
final HttpProcessor httpProcessor,
|
||||
final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
|
||||
this.server.start(httpProcessor, handlerDecorator);
|
||||
|
||||
if (this.httpclient == null) {
|
||||
this.httpclient = this.clientBuilder.build();
|
||||
}
|
||||
|
||||
return new HttpHost("localhost", this.server.getLocalPort(), this.scheme.name());
|
||||
return new HttpHost("localhost", this.server.getPort(), this.scheme.name());
|
||||
}
|
||||
|
||||
public HttpHost start() throws Exception {
|
||||
return start(null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
@ -37,6 +38,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
import org.apache.hc.client5.http.auth.AuthCache;
|
||||
import org.apache.hc.client5.http.auth.AuthChallenge;
|
||||
import org.apache.hc.client5.http.auth.AuthScheme;
|
||||
import org.apache.hc.client5.http.auth.AuthSchemeProvider;
|
||||
import org.apache.hc.client5.http.auth.AuthScope;
|
||||
import org.apache.hc.client5.http.auth.ChallengeType;
|
||||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
|
@ -45,17 +47,21 @@ import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
|||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
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.BasicSchemeFactory;
|
||||
import org.apache.hc.client5.http.impl.protocol.DefaultAuthenticationStrategy;
|
||||
import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
|
||||
import org.apache.hc.client5.http.impl.sync.CloseableHttpResponse;
|
||||
import org.apache.hc.client5.http.protocol.ClientProtocolException;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.protocol.NonRepeatableRequestException;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpPost;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpPut;
|
||||
import org.apache.hc.client5.testing.auth.BasicAuthTokenExtractor;
|
||||
import org.apache.hc.client5.testing.auth.RequestBasicAuth;
|
||||
import org.apache.hc.client5.testing.auth.ResponseBasicUnauthorized;
|
||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||
import org.apache.hc.client5.testing.classic.AuthenticatingDecorator;
|
||||
import org.apache.hc.client5.testing.classic.EchoHandler;
|
||||
import org.apache.hc.core5.function.Decorator;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.EndpointDetails;
|
||||
|
@ -65,18 +71,19 @@ import org.apache.hc.core5.http.HttpException;
|
|||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.config.Registry;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
||||
import org.apache.hc.core5.http.io.HttpExpectationVerifier;
|
||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||
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.InputStreamEntity;
|
||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||
import org.apache.hc.core5.net.URIAuthority;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -84,56 +91,19 @@ import org.junit.Test;
|
|||
*/
|
||||
public class TestClientAuthentication extends LocalServerTestBase {
|
||||
|
||||
@Before @Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new RequestBasicAuth())
|
||||
.add(new ResponseBasicUnauthorized()).build();
|
||||
this.serverBootstrap.setHttpProcessor(httpproc);
|
||||
public HttpHost start(final Authenticator authenticator) throws IOException {
|
||||
return super.start(null, new Decorator<HttpServerRequestHandler>() {
|
||||
|
||||
@Override
|
||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
||||
return new AuthenticatingDecorator(requestHandler, authenticator);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
static class AuthHandler implements HttpRequestHandler {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
|
||||
response.setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class AuthExpectationVerifier implements HttpExpectationVerifier {
|
||||
|
||||
private final BasicAuthTokenExtractor authTokenExtractor;
|
||||
|
||||
public AuthExpectationVerifier() {
|
||||
super();
|
||||
this.authTokenExtractor = new BasicAuthTokenExtractor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verify(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException {
|
||||
final String creds = this.authTokenExtractor.extract(request);
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_CONTINUE);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpHost start() throws IOException {
|
||||
return start(new BasicTestAuthenticator("test:test", "test realm"));
|
||||
}
|
||||
|
||||
static class TestCredentialsProvider implements CredentialsProvider {
|
||||
|
@ -160,8 +130,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicAuthenticationNoCreds() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
@ -181,8 +150,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicAuthenticationFailure() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
@ -203,8 +171,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicAuthenticationSuccess() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpGet httpget = new HttpGet("/");
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
|
@ -225,13 +192,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new RequestBasicAuth())
|
||||
.add(new ResponseBasicUnauthorized()).build();
|
||||
this.serverBootstrap.setHttpProcessor(httpproc)
|
||||
.setExpectationVerifier(new AuthExpectationVerifier())
|
||||
.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
|
||||
final RequestConfig config = RequestConfig.custom()
|
||||
|
@ -256,11 +217,10 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test(expected=ClientProtocolException.class)
|
||||
public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
|
||||
final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build();
|
||||
final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(false).build();
|
||||
final HttpPut httpput = new HttpPut("/");
|
||||
httpput.setConfig(config);
|
||||
httpput.setEntity(new InputStreamEntity(
|
||||
|
@ -286,8 +246,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpPost httppost = new HttpPost("/");
|
||||
|
@ -310,8 +269,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test(expected=ClientProtocolException.class)
|
||||
public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpPost httppost = new HttpPost("/");
|
||||
|
@ -362,8 +320,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final TestTargetAuthenticationStrategy authStrategy = new TestTargetAuthenticationStrategy();
|
||||
this.clientBuilder.setTargetAuthenticationStrategy(authStrategy);
|
||||
|
||||
|
@ -392,43 +349,34 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
Assert.assertEquals(1, authStrategy.getCount());
|
||||
}
|
||||
|
||||
static class RealmAuthHandler implements HttpRequestHandler {
|
||||
|
||||
final String realm;
|
||||
final String realmCreds;
|
||||
|
||||
public RealmAuthHandler(final String realm, final String realmCreds) {
|
||||
this.realm = realm;
|
||||
this.realmCreds = realmCreds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String givenCreds = (String) context.getAttribute("creds");
|
||||
if (givenCreds == null || !givenCreds.equals(this.realmCreds)) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + this.realm + "\"");
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
|
||||
response.setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationCredentialsCachingReauthenticationOnDifferentRealm() throws Exception {
|
||||
this.serverBootstrap.registerHandler("/this", new RealmAuthHandler("this realm", "test:this"));
|
||||
this.serverBootstrap.registerHandler("/that", new RealmAuthHandler("that realm", "test:that"));
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start(new Authenticator() {
|
||||
|
||||
this.server = this.serverBootstrap.create();
|
||||
this.server.start();
|
||||
@Override
|
||||
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
||||
if (requestUri.equals("/this")) {
|
||||
return "test:this".equals(credentials);
|
||||
} else if (requestUri.equals("/that")) {
|
||||
return "test:that".equals(credentials);
|
||||
} else {
|
||||
return "test:test".equals(credentials);
|
||||
}
|
||||
}
|
||||
|
||||
final HttpHost target = new HttpHost("localhost", this.server.getLocalPort(), this.scheme.name());
|
||||
@Override
|
||||
public String getRealm(final URIAuthority authority, final String requestUri) {
|
||||
if (requestUri.equals("/this")) {
|
||||
return "this realm";
|
||||
} else if (requestUri.equals("/that")) {
|
||||
return "that realm";
|
||||
} else {
|
||||
return "test realm";
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final TestTargetAuthenticationStrategy authStrategy = new TestTargetAuthenticationStrategy();
|
||||
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||
|
@ -472,8 +420,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testAuthenticationUserinfoInRequestSuccess() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
final HttpGet httpget = new HttpGet("http://test:test@" + target.toHostString() + "/");
|
||||
|
||||
|
@ -487,8 +434,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testAuthenticationUserinfoInRequestFailure() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final HttpHost target = start();
|
||||
final HttpGet httpget = new HttpGet("http://test:all-wrong@" + target.toHostString() + "/");
|
||||
|
||||
|
@ -500,36 +446,39 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
EntityUtils.consume(entity);
|
||||
}
|
||||
|
||||
private static class RedirectHandler implements HttpRequestHandler {
|
||||
|
||||
public RedirectHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
|
||||
final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
|
||||
final String localhost = socketAddress.getHostName();
|
||||
final int port = socketAddress.getPort();
|
||||
response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
|
||||
response.addHeader(new BasicHeader("Location",
|
||||
"http://test:test@" + localhost + ":" + port + "/"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
this.serverBootstrap.registerHandler("/thatway", new RedirectHandler());
|
||||
this.server.registerHandler("/*", new EchoHandler());
|
||||
this.server.registerHandler("/thatway", new HttpRequestHandler() {
|
||||
|
||||
final HttpHost target = start();
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
|
||||
final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
|
||||
final String localhost = socketAddress.getHostName();
|
||||
final int port = socketAddress.getPort();
|
||||
response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
|
||||
response.addHeader(new BasicHeader("Location", "http://test:test@" + localhost + ":" + port + "/secure"));
|
||||
}
|
||||
|
||||
final HttpGet httpget = new HttpGet("http://" + target.toHostString() + "/thatway");
|
||||
});
|
||||
|
||||
final HttpHost target = start(new BasicTestAuthenticator("test:test", "test realm") {
|
||||
|
||||
@Override
|
||||
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
||||
if (requestUri.equals("/secure") || requestUri.startsWith("/secure/")) {
|
||||
return super.authenticate(authority, requestUri, credentials);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final HttpGet httpget = new HttpGet("/thatway");
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
|
||||
|
@ -539,29 +488,19 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
EntityUtils.consume(entity);
|
||||
}
|
||||
|
||||
static class CountingAuthHandler implements HttpRequestHandler {
|
||||
static class CountingAuthenticator extends BasicTestAuthenticator {
|
||||
|
||||
private final AtomicLong count;
|
||||
|
||||
public CountingAuthHandler() {
|
||||
super();
|
||||
public CountingAuthenticator(final String userToken, final String realm) {
|
||||
super(userToken, realm);
|
||||
this.count = new AtomicLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
|
||||
this.count.incrementAndGet();
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
|
||||
response.setEntity(entity);
|
||||
}
|
||||
return super.authenticate(authority, requestUri, credentials);
|
||||
}
|
||||
|
||||
public long getCount() {
|
||||
|
@ -572,10 +511,9 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testPreemptiveAuthentication() throws Exception {
|
||||
final CountingAuthHandler requestHandler = new CountingAuthHandler();
|
||||
this.serverBootstrap.registerHandler("*", requestHandler);
|
||||
|
||||
final HttpHost target = start();
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final CountingAuthenticator countingAuthenticator = new CountingAuthenticator("test:test", "test realm");
|
||||
final HttpHost target = start(countingAuthenticator);
|
||||
|
||||
final BasicScheme basicScheme = new BasicScheme();
|
||||
basicScheme.initPreemptive(new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
|
@ -591,15 +529,15 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
Assert.assertNotNull(entity1);
|
||||
EntityUtils.consume(entity1);
|
||||
|
||||
Assert.assertEquals(1, requestHandler.getCount());
|
||||
Assert.assertEquals(1, countingAuthenticator.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreemptiveAuthenticationFailure() throws Exception {
|
||||
final CountingAuthHandler requestHandler = new CountingAuthHandler();
|
||||
this.serverBootstrap.registerHandler("*", requestHandler);
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
final CountingAuthenticator countingAuthenticator = new CountingAuthenticator("test:test", "test realm");
|
||||
|
||||
final HttpHost target = start();
|
||||
final HttpHost target = start(countingAuthenticator);
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
final AuthCache authCache = new BasicAuthCache();
|
||||
|
@ -617,7 +555,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
Assert.assertNotNull(entity1);
|
||||
EntityUtils.consume(entity1);
|
||||
|
||||
Assert.assertEquals(1, requestHandler.getCount());
|
||||
Assert.assertEquals(1, countingAuthenticator.getCount());
|
||||
}
|
||||
|
||||
static class ProxyAuthHandler implements HttpRequestHandler {
|
||||
|
@ -641,9 +579,9 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testAuthenticationTargetAsProxy() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new ProxyAuthHandler());
|
||||
this.server.registerHandler("*", new ProxyAuthHandler());
|
||||
|
||||
final HttpHost target = start();
|
||||
final HttpHost target = super.start();
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null);
|
||||
|
@ -657,31 +595,27 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
EntityUtils.consume(entity);
|
||||
}
|
||||
|
||||
static class ClosingAuthHandler implements HttpRequestHandler {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
|
||||
response.setEntity(entity);
|
||||
response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new ClosingAuthHandler());
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
|
||||
final HttpHost target = start();
|
||||
final HttpHost target = start(
|
||||
HttpProcessors.server(),
|
||||
new Decorator<HttpServerRequestHandler>() {
|
||||
|
||||
@Override
|
||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
||||
return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||
|
||||
@Override
|
||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||
|
@ -698,4 +632,128 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReauthentication() throws Exception {
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
|
||||
final BasicSchemeFactory myBasicAuthSchemeFactory = new BasicSchemeFactory() {
|
||||
|
||||
@Override
|
||||
public AuthScheme create(final HttpContext context) {
|
||||
return new BasicScheme() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "MyBasic";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
|
||||
final RequestConfig config = RequestConfig.custom()
|
||||
.setTargetPreferredAuthSchemes(Arrays.asList("MyBasic"))
|
||||
.build();
|
||||
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
.register("MyBasic", myBasicAuthSchemeFactory)
|
||||
.build();
|
||||
this.httpclient = this.clientBuilder
|
||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||
.setDefaultCredentialsProvider(credsProvider)
|
||||
.build();
|
||||
|
||||
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) {
|
||||
if (this.count.incrementAndGet() % 4 != 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final HttpHost target = start(
|
||||
HttpProcessors.server(),
|
||||
new Decorator<HttpServerRequestHandler>() {
|
||||
|
||||
@Override
|
||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
||||
return new AuthenticatingDecorator(requestHandler, authenticator) {
|
||||
|
||||
@Override
|
||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
final HttpGet httpget = new HttpGet("/");
|
||||
httpget.setConfig(config);
|
||||
try (final CloseableHttpResponse response = this.httpclient.execute(target, httpget, context)) {
|
||||
final HttpEntity entity = response.getEntity();
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||
Assert.assertNotNull(entity);
|
||||
EntityUtils.consume(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationFallback() throws Exception {
|
||||
this.server.registerHandler("*", new EchoHandler());
|
||||
|
||||
final HttpHost target = start(
|
||||
HttpProcessors.server(),
|
||||
new Decorator<HttpServerRequestHandler>() {
|
||||
|
||||
@Override
|
||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
||||
return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||
|
||||
@Override
|
||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
context.setCredentialsProvider(credsProvider);
|
||||
final HttpGet httpget = new HttpGet("/");
|
||||
|
||||
final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
|
||||
final HttpEntity entity = response.getEntity();
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||
Assert.assertNotNull(entity);
|
||||
EntityUtils.consume(entity);
|
||||
final AuthScope authscope = credsProvider.getAuthScope();
|
||||
Assert.assertNotNull(authscope);
|
||||
Assert.assertEquals("test realm", authscope.getRealm());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNTLMAuthenticationFailure() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new NtlmResponseHandler());
|
||||
this.server.registerHandler("*", new NtlmResponseHandler());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -112,7 +112,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNTLMv1Type2Message() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
||||
this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
||||
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
||||
"AGUAcgB2AGUAcgA="));
|
||||
final HttpHost target = start();
|
||||
|
@ -136,7 +136,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNTLMv2Type2Message() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
||||
this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
|
||||
"AADAAMADgAAAAzgoriASNFZ4mrze8AAAAAAAAAACQAJABEAAAABgBwFwAAAA9T" +
|
||||
"AGUAcgB2AGUAcgACAAwARABvAG0AYQBpAG4AAQAMAFMAZQByAHYAZQByAAAAAAA="));
|
||||
final HttpHost target = start();
|
||||
|
@ -179,7 +179,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
||||
this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
||||
"AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
||||
"AGUAcgB2AGUAcgA="));
|
||||
|
||||
|
@ -200,7 +200,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
||||
this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
|
||||
"AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
|
||||
"ZXJ2ZXI="));
|
||||
|
||||
|
|
|
@ -1,148 +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 java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.apache.hc.client5.http.auth.AuthScope;
|
||||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.client5.testing.auth.RequestBasicAuth;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
||||
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.StringEntity;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestClientAuthenticationFallBack extends LocalServerTestBase {
|
||||
|
||||
public class ResponseBasicUnauthorized implements HttpResponseInterceptor {
|
||||
|
||||
@Override
|
||||
public void process(
|
||||
final HttpResponse response,
|
||||
final EntityDetails entityDetails,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"test realm\"");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Before @Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new RequestBasicAuth())
|
||||
.add(new ResponseBasicUnauthorized()).build();
|
||||
this.serverBootstrap.setHttpProcessor(httpproc);
|
||||
}
|
||||
|
||||
static class AuthHandler implements HttpRequestHandler {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
|
||||
response.setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestCredentialsProvider implements CredentialsProvider {
|
||||
|
||||
private final Credentials creds;
|
||||
private AuthScope authscope;
|
||||
|
||||
TestCredentialsProvider(final Credentials creds) {
|
||||
super();
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Credentials getCredentials(final AuthScope authscope, final HttpContext context) {
|
||||
this.authscope = authscope;
|
||||
return this.creds;
|
||||
}
|
||||
|
||||
public AuthScope getAuthScope() {
|
||||
return this.authscope;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicAuthenticationSuccess() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
context.setCredentialsProvider(credsProvider);
|
||||
final HttpGet httpget = new HttpGet("/");
|
||||
|
||||
final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
|
||||
final HttpEntity entity = response.getEntity();
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||
Assert.assertNotNull(entity);
|
||||
EntityUtils.consume(entity);
|
||||
final AuthScope authscope = credsProvider.getAuthScope();
|
||||
Assert.assertNotNull(authscope);
|
||||
Assert.assertEquals("test realm", authscope.getRealm());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,188 +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 java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.apache.hc.client5.http.auth.AuthScheme;
|
||||
import org.apache.hc.client5.http.auth.AuthSchemeProvider;
|
||||
import org.apache.hc.client5.http.auth.AuthScope;
|
||||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
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.sync.CloseableHttpResponse;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.client5.testing.auth.RequestBasicAuth;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.config.Registry;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestClientReauthentication extends LocalServerTestBase {
|
||||
|
||||
public class ResponseBasicUnauthorized implements HttpResponseInterceptor {
|
||||
|
||||
@Override
|
||||
public void process(
|
||||
final HttpResponse response,
|
||||
final EntityDetails entityDetails,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
|
||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Before @Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new RequestBasicAuth())
|
||||
.add(new ResponseBasicUnauthorized()).build();
|
||||
this.serverBootstrap.setHttpProcessor(httpproc);
|
||||
}
|
||||
|
||||
static class AuthHandler implements HttpRequestHandler {
|
||||
|
||||
private final AtomicLong count = new AtomicLong(0);
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String creds = (String) context.getAttribute("creds");
|
||||
if (creds == null || !creds.equals("test:test")) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
// Make client re-authenticate on each fourth request
|
||||
if (this.count.incrementAndGet() % 4 == 0) {
|
||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
|
||||
response.setEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestCredentialsProvider implements CredentialsProvider {
|
||||
|
||||
private final Credentials creds;
|
||||
private AuthScope authscope;
|
||||
|
||||
TestCredentialsProvider(final Credentials creds) {
|
||||
super();
|
||||
this.creds = creds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Credentials getCredentials(final AuthScope authscope, final HttpContext context) {
|
||||
this.authscope = authscope;
|
||||
return this.creds;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicAuthenticationSuccess() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new AuthHandler());
|
||||
|
||||
final BasicSchemeFactory myBasicAuthSchemeFactory = new BasicSchemeFactory() {
|
||||
|
||||
@Override
|
||||
public AuthScheme create(final HttpContext context) {
|
||||
return new BasicScheme() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "MyBasic";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||
|
||||
final RequestConfig config = RequestConfig.custom()
|
||||
.setTargetPreferredAuthSchemes(Arrays.asList("MyBasic"))
|
||||
.build();
|
||||
final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
|
||||
.register("MyBasic", myBasicAuthSchemeFactory)
|
||||
.build();
|
||||
this.httpclient = this.clientBuilder
|
||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry)
|
||||
.setDefaultCredentialsProvider(credsProvider)
|
||||
.build();
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
final HttpGet httpget = new HttpGet("/");
|
||||
httpget.setConfig(config);
|
||||
try (final CloseableHttpResponse response = this.httpclient.execute(target, httpget, context)) {
|
||||
final HttpEntity entity = response.getEntity();
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
|
||||
Assert.assertNotNull(entity);
|
||||
EntityUtils.consume(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -110,7 +110,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testAutoGeneratedHeaders() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
|
||||
final HttpRequestInterceptor interceptor = new HttpRequestInterceptor() {
|
||||
|
||||
|
@ -163,7 +163,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
|||
|
||||
@Test(expected=ClientProtocolException.class)
|
||||
public void testNonRepeatableEntity() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
|
||||
final HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {
|
||||
|
||||
|
@ -206,7 +206,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNonCompliantURI() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -224,7 +224,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testRelativeRequestURIWithFragment() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -241,7 +241,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testAbsoluteRequestURIWithFragment() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
|
|
@ -1,229 +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.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.apache.hc.client5.http.HttpRoute;
|
||||
import org.apache.hc.client5.http.io.ConnectionEndpoint;
|
||||
import org.apache.hc.client5.http.io.LeaseRequest;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.core5.function.Supplier;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.CharCodingConfig;
|
||||
import org.apache.hc.core5.http.config.H1Config;
|
||||
import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
|
||||
import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnectionFactory;
|
||||
import org.apache.hc.core5.http.io.SessionOutputBuffer;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestConnectionAutoRelease extends LocalServerTestBase {
|
||||
|
||||
@Test
|
||||
public void testReleaseOnEntityConsumeContent() throws Exception {
|
||||
this.connManager.setDefaultMaxPerRoute(1);
|
||||
this.connManager.setMaxTotal(1);
|
||||
|
||||
// Zero connections in the pool
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
final HttpHost target = start();
|
||||
// Get some random data
|
||||
final HttpGet httpget = new HttpGet("/random/20000");
|
||||
final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
|
||||
|
||||
final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
|
||||
try {
|
||||
connreq1.get(250, TimeUnit.MILLISECONDS);
|
||||
Assert.fail("ConnectionPoolTimeoutException should have been thrown");
|
||||
} catch (final TimeoutException expected) {
|
||||
}
|
||||
|
||||
final HttpEntity e = response.getEntity();
|
||||
Assert.assertNotNull(e);
|
||||
EntityUtils.consume(e);
|
||||
|
||||
// Expect one connection in the pool
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
// Make sure one connection is available
|
||||
final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
|
||||
final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
|
||||
|
||||
this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseOnEntityWriteTo() throws Exception {
|
||||
this.connManager.setDefaultMaxPerRoute(1);
|
||||
this.connManager.setMaxTotal(1);
|
||||
|
||||
// Zero connections in the pool
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
final HttpHost target = start();
|
||||
// Get some random data
|
||||
final HttpGet httpget = new HttpGet("/random/20000");
|
||||
final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
|
||||
|
||||
final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
|
||||
try {
|
||||
connreq1.get(250, TimeUnit.MILLISECONDS);
|
||||
Assert.fail("ConnectionPoolTimeoutException should have been thrown");
|
||||
} catch (final TimeoutException expected) {
|
||||
}
|
||||
|
||||
final HttpEntity e = response.getEntity();
|
||||
Assert.assertNotNull(e);
|
||||
final ByteArrayOutputStream outsteam = new ByteArrayOutputStream();
|
||||
e.writeTo(outsteam);
|
||||
|
||||
// Expect one connection in the pool
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
// Make sure one connection is available
|
||||
final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
|
||||
final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
|
||||
|
||||
this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseOnAbort() throws Exception {
|
||||
this.connManager.setDefaultMaxPerRoute(1);
|
||||
this.connManager.setMaxTotal(1);
|
||||
|
||||
// Zero connections in the pool
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
// Get some random data
|
||||
final HttpGet httpget = new HttpGet("/random/20000");
|
||||
final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
|
||||
|
||||
final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
|
||||
try {
|
||||
connreq1.get(250, TimeUnit.MILLISECONDS);
|
||||
Assert.fail("ConnectionPoolTimeoutException should have been thrown");
|
||||
} catch (final TimeoutException expected) {
|
||||
}
|
||||
|
||||
final HttpEntity e = response.getEntity();
|
||||
Assert.assertNotNull(e);
|
||||
httpget.abort();
|
||||
|
||||
// Expect zero connections in the pool
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
// Make sure one connection is available
|
||||
final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
|
||||
final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
|
||||
|
||||
this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseOnIOException() throws Exception {
|
||||
serverBootstrap.setConnectionFactory(new DefaultBHttpServerConnectionFactory(null, H1Config.DEFAULT, CharCodingConfig.DEFAULT) {
|
||||
|
||||
@Override
|
||||
public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException {
|
||||
final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(null, H1Config.DEFAULT) {
|
||||
|
||||
@Override
|
||||
protected OutputStream createContentOutputStream(
|
||||
final long len,
|
||||
final SessionOutputBuffer buffer,
|
||||
final OutputStream outputStream,
|
||||
final Supplier<List<? extends Header>> trailers) {
|
||||
try {
|
||||
buffer.flush(outputStream);
|
||||
outputStream.close();
|
||||
} catch (final IOException ignore) {
|
||||
}
|
||||
return super.createContentOutputStream(len, buffer, outputStream, trailers);
|
||||
}
|
||||
};
|
||||
conn.bind(socket);
|
||||
return conn;
|
||||
}
|
||||
});
|
||||
|
||||
this.connManager.setDefaultMaxPerRoute(1);
|
||||
this.connManager.setMaxTotal(1);
|
||||
|
||||
// Zero connections in the pool
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
// Get some random data
|
||||
final HttpGet httpget = new HttpGet("/random/1024");
|
||||
final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
|
||||
|
||||
final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
|
||||
try {
|
||||
connreq1.get(250, TimeUnit.MILLISECONDS);
|
||||
Assert.fail("ConnectionPoolTimeoutException should have been thrown");
|
||||
} catch (final TimeoutException expected) {
|
||||
}
|
||||
|
||||
final HttpEntity e = response.getEntity();
|
||||
Assert.assertNotNull(e);
|
||||
// Read the content
|
||||
try {
|
||||
EntityUtils.toByteArray(e);
|
||||
Assert.fail("IOException should have been thrown");
|
||||
} catch (final IOException expected) {
|
||||
|
||||
}
|
||||
|
||||
// Expect zero connections in the pool
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
|
||||
// Make sure one connection is available
|
||||
final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
|
||||
final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
|
||||
|
||||
this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,6 @@ import java.net.URI;
|
|||
|
||||
import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.client5.testing.classic.RandomHandler;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
|
@ -53,11 +52,6 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testReuseOfPersistentConnections() throws Exception {
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null).build();
|
||||
|
||||
this.serverBootstrap.setHttpProcessor(httpproc)
|
||||
.registerHandler("/random/*", new RandomHandler());
|
||||
|
||||
this.connManager.setMaxTotal(5);
|
||||
this.connManager.setDefaultMaxPerRoute(5);
|
||||
|
||||
|
@ -101,16 +95,13 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testReuseOfClosedConnections() throws Exception {
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new AlwaysCloseConn()).build();
|
||||
|
||||
this.serverBootstrap.setHttpProcessor(httpproc)
|
||||
.registerHandler("/random/*", new RandomHandler());
|
||||
|
||||
this.connManager.setMaxTotal(5);
|
||||
this.connManager.setDefaultMaxPerRoute(5);
|
||||
|
||||
final HttpHost target = start();
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new AlwaysCloseConn())
|
||||
.build();
|
||||
final HttpHost target = start(httpproc, null);
|
||||
|
||||
final WorkerThread[] workers = new WorkerThread[10];
|
||||
for (int i = 0; i < workers.length; i++) {
|
||||
|
@ -138,11 +129,6 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testReuseOfAbortedConnections() throws Exception {
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null).build();
|
||||
|
||||
this.serverBootstrap.setHttpProcessor(httpproc)
|
||||
.registerHandler("/random/*", new RandomHandler());
|
||||
|
||||
this.connManager.setMaxTotal(5);
|
||||
this.connManager.setDefaultMaxPerRoute(5);
|
||||
|
||||
|
@ -174,16 +160,13 @@ public class TestConnectionReuse extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testKeepAliveHeaderRespected() throws Exception {
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new ResponseKeepAlive()).build();
|
||||
|
||||
this.serverBootstrap.setHttpProcessor(httpproc)
|
||||
.registerHandler("/random/*", new RandomHandler());
|
||||
|
||||
this.connManager.setMaxTotal(1);
|
||||
this.connManager.setDefaultMaxPerRoute(1);
|
||||
|
||||
final HttpHost target = start();
|
||||
final HttpProcessor httpproc = HttpProcessors.customServer(null)
|
||||
.add(new ResponseKeepAlive())
|
||||
.build();
|
||||
final HttpHost target = start(httpproc, null);
|
||||
|
||||
ClassicHttpResponse response = this.httpclient.execute(target, new HttpGet("/random/2000"));
|
||||
EntityUtils.consume(response.getEntity());
|
||||
|
|
|
@ -41,7 +41,7 @@ import java.util.concurrent.Executors;
|
|||
import java.util.zip.Deflater;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.apache.hc.client5.http.impl.sync.BasicResponseHandler;
|
||||
import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
|
||||
import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
|
@ -75,7 +75,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
*/
|
||||
@Test
|
||||
public void testResponseWithNoContent() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new HttpRequestHandler() {
|
||||
this.server.registerHandler("*", new HttpRequestHandler() {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
|
@ -107,7 +107,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void testDeflateSupportForServerReturningRfc1950Stream() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -127,7 +127,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void testDeflateSupportForServerReturningRfc1951Stream() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -146,7 +146,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void testGzipSupport() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -166,7 +166,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void testThreadSafetyOfContentCodings() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
|
||||
/*
|
||||
* Create a load of workers which will access the resource. Half will use the default
|
||||
|
@ -212,7 +212,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void testHttpEntityWriteToForGzip() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -229,7 +229,7 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void testHttpEntityWriteToForDeflate() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -246,12 +246,12 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void gzipResponsesWorkWithBasicResponseHandler() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpGet request = new HttpGet("/some-resource");
|
||||
final String response = this.httpclient.execute(target, request, new BasicResponseHandler());
|
||||
final String response = this.httpclient.execute(target, request, new BasicHttpClientResponseHandler());
|
||||
Assert.assertEquals("The entity text is correctly transported", entityText, response);
|
||||
}
|
||||
|
||||
|
@ -259,12 +259,12 @@ public class TestContentCodings extends LocalServerTestBase {
|
|||
public void deflateResponsesWorkWithBasicResponseHandler() throws Exception {
|
||||
final String entityText = "Hello, this is some plain text coming back.";
|
||||
|
||||
this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
||||
this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpGet request = new HttpGet("/some-resource");
|
||||
final String response = this.httpclient.execute(target, request, new BasicResponseHandler());
|
||||
final String response = this.httpclient.execute(target, request, new BasicHttpClientResponseHandler());
|
||||
Assert.assertEquals("The entity text is correctly transported", entityText, response);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testCookieMatchingWithVirtualHosts() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new HttpRequestHandler() {
|
||||
this.server.registerHandlerVirtual("app.mydomain.fr", "*", new HttpRequestHandler() {
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
|
|
|
@ -29,7 +29,9 @@ package org.apache.hc.client5.testing.sync;
|
|||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.sync.CloseableHttpResponse;
|
||||
import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
|
||||
import org.apache.hc.client5.http.sync.methods.HttpGet;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
|
@ -37,6 +39,8 @@ import org.apache.hc.core5.http.HttpException;
|
|||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.config.H1Config;
|
||||
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
||||
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
||||
import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
|
||||
import org.apache.hc.core5.http.io.HttpConnectionFactory;
|
||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||
|
@ -46,7 +50,7 @@ import org.apache.hc.core5.http.protocol.HttpContext;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestMalformedServerResponse extends LocalServerTestBase {
|
||||
public class TestMalformedServerResponse {
|
||||
|
||||
static class BrokenServerConnection extends DefaultBHttpServerConnection {
|
||||
|
||||
|
@ -85,41 +89,46 @@ public class TestMalformedServerResponse extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNoContentResponseWithGarbage() throws Exception {
|
||||
this.serverBootstrap.setConnectionFactory(new BrokenServerConnectionFactory());
|
||||
this.serverBootstrap.registerHandler("/nostuff", new HttpRequestHandler() {
|
||||
try (final HttpServer server = ServerBootstrap.bootstrap()
|
||||
.setConnectionFactory(new BrokenServerConnectionFactory())
|
||||
.register("/nostuff", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
response.setCode(HttpStatus.SC_NO_CONTENT);
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
response.setCode(HttpStatus.SC_NO_CONTENT);
|
||||
}
|
||||
|
||||
})
|
||||
.register("/stuff", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
response.setEntity(new StringEntity("Some important stuff"));
|
||||
}
|
||||
|
||||
})
|
||||
.create()) {
|
||||
server.start();
|
||||
final HttpHost target = new HttpHost("localhost", server.getLocalPort());
|
||||
try (final CloseableHttpClient httpclient = HttpClientBuilder.create().build()) {
|
||||
final HttpGet get1 = new HttpGet("/nostuff");
|
||||
try (final CloseableHttpResponse response1 = httpclient.execute(target, get1)) {
|
||||
Assert.assertEquals(HttpStatus.SC_NO_CONTENT, response1.getCode());
|
||||
EntityUtils.consume(response1.getEntity());
|
||||
}
|
||||
final HttpGet get2 = new HttpGet("/stuff");
|
||||
try (final CloseableHttpResponse response2 = httpclient.execute(target, get2)) {
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
||||
EntityUtils.consume(response2.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
this.serverBootstrap.registerHandler("/stuff", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
response.setEntity(new StringEntity("Some important stuff"));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
final HttpHost target = start();
|
||||
final HttpGet get1 = new HttpGet("/nostuff");
|
||||
try (CloseableHttpResponse response1 = this.httpclient.execute(target, get1)) {
|
||||
Assert.assertEquals(HttpStatus.SC_NO_CONTENT, response1.getCode());
|
||||
EntityUtils.consume(response1.getEntity());
|
||||
}
|
||||
final HttpGet get2 = new HttpGet("/stuff");
|
||||
try (CloseableHttpResponse response2 = this.httpclient.execute(target, get2)) {
|
||||
Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
|
||||
EntityUtils.consume(response2.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class TestMinimalClientRequestExecution extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testNonCompliantURI() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
this.httpclient = HttpClients.createMinimal();
|
||||
final HttpHost target = start();
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.apache.hc.core5.http.HttpRequest;
|
|||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.ProtocolException;
|
||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||
import org.apache.hc.core5.http.io.UriHttpRequestHandlerMapper;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
|
@ -120,15 +119,20 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String uri = request.getRequestUri();
|
||||
if (uri.startsWith("/circular-oldlocation")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/circular-location2"));
|
||||
} else if (uri.startsWith("/circular-location2")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/circular-oldlocation"));
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
try {
|
||||
final URI requestURI = request.getUri();
|
||||
final String path = requestURI.getPath();
|
||||
if (path.startsWith("/circular-oldlocation")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/circular-location2"));
|
||||
} else if (path.startsWith("/circular-location2")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/circular-oldlocation"));
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
}
|
||||
} catch (final URISyntaxException ex) {
|
||||
throw new ProtocolException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,16 +148,21 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String uri = request.getRequestUri();
|
||||
if (uri.equals("/oldlocation/")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/relativelocation/"));
|
||||
} else if (uri.equals("/relativelocation/")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
try {
|
||||
final URI requestURI = request.getUri();
|
||||
final String path = requestURI.getPath();
|
||||
if (path.equals("/oldlocation/")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/relativelocation/"));
|
||||
} else if (path.equals("/relativelocation/")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
}
|
||||
} catch (final URISyntaxException ex) {
|
||||
throw new ProtocolException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,16 +178,21 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String uri = request.getRequestUri();
|
||||
if (uri.equals("/test/oldlocation")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "relativelocation"));
|
||||
} else if (uri.equals("/test/relativelocation")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
try {
|
||||
final URI requestURI = request.getUri();
|
||||
final String path = requestURI.getPath();
|
||||
if (path.equals("/test/oldlocation")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "relativelocation"));
|
||||
} else if (path.equals("/test/relativelocation")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
}
|
||||
} catch (final URISyntaxException ex) {
|
||||
throw new ProtocolException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,24 +208,36 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String uri = request.getRequestUri();
|
||||
if (uri.equals("/rome")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/rome"));
|
||||
try {
|
||||
final URI requestURI = request.getUri();
|
||||
final String path = requestURI.getPath();
|
||||
if (path.equals("/rome")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", "/rome"));
|
||||
}
|
||||
} catch (final URISyntaxException ex) {
|
||||
throw new ProtocolException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class BogusRedirectService implements HttpRequestHandler {
|
||||
private final String url;
|
||||
interface UriTransformation {
|
||||
|
||||
public BogusRedirectService(final String redirectUrl) {
|
||||
String rewrite(URI requestUri);
|
||||
|
||||
}
|
||||
|
||||
private static class TransformingRedirectService implements HttpRequestHandler {
|
||||
|
||||
private final UriTransformation uriTransformation;
|
||||
|
||||
public TransformingRedirectService(final UriTransformation uriTransformation) {
|
||||
super();
|
||||
this.url = redirectUrl;
|
||||
this.uriTransformation = uriTransformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -219,24 +245,28 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
final ClassicHttpRequest request,
|
||||
final ClassicHttpResponse response,
|
||||
final HttpContext context) throws HttpException, IOException {
|
||||
final String uri = request.getRequestUri();
|
||||
if (uri.equals("/oldlocation/")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", url));
|
||||
} else if (uri.equals("/relativelocation/")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
try {
|
||||
final URI requestURI = request.getUri();
|
||||
final String path = requestURI.getPath();
|
||||
if (path.equals("/oldlocation/")) {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.addHeader(new BasicHeader("Location", uriTransformation.rewrite(requestURI)));
|
||||
} else if (path.equals("/relativelocation/")) {
|
||||
response.setCode(HttpStatus.SC_OK);
|
||||
final StringEntity entity = new StringEntity("Successful redirect");
|
||||
response.setEntity(entity);
|
||||
} else {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
}
|
||||
} catch (final URISyntaxException ex) {
|
||||
throw new ProtocolException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicRedirect300() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*",
|
||||
new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -258,8 +288,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicRedirect301() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*",
|
||||
new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -285,8 +314,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicRedirect302() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*",
|
||||
new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -305,7 +333,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicRedirect302NoLocation() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new HttpRequestHandler() {
|
||||
this.server.registerHandler("*", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
|
@ -334,8 +362,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicRedirect303() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*",
|
||||
new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -354,8 +381,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicRedirect304() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*",
|
||||
new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -374,8 +400,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicRedirect305() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*",
|
||||
new BasicRedirectService(HttpStatus.SC_USE_PROXY));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_USE_PROXY));
|
||||
final HttpHost target = start();
|
||||
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
@ -393,8 +418,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testBasicRedirect307() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*",
|
||||
new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -413,7 +437,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test(expected=ClientProtocolException.class)
|
||||
public void testMaxRedirectCheck() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new CircularRedirectService());
|
||||
this.server.registerHandler("*", new CircularRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -434,7 +458,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test(expected=ClientProtocolException.class)
|
||||
public void testCircularRedirect() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new CircularRedirectService());
|
||||
this.server.registerHandler("*", new CircularRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -454,7 +478,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testRepeatRequest() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new RomeRedirectService());
|
||||
this.server.registerHandler("*", new RomeRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -477,7 +501,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testRepeatRequestRedirect() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new RomeRedirectService());
|
||||
this.server.registerHandler("*", new RomeRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -500,7 +524,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testDifferentRequestSameRedirect() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new RomeRedirectService());
|
||||
this.server.registerHandler("*", new RomeRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -524,7 +548,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testPostRedirectSeeOther() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
|
||||
this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -545,7 +569,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testRelativeRedirect() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new RelativeRedirectService());
|
||||
this.server.registerHandler("*", new RelativeRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -564,7 +588,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testRelativeRedirect2() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new RelativeRedirectService2());
|
||||
this.server.registerHandler("*", new RelativeRedirectService2());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -583,7 +607,14 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test(expected=ClientProtocolException.class)
|
||||
public void testRejectBogusRedirectLocation() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new BogusRedirectService("xxx://bogus"));
|
||||
this.server.registerHandler("*", new TransformingRedirectService(new UriTransformation() {
|
||||
|
||||
@Override
|
||||
public String rewrite(final URI requestUri) {
|
||||
return "xxx://bogus";
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -600,15 +631,16 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test(expected=ClientProtocolException.class)
|
||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||
final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
|
||||
this.serverBootstrap.setHandlerMapper(reqistry);
|
||||
this.server.registerHandler("*", new TransformingRedirectService(new UriTransformation() {
|
||||
|
||||
@Override
|
||||
public String rewrite(final URI requestUri) {
|
||||
return "/newlocation/?p=I have spaces";
|
||||
}
|
||||
|
||||
}));
|
||||
final HttpHost target = start();
|
||||
|
||||
reqistry.register("*",
|
||||
new BogusRedirectService("http://" + target.toHostString() +
|
||||
"/newlocation/?p=I have spaces"));
|
||||
|
||||
final HttpGet httpget = new HttpGet("/oldlocation/");
|
||||
|
||||
try {
|
||||
|
@ -621,7 +653,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
|
||||
@Test
|
||||
public void testRedirectWithCookie() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new BasicRedirectService());
|
||||
this.server.registerHandler("*", new BasicRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
@ -653,7 +685,7 @@ public class TestRedirects extends LocalServerTestBase {
|
|||
public void testDefaultHeadersRedirect() throws Exception {
|
||||
this.clientBuilder.setDefaultHeaders(Arrays.asList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")));
|
||||
|
||||
this.serverBootstrap.registerHandler("*", new BasicRedirectService());
|
||||
this.server.registerHandler("*", new BasicRedirectService());
|
||||
|
||||
final HttpHost target = start();
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ public class TestSPNegoScheme extends LocalServerTestBase {
|
|||
*/
|
||||
@Test
|
||||
public void testDontTryToAuthenticateEndlessly() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new PleaseNegotiateService());
|
||||
this.server.registerHandler("*", new PleaseNegotiateService());
|
||||
final HttpHost target = start();
|
||||
|
||||
final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager();
|
||||
|
@ -179,7 +179,7 @@ public class TestSPNegoScheme extends LocalServerTestBase {
|
|||
*/
|
||||
@Test
|
||||
public void testNoTokenGeneratedError() throws Exception {
|
||||
this.serverBootstrap.registerHandler("*", new PleaseNegotiateService());
|
||||
this.server.registerHandler("*", new PleaseNegotiateService());
|
||||
final HttpHost target = start();
|
||||
|
||||
final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager();
|
||||
|
|
|
@ -75,7 +75,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
|||
final int workerCount = 5;
|
||||
final int requestCount = 5;
|
||||
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
|
||||
this.connManager.setMaxTotal(workerCount);
|
||||
this.connManager.setDefaultMaxPerRoute(workerCount);
|
||||
|
@ -194,7 +194,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
|||
|
||||
final int maxConn = 2;
|
||||
|
||||
this.serverBootstrap.registerHandler("*", new SimpleService());
|
||||
this.server.registerHandler("*", new SimpleService());
|
||||
|
||||
this.connManager.setMaxTotal(maxConn);
|
||||
this.connManager.setDefaultMaxPerRoute(maxConn);
|
||||
|
@ -229,7 +229,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
|||
// Send it to another route. Must be a keepalive.
|
||||
final HttpContext context2 = new BasicHttpContext();
|
||||
final ClassicHttpResponse response2 = this.httpclient.execute(
|
||||
new HttpHost("127.0.0.1", this.server.getLocalPort()), new HttpGet("/"), context2);
|
||||
new HttpHost("127.0.0.1", this.server.getPort()), new HttpGet("/"), context2);
|
||||
EntityUtils.consume(response2.getEntity());
|
||||
// ConnPoolByRoute now has 2 free connexions, out of its 2 max.
|
||||
// The [localhost][stuff] RouteSpcfcPool is the same as earlier
|
||||
|
|
|
@ -48,9 +48,7 @@ import org.apache.hc.core5.http.config.RegistryBuilder;
|
|||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -58,10 +56,9 @@ import org.junit.Test;
|
|||
*/
|
||||
public class TestWindowsNegotiateScheme extends LocalServerTestBase {
|
||||
|
||||
@Before @Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.serverBootstrap.registerHandler("/", new HttpRequestHandler() {
|
||||
@Test(timeout=30000) // this timeout (in ms) needs to be extended if you're actively debugging the code
|
||||
public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
|
||||
this.server.registerHandler("/", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
|
@ -73,15 +70,6 @@ public class TestWindowsNegotiateScheme extends LocalServerTestBase {
|
|||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@After @Override
|
||||
public void shutDown() throws Exception {
|
||||
super.shutDown();
|
||||
}
|
||||
|
||||
@Test(timeout=30000) // this timeout (in ms) needs to be extended if you're actively debugging the code
|
||||
public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
|
||||
Assume.assumeTrue("Test can only be run on Windows", WinHttpClients.isWinAuthAvailable());
|
||||
|
||||
// HTTPCLIENT-1545
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.hc.core5.http.HttpHost;
|
|||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Example demonstrating how to evict expired and idle connections
|
||||
|
@ -50,7 +51,7 @@ public class AsyncClientConnectionEviction {
|
|||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||
|
|
|
@ -42,7 +42,7 @@ import org.apache.hc.core5.http.config.H1Config;
|
|||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates pipelined execution of multiple HTTP/1.1 message exchanges.
|
||||
|
@ -52,7 +52,7 @@ public class AsyncClientHttp1Pipelining {
|
|||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(H1Config.DEFAULT, ioReactorConfig);
|
||||
|
|
|
@ -42,7 +42,7 @@ import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
|||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates concurrent (multiplexed) execution of multiple
|
||||
|
@ -53,7 +53,7 @@ public class AsyncClientHttp2Multiplexing {
|
|||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(H2Config.DEFAULT, ioReactorConfig);
|
||||
|
|
|
@ -48,7 +48,7 @@ import org.apache.hc.core5.http2.HttpVersionPolicy;
|
|||
import org.apache.hc.core5.http2.config.H2Config;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates handling of HTTP/2 message exchanges pushed by the server.
|
||||
|
@ -58,7 +58,7 @@ public class AsyncClientHttp2ServerPush {
|
|||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final H2Config h2Config = H2Config.custom()
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.apache.hc.core5.concurrent.FutureCallback;
|
|||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Example of asynchronous HTTP/1.1 request execution.
|
||||
|
@ -46,7 +46,7 @@ public class AsyncClientHttpExchange {
|
|||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.apache.hc.core5.http.HttpResponse;
|
|||
import org.apache.hc.core5.http.message.StatusLine;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Example of asynchronous HTTP/1.1 request execution with response streaming.
|
||||
|
@ -51,7 +51,7 @@ public class AsyncClientHttpExchangeStreaming {
|
|||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||
|
|
|
@ -57,7 +57,7 @@ import org.apache.hc.core5.http.nio.AsyncEntityProducer;
|
|||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates how to insert custom request interceptor and an execution interceptor
|
||||
|
@ -68,7 +68,7 @@ public class AsyncClientInterceptors {
|
|||
public final static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||
|
|
|
@ -49,7 +49,7 @@ import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
|
|||
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates how to use a custom execution interceptor
|
||||
|
@ -60,7 +60,7 @@ public class AsyncClientMessageTrailers {
|
|||
public final static void main(final String[] args) throws Exception {
|
||||
|
||||
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
|
||||
.setSoTimeout(TimeValue.ofSeconds(5))
|
||||
.setSoTimeout(Timeout.ofSeconds(5))
|
||||
.build();
|
||||
|
||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||
|
|
|
@ -81,6 +81,7 @@ import org.apache.hc.core5.http.message.LineParser;
|
|||
import org.apache.hc.core5.ssl.SSLContexts;
|
||||
import org.apache.hc.core5.util.CharArrayBuffer;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* This example demonstrates how to customize and configure the most common aspects
|
||||
|
@ -208,9 +209,9 @@ public class ClientConfiguration {
|
|||
// Request configuration can be overridden at the request level.
|
||||
// They will take precedence over the one set at the client level.
|
||||
final RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
|
||||
.setSocketTimeout(TimeValue.ofSeconds(5))
|
||||
.setConnectTimeout(TimeValue.ofSeconds(5))
|
||||
.setConnectionRequestTimeout(TimeValue.ofSeconds(5))
|
||||
.setSocketTimeout(Timeout.ofSeconds(5))
|
||||
.setConnectTimeout(Timeout.ofSeconds(5))
|
||||
.setConnectionRequestTimeout(Timeout.ofSeconds(5))
|
||||
.setProxy(new HttpHost("myotherproxy", 8080))
|
||||
.build();
|
||||
httpget.setConfig(requestConfig);
|
||||
|
|
|
@ -43,7 +43,7 @@ import org.apache.hc.client5.http.sync.methods.HttpGet;
|
|||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
|
||||
public class ClientWithRequestFuture {
|
||||
|
||||
|
@ -59,8 +59,8 @@ public class ClientWithRequestFuture {
|
|||
final ExecutorService execService = Executors.newFixedThreadPool(5);
|
||||
try (FutureRequestExecutionService requestExecService = new FutureRequestExecutionService(
|
||||
httpclient, execService)) {
|
||||
// Because things are asynchronous, you must provide a ResponseHandler
|
||||
final ResponseHandler<Boolean> handler = new ResponseHandler<Boolean>() {
|
||||
// Because things are asynchronous, you must provide a HttpClientResponseHandler
|
||||
final HttpClientResponseHandler<Boolean> handler = new HttpClientResponseHandler<Boolean>() {
|
||||
@Override
|
||||
public Boolean handleResponse(final ClassicHttpResponse response) throws IOException {
|
||||
// simply return true if the status was OK
|
||||
|
|
|
@ -37,11 +37,11 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
|
|||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.ParseException;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
|
||||
/**
|
||||
* This example demonstrates the use of the {@link ResponseHandler} to simplify
|
||||
* This example demonstrates the use of the {@link HttpClientResponseHandler} to simplify
|
||||
* the process of processing the HTTP response and releasing associated resources.
|
||||
*/
|
||||
public class ClientWithResponseHandler {
|
||||
|
@ -53,7 +53,7 @@ public class ClientWithResponseHandler {
|
|||
System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
|
||||
|
||||
// Create a custom response handler
|
||||
final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
|
||||
final HttpClientResponseHandler<String> responseHandler = new HttpClientResponseHandler<String>() {
|
||||
|
||||
@Override
|
||||
public String handleResponse(
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Immutable class encapsulating request configuration items.
|
||||
|
@ -42,9 +42,9 @@ import org.apache.hc.core5.util.TimeValue;
|
|||
@Contract(threading = ThreadingBehavior.IMMUTABLE)
|
||||
public class RequestConfig implements Cloneable {
|
||||
|
||||
private static final TimeValue DEFAULT_CONNECTION_REQUEST_TIMEOUT = TimeValue.ofMinutes(3);
|
||||
private static final TimeValue DEFAULT_CONNECT_TIMEOUT = TimeValue.ofMinutes(3);
|
||||
private static final TimeValue DEFAULT_SOCKET_TIMEOUT = TimeValue.NEG_ONE_MILLISECONDS;
|
||||
private static final Timeout DEFAULT_CONNECTION_REQUEST_TIMEOUT = Timeout.ofMinutes(3);
|
||||
private static final Timeout DEFAULT_CONNECT_TIMEOUT = Timeout.ofMinutes(3);
|
||||
private static final Timeout DEFAULT_SOCKET_TIMEOUT = Timeout.ZERO_MILLISECONDS;
|
||||
|
||||
public static final RequestConfig DEFAULT = new Builder().build();
|
||||
|
||||
|
@ -58,9 +58,9 @@ public class RequestConfig implements Cloneable {
|
|||
private final boolean authenticationEnabled;
|
||||
private final Collection<String> targetPreferredAuthSchemes;
|
||||
private final Collection<String> proxyPreferredAuthSchemes;
|
||||
private final TimeValue connectionRequestTimeout;
|
||||
private final TimeValue connectTimeout;
|
||||
private final TimeValue socketTimeout;
|
||||
private final Timeout connectionRequestTimeout;
|
||||
private final Timeout connectTimeout;
|
||||
private final Timeout socketTimeout;
|
||||
private final boolean contentCompressionEnabled;
|
||||
|
||||
/**
|
||||
|
@ -82,9 +82,9 @@ public class RequestConfig implements Cloneable {
|
|||
final boolean authenticationEnabled,
|
||||
final Collection<String> targetPreferredAuthSchemes,
|
||||
final Collection<String> proxyPreferredAuthSchemes,
|
||||
final TimeValue connectionRequestTimeout,
|
||||
final TimeValue connectTimeout,
|
||||
final TimeValue socketTimeout,
|
||||
final Timeout connectionRequestTimeout,
|
||||
final Timeout connectTimeout,
|
||||
final Timeout socketTimeout,
|
||||
final boolean contentCompressionEnabled) {
|
||||
super();
|
||||
this.expectContinueEnabled = expectContinueEnabled;
|
||||
|
@ -242,7 +242,7 @@ public class RequestConfig implements Cloneable {
|
|||
* Default: 3 minutes.
|
||||
* </p>
|
||||
*/
|
||||
public TimeValue getConnectionRequestTimeout() {
|
||||
public Timeout getConnectionRequestTimeout() {
|
||||
return connectionRequestTimeout;
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ public class RequestConfig implements Cloneable {
|
|||
* Default: 3 minutes
|
||||
* </p>
|
||||
*/
|
||||
public TimeValue getConnectTimeout() {
|
||||
public Timeout getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,7 @@ public class RequestConfig implements Cloneable {
|
|||
* Default: no timeout.
|
||||
* </p>
|
||||
*/
|
||||
public TimeValue getSocketTimeout() {
|
||||
public Timeout getSocketTimeout() {
|
||||
return socketTimeout;
|
||||
}
|
||||
|
||||
|
@ -350,9 +350,9 @@ public class RequestConfig implements Cloneable {
|
|||
private boolean authenticationEnabled;
|
||||
private Collection<String> targetPreferredAuthSchemes;
|
||||
private Collection<String> proxyPreferredAuthSchemes;
|
||||
private TimeValue connectionRequestTimeout;
|
||||
private TimeValue connectTimeout;
|
||||
private TimeValue socketTimeout;
|
||||
private Timeout connectionRequestTimeout;
|
||||
private Timeout connectTimeout;
|
||||
private Timeout socketTimeout;
|
||||
private boolean contentCompressionEnabled;
|
||||
|
||||
Builder() {
|
||||
|
@ -416,33 +416,33 @@ public class RequestConfig implements Cloneable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setConnectionRequestTimeout(final TimeValue connectionRequestTimeout) {
|
||||
public Builder setConnectionRequestTimeout(final Timeout connectionRequestTimeout) {
|
||||
this.connectionRequestTimeout = connectionRequestTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setConnectionRequestTimeout(final long connectionRequestTimeout, final TimeUnit timeUnit) {
|
||||
this.connectionRequestTimeout = TimeValue.of(connectionRequestTimeout, timeUnit);
|
||||
this.connectionRequestTimeout = Timeout.of(connectionRequestTimeout, timeUnit);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setConnectTimeout(final TimeValue connectTimeout) {
|
||||
public Builder setConnectTimeout(final Timeout connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setConnectTimeout(final long connectTimeout, final TimeUnit timeUnit) {
|
||||
this.connectTimeout = TimeValue.of(connectTimeout, timeUnit);
|
||||
this.connectTimeout = Timeout.of(connectTimeout, timeUnit);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSocketTimeout(final TimeValue socketTimeout) {
|
||||
public Builder setSocketTimeout(final Timeout socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSocketTimeout(final long socketTimeout, final TimeUnit timeUnit) {
|
||||
this.socketTimeout = TimeValue.of(socketTimeout, timeUnit);
|
||||
this.socketTimeout = Timeout.of(socketTimeout, timeUnit);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,212 +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.http.impl;
|
||||
|
||||
import org.apache.hc.core5.util.Args;
|
||||
|
||||
/**
|
||||
* Chain of doubly linked elements.
|
||||
* <p>
|
||||
* This implementation makes no attempts to ensure uniqueness of element names.
|
||||
*
|
||||
* @param <E>
|
||||
*/
|
||||
public class NamedElementChain<E> {
|
||||
|
||||
private final Node master;
|
||||
private int size;
|
||||
|
||||
public NamedElementChain() {
|
||||
this.master = new Node("master", null);
|
||||
this.master.previous = this.master;
|
||||
this.master.next = this.master;
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
public Node getFirst() {
|
||||
if (master.next != master) {
|
||||
return master.next;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Node getLast() {
|
||||
if (master.previous != master) {
|
||||
return master.previous;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Node addFirst(final E value, final String name) {
|
||||
Args.notBlank(name, "Name");
|
||||
Args.notNull(value, "Value");
|
||||
final Node newNode = new Node(name, value);
|
||||
final Node oldNode = master.next;
|
||||
master.next = newNode;
|
||||
newNode.previous = master;
|
||||
newNode.next = oldNode;
|
||||
oldNode.previous = newNode;
|
||||
size++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public Node addLast(final E value, final String name) {
|
||||
Args.notBlank(name, "Name");
|
||||
Args.notNull(value, "Value");
|
||||
final Node newNode = new Node(name, value);
|
||||
final Node oldNode = master.previous;
|
||||
master.previous = newNode;
|
||||
newNode.previous = oldNode;
|
||||
newNode.next = master;
|
||||
oldNode.next = newNode;
|
||||
size++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public Node find(final String name) {
|
||||
Args.notBlank(name, "Name");
|
||||
return doFind(name);
|
||||
}
|
||||
|
||||
private Node doFind(final String name) {
|
||||
Node current = master.next;
|
||||
while (current != master) {
|
||||
if (name.equals(current.name)) {
|
||||
return current;
|
||||
}
|
||||
current = current.next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Node addBefore(final String existing, final E value, final String name) {
|
||||
Args.notBlank(name, "Name");
|
||||
Args.notNull(value, "Value");
|
||||
final Node current = doFind(existing);
|
||||
if (current == null) {
|
||||
return null;
|
||||
}
|
||||
final Node newNode = new Node(name, value);
|
||||
final Node previousNode = current.previous;
|
||||
previousNode.next = newNode;
|
||||
newNode.previous = previousNode;
|
||||
newNode.next = current;
|
||||
current.previous = newNode;
|
||||
size++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public Node addAfter(final String existing, final E value, final String name) {
|
||||
Args.notBlank(name, "Name");
|
||||
Args.notNull(value, "Value");
|
||||
final Node current = doFind(existing);
|
||||
if (current == null) {
|
||||
return null;
|
||||
}
|
||||
final Node newNode = new Node(name, value);
|
||||
final Node nextNode = current.next;
|
||||
current.next = newNode;
|
||||
newNode.previous = current;
|
||||
newNode.next = nextNode;
|
||||
nextNode.previous = newNode;
|
||||
size++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public boolean remove(final String name) {
|
||||
final Node node = doFind(name);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
node.previous.next = node.next;
|
||||
node.next.previous = node.previous;
|
||||
node.previous = null;
|
||||
node.next = null;
|
||||
size--;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean replace(final String existing, final E value) {
|
||||
final Node node = doFind(existing);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
node.value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public class Node {
|
||||
|
||||
private final String name;
|
||||
private E value;
|
||||
private Node previous;
|
||||
private Node next;
|
||||
|
||||
Node(final String name, final E value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public E getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Node getPrevious() {
|
||||
if (previous != master) {
|
||||
return previous;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Node getNext() {
|
||||
if (next != master) {
|
||||
return next;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ": " + value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -33,7 +33,6 @@ import java.util.concurrent.ThreadFactory;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.hc.core5.function.Supplier;
|
||||
import org.apache.hc.core5.http.ExceptionListener;
|
||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.ConnectionInitiator;
|
||||
|
@ -52,7 +51,6 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
|
|||
|
||||
private final AsyncPushConsumerRegistry pushConsumerRegistry;
|
||||
private final DefaultConnectingIOReactor ioReactor;
|
||||
private final ExceptionListener exceptionListener;
|
||||
private final ExecutorService executorService;
|
||||
private final AtomicReference<Status> status;
|
||||
|
||||
|
@ -63,14 +61,6 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
|
|||
super();
|
||||
this.ioReactor = ioReactor;
|
||||
this.pushConsumerRegistry = pushConsumerRegistry;
|
||||
this.exceptionListener = new ExceptionListener() {
|
||||
|
||||
@Override
|
||||
public void onError(final Exception ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
};
|
||||
this.executorService = Executors.newSingleThreadExecutor(threadFactory);
|
||||
this.status = new AtomicReference<>(Status.READY);
|
||||
}
|
||||
|
@ -82,11 +72,7 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ioReactor.execute();
|
||||
} catch (final Exception ex) {
|
||||
exceptionListener.onError(ex);
|
||||
}
|
||||
ioReactor.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -116,8 +102,8 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final List<ExceptionEvent> getAuditLog() {
|
||||
return ioReactor.getAuditLog();
|
||||
public final List<ExceptionEvent> getExceptionLog() {
|
||||
return ioReactor.getExceptionLog();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -62,7 +62,7 @@ public abstract class CloseableHttpAsyncClient implements HttpAsyncClient, Close
|
|||
|
||||
public abstract IOReactorStatus getStatus();
|
||||
|
||||
public abstract List<ExceptionEvent> getAuditLog();
|
||||
public abstract List<ExceptionEvent> getExceptionLog();
|
||||
|
||||
public abstract void awaitShutdown(TimeValue waitTime) throws InterruptedException;
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.apache.hc.client5.http.impl.DefaultConnectionKeepAliveStrategy;
|
|||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
|
||||
import org.apache.hc.client5.http.impl.DefaultUserTokenHandler;
|
||||
import org.apache.hc.client5.http.impl.IdleConnectionEvictor;
|
||||
import org.apache.hc.client5.http.impl.NamedElementChain;
|
||||
import org.apache.hc.client5.http.impl.NoopUserTokenHandler;
|
||||
import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
|
||||
import org.apache.hc.client5.http.impl.auth.CredSspSchemeFactory;
|
||||
|
@ -97,6 +96,7 @@ import org.apache.hc.core5.http.HttpResponseInterceptor;
|
|||
import org.apache.hc.core5.http.config.CharCodingConfig;
|
||||
import org.apache.hc.core5.http.config.H1Config;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.config.NamedElementChain;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||
|
@ -118,7 +118,6 @@ import org.apache.hc.core5.pool.ConnPoolControl;
|
|||
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
||||
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.reactor.IOReactorException;
|
||||
import org.apache.hc.core5.reactor.IOSession;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
@ -904,7 +903,7 @@ public class HttpAsyncClientBuilder {
|
|||
new HandlerFactory<AsyncPushConsumer>() {
|
||||
|
||||
@Override
|
||||
public AsyncPushConsumer create(final HttpRequest request) throws HttpException {
|
||||
public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
|
||||
return pushConsumerRegistry.get(request);
|
||||
}
|
||||
|
||||
|
@ -914,23 +913,20 @@ public class HttpAsyncClientBuilder {
|
|||
h1Config != null ? h1Config : H1Config.DEFAULT,
|
||||
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
|
||||
reuseStrategyCopy);
|
||||
final DefaultConnectingIOReactor ioReactor;
|
||||
try {
|
||||
ioReactor = new DefaultConnectingIOReactor(
|
||||
ioEventHandlerFactory,
|
||||
ioReactorConfig != null ? ioReactorConfig : IOReactorConfig.DEFAULT,
|
||||
threadFactory != null ? threadFactory : new DefaultThreadFactory("httpclient-dispatch", true),
|
||||
new Callback<IOSession>() {
|
||||
final DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
|
||||
ioEventHandlerFactory,
|
||||
ioReactorConfig != null ? ioReactorConfig : IOReactorConfig.DEFAULT,
|
||||
threadFactory != null ? threadFactory : new DefaultThreadFactory("httpclient-dispatch", true),
|
||||
null,
|
||||
null,
|
||||
new Callback<IOSession>() {
|
||||
|
||||
@Override
|
||||
public void execute(final IOSession ioSession) {
|
||||
ioSession.addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
|
||||
}
|
||||
@Override
|
||||
public void execute(final IOSession ioSession) {
|
||||
ioSession.addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
|
||||
}
|
||||
|
||||
});
|
||||
} catch (final IOReactorException ex) {
|
||||
throw new IllegalStateException(ex.getMessage(), ex);
|
||||
}
|
||||
});
|
||||
|
||||
if (execInterceptors != null) {
|
||||
for (final ExecInterceptorEntry entry: execInterceptors) {
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.apache.hc.client5.http.impl.logging.LogAppendable;
|
|||
import org.apache.hc.client5.http.impl.logging.LoggingIOSession;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.ConnectionClosedException;
|
||||
import org.apache.hc.core5.http.ConnectionReuseStrategy;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpConnection;
|
||||
|
@ -44,7 +43,6 @@ import org.apache.hc.core5.http.HttpRequest;
|
|||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.config.CharCodingConfig;
|
||||
import org.apache.hc.core5.http.config.H1Config;
|
||||
import org.apache.hc.core5.http.impl.ConnectionListener;
|
||||
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
||||
import org.apache.hc.core5.http.impl.Http1StreamListener;
|
||||
import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
|
||||
|
@ -124,31 +122,6 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
|
|||
|| framePayloadLog.isDebugEnabled()
|
||||
|| flowCtrlLog.isDebugEnabled()) {
|
||||
final String id = ConnPoolSupport.getId(ioSession);
|
||||
final ConnectionListener connectionListener = new ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void onConnect(final HttpConnection connection) {
|
||||
if (streamLog.isDebugEnabled()) {
|
||||
streamLog.debug(id + ": " + connection + " connected");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(final HttpConnection connection) {
|
||||
if (streamLog.isDebugEnabled()) {
|
||||
streamLog.debug(id + ": " + connection + " disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(final HttpConnection connection, final Exception ex) {
|
||||
if (ex instanceof ConnectionClosedException) {
|
||||
return;
|
||||
}
|
||||
streamLog.error(id + ": " + ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
};
|
||||
final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
|
||||
httpProcessor,
|
||||
h1Config,
|
||||
|
@ -156,7 +129,6 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
|
|||
http1ConnectionReuseStrategy,
|
||||
http1ResponseParserFactory,
|
||||
http1RequestWriterFactory,
|
||||
connectionListener,
|
||||
new Http1StreamListener() {
|
||||
|
||||
@Override
|
||||
|
@ -196,7 +168,6 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
|
|||
exchangeHandlerFactory,
|
||||
h2Config,
|
||||
charCodingConfig,
|
||||
connectionListener,
|
||||
new Http2StreamListener() {
|
||||
|
||||
final FramePrinter framePrinter = new FramePrinter();
|
||||
|
@ -285,8 +256,7 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
|
|||
loggingIOSession,
|
||||
http1StreamHandlerFactory,
|
||||
http2StreamHandlerFactory,
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy,
|
||||
connectionListener);
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy);
|
||||
} else {
|
||||
final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
|
||||
httpProcessor,
|
||||
|
@ -295,19 +265,18 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
|
|||
http1ConnectionReuseStrategy,
|
||||
http1ResponseParserFactory,
|
||||
http1RequestWriterFactory,
|
||||
null, null);
|
||||
null);
|
||||
final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory = new ClientHttp2StreamMultiplexerFactory(
|
||||
httpProcessor,
|
||||
exchangeHandlerFactory,
|
||||
h2Config,
|
||||
charCodingConfig,
|
||||
null, null);
|
||||
null);
|
||||
return new ClientHttpProtocolNegotiator(
|
||||
ioSession,
|
||||
http1StreamHandlerFactory,
|
||||
http2StreamHandlerFactory,
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy,
|
||||
null);
|
||||
attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ import org.apache.hc.core5.http2.protocol.H2RequestContent;
|
|||
import org.apache.hc.core5.http2.protocol.H2RequestTargetHost;
|
||||
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.reactor.IOReactorException;
|
||||
import org.apache.hc.core5.util.VersionInfo;
|
||||
|
||||
/**
|
||||
|
@ -95,18 +94,14 @@ public class HttpAsyncClients {
|
|||
final HttpVersionPolicy versionPolicy,
|
||||
final IOReactorConfig ioReactorConfig,
|
||||
final AsyncClientConnectionManager connmgr) {
|
||||
try {
|
||||
return new MinimalHttpAsyncClient(
|
||||
eventHandlerFactory,
|
||||
pushConsumerRegistry,
|
||||
versionPolicy,
|
||||
ioReactorConfig,
|
||||
new DefaultThreadFactory("httpclient-main", true),
|
||||
new DefaultThreadFactory("httpclient-dispatch", true),
|
||||
connmgr);
|
||||
} catch (final IOReactorException ex) {
|
||||
throw new IllegalStateException(ex.getMessage(), ex);
|
||||
}
|
||||
return new MinimalHttpAsyncClient(
|
||||
eventHandlerFactory,
|
||||
pushConsumerRegistry,
|
||||
versionPolicy,
|
||||
ioReactorConfig,
|
||||
new DefaultThreadFactory("httpclient-main", true),
|
||||
new DefaultThreadFactory("httpclient-dispatch", true),
|
||||
connmgr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,16 +34,15 @@ import org.apache.hc.core5.http.EntityDetails;
|
|||
import org.apache.hc.core5.http.nio.AsyncDataProducer;
|
||||
import org.apache.hc.core5.http.nio.AsyncEntityProducer;
|
||||
import org.apache.hc.core5.http.nio.DataStreamChannel;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
|
||||
public class BasicAsyncEntityProducer implements AsyncEntityProducer {
|
||||
final class InternalAsyncEntityProducer implements AsyncEntityProducer {
|
||||
|
||||
private final AsyncDataProducer dataProducer;
|
||||
private final EntityDetails entityDetails;
|
||||
|
||||
BasicAsyncEntityProducer(final AsyncDataProducer dataProducer, final EntityDetails entityDetails) {
|
||||
this.dataProducer = Args.notNull(dataProducer, "Data producer");
|
||||
this.entityDetails = Args.notNull(entityDetails, "Entity details");
|
||||
InternalAsyncEntityProducer(final AsyncDataProducer dataProducer, final EntityDetails entityDetails) {
|
||||
this.dataProducer = dataProducer;
|
||||
this.entityDetails = entityDetails;
|
||||
}
|
||||
|
||||
@Override
|
|
@ -53,6 +53,8 @@ import org.apache.hc.core5.http.HttpException;
|
|||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpVersion;
|
||||
import org.apache.hc.core5.http.ProtocolVersion;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.AsyncDataConsumer;
|
||||
|
@ -150,9 +152,9 @@ class InternalHttpAsyncClient extends AbstractHttpAsyncClientBase {
|
|||
log.debug(exchangeId + ": preparing request execution");
|
||||
}
|
||||
|
||||
//TODO remove when fixed in HttpCore
|
||||
if (route.isTunnelled()) {
|
||||
throw new HttpException("HTTP tunneling not supported");
|
||||
final ProtocolVersion protocolVersion = clientContext.getProtocolVersion();
|
||||
if (route.isTunnelled() && protocolVersion.greaterEquals(HttpVersion.HTTP_2_0)) {
|
||||
throw new HttpException("HTTP/2 tunneling not supported");
|
||||
}
|
||||
|
||||
setupContext(clientContext);
|
||||
|
@ -160,7 +162,7 @@ class InternalHttpAsyncClient extends AbstractHttpAsyncClientBase {
|
|||
final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, clientContext, execRuntime);
|
||||
execChain.execute(
|
||||
ExecSupport.copy(request),
|
||||
entityDetails != null ? new BasicAsyncEntityProducer(exchangeHandler, entityDetails) : null,
|
||||
entityDetails != null ? new InternalAsyncEntityProducer(exchangeHandler, entityDetails) : null,
|
||||
scope,
|
||||
new AsyncExecCallback() {
|
||||
|
||||
|
|
|
@ -44,12 +44,15 @@ import org.apache.hc.core5.concurrent.Cancellable;
|
|||
import org.apache.hc.core5.concurrent.ComplexFuture;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.function.Callback;
|
||||
import org.apache.hc.core5.http.EntityDetails;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
||||
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
|
||||
import org.apache.hc.core5.http.nio.RequestChannel;
|
||||
import org.apache.hc.core5.http.nio.command.ShutdownCommand;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||
|
@ -57,11 +60,11 @@ import org.apache.hc.core5.io.ShutdownType;
|
|||
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
||||
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||
import org.apache.hc.core5.reactor.IOReactorException;
|
||||
import org.apache.hc.core5.reactor.IOSession;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.Asserts;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
|
||||
|
||||
|
@ -75,11 +78,13 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
|
|||
final IOReactorConfig reactorConfig,
|
||||
final ThreadFactory threadFactory,
|
||||
final ThreadFactory workerThreadFactory,
|
||||
final AsyncClientConnectionManager connmgr) throws IOReactorException {
|
||||
final AsyncClientConnectionManager connmgr) {
|
||||
super(new DefaultConnectingIOReactor(
|
||||
eventHandlerFactory,
|
||||
reactorConfig,
|
||||
workerThreadFactory,
|
||||
null,
|
||||
null,
|
||||
new Callback<IOSession>() {
|
||||
|
||||
@Override
|
||||
|
@ -96,7 +101,7 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
|
|||
|
||||
private Future<AsyncConnectionEndpoint> leaseEndpoint(
|
||||
final HttpHost host,
|
||||
final TimeValue connectTimeout,
|
||||
final Timeout connectTimeout,
|
||||
final HttpClientContext clientContext,
|
||||
final FutureCallback<AsyncConnectionEndpoint> callback) {
|
||||
final ComplexFuture<AsyncConnectionEndpoint> resultFuture = new ComplexFuture<>(callback);
|
||||
|
@ -197,8 +202,6 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
|
|||
final HttpContext context,
|
||||
final FutureCallback<T> callback) {
|
||||
ensureRunning();
|
||||
final HttpRequest request = requestProducer.produceRequest();
|
||||
final HttpHost target = new HttpHost(request.getAuthority(), request.getScheme());
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
RequestConfig requestConfig = null;
|
||||
if (requestProducer instanceof Configurable) {
|
||||
|
@ -210,58 +213,73 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
|
|||
requestConfig = clientContext.getRequestConfig();
|
||||
}
|
||||
final ComplexFuture<T> resultFuture = new ComplexFuture<>(callback);
|
||||
final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(target, requestConfig.getConnectTimeout(), clientContext,
|
||||
new FutureCallback<AsyncConnectionEndpoint>() {
|
||||
try {
|
||||
final Timeout connectTimeout = requestConfig.getConnectTimeout();
|
||||
requestProducer.sendRequest(new RequestChannel() {
|
||||
|
||||
@Override
|
||||
public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
|
||||
final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
|
||||
endpoint.execute(requestProducer, responseConsumer, clientContext, new FutureCallback<T>() {
|
||||
@Override
|
||||
public void sendRequest(
|
||||
final HttpRequest request,
|
||||
final EntityDetails entityDetails) throws HttpException, IOException {
|
||||
final HttpHost target = new HttpHost(request.getAuthority(), request.getScheme());
|
||||
final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(target, connectTimeout, clientContext,
|
||||
new FutureCallback<AsyncConnectionEndpoint>() {
|
||||
|
||||
@Override
|
||||
public void completed(final T result) {
|
||||
endpoint.releaseAndReuse();
|
||||
resultFuture.completed(result);
|
||||
}
|
||||
@Override
|
||||
public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
|
||||
final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
|
||||
endpoint.execute(requestProducer, responseConsumer, clientContext, new FutureCallback<T>() {
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
endpoint.releaseAndDiscard();
|
||||
resultFuture.failed(ex);
|
||||
}
|
||||
@Override
|
||||
public void completed(final T result) {
|
||||
endpoint.releaseAndReuse();
|
||||
resultFuture.completed(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
endpoint.releaseAndDiscard();
|
||||
resultFuture.cancel();
|
||||
}
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
endpoint.releaseAndDiscard();
|
||||
resultFuture.failed(ex);
|
||||
}
|
||||
|
||||
});
|
||||
resultFuture.setDependency(new Cancellable() {
|
||||
@Override
|
||||
public void cancelled() {
|
||||
endpoint.releaseAndDiscard();
|
||||
resultFuture.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
final boolean active = !endpoint.isReleased();
|
||||
endpoint.releaseAndDiscard();
|
||||
return active;
|
||||
}
|
||||
});
|
||||
resultFuture.setDependency(new Cancellable() {
|
||||
|
||||
});
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
final boolean active = !endpoint.isReleased();
|
||||
endpoint.releaseAndDiscard();
|
||||
return active;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
resultFuture.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
resultFuture.cancel();
|
||||
}
|
||||
@Override
|
||||
public void failed(final Exception ex) {
|
||||
resultFuture.failed(ex);
|
||||
}
|
||||
|
||||
});
|
||||
resultFuture.setDependency(leaseFuture);
|
||||
@Override
|
||||
public void cancelled() {
|
||||
resultFuture.cancel();
|
||||
}
|
||||
|
||||
});
|
||||
resultFuture.setDependency(leaseFuture);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (final HttpException | IOException ex) {
|
||||
resultFuture.failed(ex);
|
||||
}
|
||||
return resultFuture;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,8 +65,8 @@ import org.apache.hc.core5.http.protocol.HttpContext;
|
|||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.pool.ConnPoolControl;
|
||||
import org.apache.hc.core5.pool.ConnPoolListener;
|
||||
import org.apache.hc.core5.pool.ConnPoolPolicy;
|
||||
import org.apache.hc.core5.pool.PoolEntry;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.pool.PoolStats;
|
||||
import org.apache.hc.core5.pool.StrictConnPool;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
|
@ -128,7 +128,7 @@ public class PoolingHttpClientConnectionManager
|
|||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(final TimeValue timeToLive) {
|
||||
this(getDefaultRegistry(), null, null ,null, ConnPoolPolicy.LIFO, null, timeToLive);
|
||||
this(getDefaultRegistry(), null, null ,null, PoolReusePolicy.LIFO, null, timeToLive);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
|
@ -157,7 +157,7 @@ public class PoolingHttpClientConnectionManager
|
|||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
|
||||
final DnsResolver dnsResolver) {
|
||||
this(socketFactoryRegistry, connFactory, null, dnsResolver, ConnPoolPolicy.LIFO, null, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
this(socketFactoryRegistry, connFactory, null, dnsResolver, PoolReusePolicy.LIFO, null, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
|
@ -165,24 +165,24 @@ public class PoolingHttpClientConnectionManager
|
|||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver,
|
||||
final ConnPoolPolicy connPoolPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final ConnPoolListener<HttpRoute> connPoolListener,
|
||||
final TimeValue timeToLive) {
|
||||
this(new DefaultHttpClientConnectionOperator(socketFactoryRegistry, schemePortResolver, dnsResolver),
|
||||
connFactory, connPoolPolicy, connPoolListener, timeToLive);
|
||||
connFactory, poolReusePolicy, connPoolListener, timeToLive);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final HttpClientConnectionOperator httpClientConnectionOperator,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
|
||||
final ConnPoolPolicy connPoolPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final ConnPoolListener<HttpRoute> connPoolListener,
|
||||
final TimeValue timeToLive) {
|
||||
super();
|
||||
this.connectionOperator = Args.notNull(httpClientConnectionOperator, "Connection operator");
|
||||
this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE;
|
||||
this.pool = new StrictConnPool<>(
|
||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive, connPoolPolicy, connPoolListener);
|
||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive, poolReusePolicy, connPoolListener);
|
||||
this.closed = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.apache.hc.core5.http.config.RegistryBuilder;
|
|||
import org.apache.hc.core5.http.config.SocketConfig;
|
||||
import org.apache.hc.core5.http.io.HttpConnectionFactory;
|
||||
import org.apache.hc.core5.pool.ConnPoolListener;
|
||||
import org.apache.hc.core5.pool.ConnPoolPolicy;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,7 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
private LayeredConnectionSocketFactory sslSocketFactory;
|
||||
private SchemePortResolver schemePortResolver;
|
||||
private DnsResolver dnsResolver;
|
||||
private ConnPoolPolicy connPoolPolicy;
|
||||
private PoolReusePolicy poolReusePolicy;
|
||||
private ConnPoolListener<HttpRoute> connPoolListener;
|
||||
private SocketConfig defaultSocketConfig;
|
||||
|
||||
|
@ -129,10 +129,10 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link ConnPoolPolicy} value.
|
||||
* Assigns {@link PoolReusePolicy} value.
|
||||
*/
|
||||
public final PoolingHttpClientConnectionManagerBuilder setConnPoolPolicy(final ConnPoolPolicy connPoolPolicy) {
|
||||
this.connPoolPolicy = connPoolPolicy;
|
||||
public final PoolingHttpClientConnectionManagerBuilder setConnPoolPolicy(final PoolReusePolicy poolReusePolicy) {
|
||||
this.poolReusePolicy = poolReusePolicy;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
connectionFactory,
|
||||
schemePortResolver,
|
||||
dnsResolver,
|
||||
connPoolPolicy,
|
||||
poolReusePolicy,
|
||||
connPoolListener,
|
||||
timeToLive != null ? timeToLive : TimeValue.NEG_ONE_MILLISECONDS);
|
||||
poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);
|
||||
|
|
|
@ -27,15 +27,14 @@
|
|||
|
||||
package org.apache.hc.client5.http.impl.nio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.hc.client5.http.ConnectTimeoutException;
|
||||
import org.apache.hc.client5.http.DnsResolver;
|
||||
import org.apache.hc.client5.http.HttpHostConnectException;
|
||||
import org.apache.hc.client5.http.SchemePortResolver;
|
||||
|
@ -48,9 +47,7 @@ import org.apache.hc.core5.http.HttpHost;
|
|||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||
import org.apache.hc.core5.reactor.ConnectionInitiator;
|
||||
import org.apache.hc.core5.reactor.SessionRequest;
|
||||
import org.apache.hc.core5.reactor.SessionRequestCallback;
|
||||
import org.apache.hc.core5.reactor.TlsCapableIOSession;
|
||||
import org.apache.hc.core5.reactor.IOSession;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
|
@ -101,16 +98,16 @@ final class AsyncClientConnectionOperator {
|
|||
void executeNext() {
|
||||
final int index = attempt.getAndIncrement();
|
||||
final InetSocketAddress remoteAddress = new InetSocketAddress(remoteAddresses[index], port);
|
||||
final SessionRequest sessionRequest = connectionInitiator.connect(
|
||||
final Future<IOSession> sessionFuture = connectionInitiator.connect(
|
||||
host,
|
||||
remoteAddress,
|
||||
localAddress,
|
||||
connectTimeout,
|
||||
attachment,
|
||||
new SessionRequestCallback() {
|
||||
new FutureCallback<IOSession>() {
|
||||
|
||||
@Override
|
||||
public void completed(final SessionRequest request) {
|
||||
final TlsCapableIOSession session = request.getSession();
|
||||
public void completed(final IOSession session) {
|
||||
final ManagedAsyncClientConnection connection = new ManagedAsyncClientConnection(session);
|
||||
if (tlsStrategy != null) {
|
||||
tlsStrategy.upgrade(
|
||||
|
@ -118,33 +115,31 @@ final class AsyncClientConnectionOperator {
|
|||
host,
|
||||
session.getLocalAddress(),
|
||||
session.getRemoteAddress(),
|
||||
request.getAttachment());
|
||||
attachment);
|
||||
}
|
||||
future.completed(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final SessionRequest request) {
|
||||
public void failed(final Exception cause) {
|
||||
if (attempt.get() >= remoteAddresses.length) {
|
||||
future.failed(new HttpHostConnectException(request.getException(), host, remoteAddresses));
|
||||
if (cause instanceof IOException) {
|
||||
future.failed(new HttpHostConnectException((IOException) cause, host, remoteAddresses));
|
||||
} else {
|
||||
future.failed(cause);
|
||||
}
|
||||
} else {
|
||||
executeNext();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeout(final SessionRequest request) {
|
||||
future.failed(new ConnectTimeoutException(new SocketException(), host, remoteAddresses));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled(final SessionRequest request) {
|
||||
public void cancelled() {
|
||||
future.cancel();
|
||||
}
|
||||
|
||||
});
|
||||
future.setDependency(sessionRequest);
|
||||
sessionRequest.setConnectTimeout(connectTimeout.toMillisIntBound());
|
||||
future.setDependency(sessionFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,7 +43,7 @@ import org.apache.hc.core5.http.nio.command.ShutdownCommand;
|
|||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.reactor.Command;
|
||||
import org.apache.hc.core5.reactor.IOEventHandler;
|
||||
import org.apache.hc.core5.reactor.TlsCapableIOSession;
|
||||
import org.apache.hc.core5.reactor.IOSession;
|
||||
import org.apache.hc.core5.reactor.ssl.SSLBufferManagement;
|
||||
import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
|
||||
import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
|
||||
|
@ -57,10 +57,10 @@ final class ManagedAsyncClientConnection implements Identifiable, HttpConnection
|
|||
|
||||
private final Logger log = LogManager.getLogger(getClass());
|
||||
|
||||
private final TlsCapableIOSession ioSession;
|
||||
private final IOSession ioSession;
|
||||
private final AtomicBoolean closed;
|
||||
|
||||
public ManagedAsyncClientConnection(final TlsCapableIOSession ioSession) {
|
||||
public ManagedAsyncClientConnection(final IOSession ioSession) {
|
||||
this.ioSession = ioSession;
|
||||
this.closed = new AtomicBoolean();
|
||||
}
|
||||
|
@ -144,17 +144,21 @@ final class ManagedAsyncClientConnection implements Identifiable, HttpConnection
|
|||
if (log.isDebugEnabled()) {
|
||||
log.debug(getId() + ": start TLS");
|
||||
}
|
||||
ioSession.startTls(sslContext, sslBufferManagement, initializer, verifier);
|
||||
if (ioSession instanceof TransportSecurityLayer) {
|
||||
((TransportSecurityLayer) ioSession).startTls(sslContext, sslBufferManagement, initializer, verifier);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("TLS upgrade not supported");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TlsDetails getTlsDetails() {
|
||||
return ioSession.getTlsDetails();
|
||||
return ioSession instanceof TransportSecurityLayer ? ((TransportSecurityLayer) ioSession).getTlsDetails() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSLSession getSSLSession() {
|
||||
final TlsDetails tlsDetails = ioSession.getTlsDetails();
|
||||
final TlsDetails tlsDetails = getTlsDetails();
|
||||
return tlsDetails != null ? tlsDetails.getSSLSession() : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,8 +59,8 @@ import org.apache.hc.core5.http2.nio.support.BasicPingHandler;
|
|||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.pool.ConnPoolControl;
|
||||
import org.apache.hc.core5.pool.ConnPoolListener;
|
||||
import org.apache.hc.core5.pool.ConnPoolPolicy;
|
||||
import org.apache.hc.core5.pool.PoolEntry;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.pool.PoolStats;
|
||||
import org.apache.hc.core5.pool.StrictConnPool;
|
||||
import org.apache.hc.core5.reactor.ConnectionInitiator;
|
||||
|
@ -68,6 +68,7 @@ import org.apache.hc.core5.util.Args;
|
|||
import org.apache.hc.core5.util.Asserts;
|
||||
import org.apache.hc.core5.util.Identifiable;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
@ -105,10 +106,10 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver,
|
||||
final TimeValue timeToLive,
|
||||
final ConnPoolPolicy policy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final ConnPoolListener<HttpRoute> connPoolListener) {
|
||||
this.connectionOperator = new AsyncClientConnectionOperator(schemePortResolver, dnsResolver, tlsStrategyLookup);
|
||||
this.pool = new StrictConnPool<>(20, 50, timeToLive, policy != null ? policy : ConnPoolPolicy.LIFO, connPoolListener);
|
||||
this.pool = new StrictConnPool<>(20, 50, timeToLive, poolReusePolicy != null ? poolReusePolicy : PoolReusePolicy.LIFO, connPoolListener);
|
||||
this.closed = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
|
@ -142,7 +143,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
public Future<AsyncConnectionEndpoint> lease(
|
||||
final HttpRoute route,
|
||||
final Object state,
|
||||
final TimeValue timeout,
|
||||
final Timeout timeout,
|
||||
final FutureCallback<AsyncConnectionEndpoint> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Connection request: " + ConnPoolSupport.formatStats(null, route, state, pool));
|
||||
|
@ -381,7 +382,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
|
||||
/**
|
||||
* Defines period of inactivity in milliseconds after which persistent connections must
|
||||
* be re-validated prior to being {@link #lease(HttpRoute, Object, TimeValue,
|
||||
* be re-validated prior to being {@link #lease(HttpRoute, Object, Timeout,
|
||||
* FutureCallback)} leased} to the consumer. Non-positive value passed
|
||||
* to this method disables connection validation. This check helps detect connections
|
||||
* that have become stale (half-closed) while kept inactive in the pool.
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
package org.apache.hc.client5.http.impl.nio;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import org.apache.hc.client5.http.DnsResolver;
|
||||
import org.apache.hc.client5.http.HttpRoute;
|
||||
import org.apache.hc.client5.http.SchemePortResolver;
|
||||
|
@ -34,12 +37,9 @@ import org.apache.hc.client5.http.ssl.H2TlsStrategy;
|
|||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||
import org.apache.hc.core5.pool.ConnPoolListener;
|
||||
import org.apache.hc.core5.pool.ConnPoolPolicy;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Builder for {@link PoolingAsyncClientConnectionManager} instances.
|
||||
* <p>
|
||||
|
@ -71,7 +71,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
private TlsStrategy tlsStrategy;
|
||||
private SchemePortResolver schemePortResolver;
|
||||
private DnsResolver dnsResolver;
|
||||
private ConnPoolPolicy connPoolPolicy;
|
||||
private PoolReusePolicy poolReusePolicy;
|
||||
private ConnPoolListener<HttpRoute> connPoolListener;
|
||||
|
||||
private boolean systemProperties;
|
||||
|
@ -116,10 +116,10 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link ConnPoolPolicy} value.
|
||||
* Assigns {@link PoolReusePolicy} value.
|
||||
*/
|
||||
public final PoolingAsyncClientConnectionManagerBuilder setConnPoolPolicy(final ConnPoolPolicy connPoolPolicy) {
|
||||
this.connPoolPolicy = connPoolPolicy;
|
||||
public final PoolingAsyncClientConnectionManagerBuilder setConnPoolPolicy(final PoolReusePolicy connPoolPolicy) {
|
||||
this.poolReusePolicy = poolReusePolicy;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
schemePortResolver,
|
||||
dnsResolver,
|
||||
timeToLive,
|
||||
connPoolPolicy,
|
||||
poolReusePolicy,
|
||||
connPoolListener);
|
||||
poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);
|
||||
if (maxConnTotal > 0) {
|
||||
|
|
|
@ -35,24 +35,24 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
|
|||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
|
||||
/**
|
||||
* A generic {@link ResponseHandler} that works with the response entity
|
||||
* A generic {@link HttpClientResponseHandler} that works with the response entity
|
||||
* for successful (2xx) responses. If the response code was >= 300, the response
|
||||
* body is consumed and an {@link HttpResponseException} is thrown.
|
||||
* <p>
|
||||
* If this is used with
|
||||
* {@link org.apache.hc.client5.http.sync.HttpClient#execute(org.apache.hc.core5.http.ClassicHttpRequest,
|
||||
* ResponseHandler)},
|
||||
* HttpClientResponseHandler)},
|
||||
* HttpClient may handle redirects (3xx responses) internally.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Contract(threading = ThreadingBehavior.IMMUTABLE)
|
||||
public abstract class AbstractResponseHandler<T> implements ResponseHandler<T> {
|
||||
public abstract class AbstractHttpClientResponseHandler<T> implements HttpClientResponseHandler<T> {
|
||||
|
||||
/**
|
||||
* Read the entity from the response body and pass it to the entity handler
|
|
@ -38,20 +38,20 @@ import org.apache.hc.core5.http.ParseException;
|
|||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
|
||||
/**
|
||||
* A {@link org.apache.hc.core5.http.io.ResponseHandler} that returns the response body as a String
|
||||
* A {@link org.apache.hc.core5.http.io.HttpClientResponseHandler} that returns the response body as a String
|
||||
* for successful (2xx) responses. If the response code was >= 300, the response
|
||||
* body is consumed and an {@link org.apache.hc.client5.http.protocol.HttpResponseException} is thrown.
|
||||
* <p>
|
||||
* If this is used with
|
||||
* {@link org.apache.hc.client5.http.sync.HttpClient#execute(
|
||||
* org.apache.hc.core5.http.ClassicHttpRequest, org.apache.hc.core5.http.io.ResponseHandler)},
|
||||
* org.apache.hc.core5.http.ClassicHttpRequest, org.apache.hc.core5.http.io.HttpClientResponseHandler)},
|
||||
* HttpClient may handle redirects (3xx responses) internally.
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
@Contract(threading = ThreadingBehavior.IMMUTABLE)
|
||||
public class BasicResponseHandler extends AbstractResponseHandler<String> {
|
||||
public class BasicHttpClientResponseHandler extends AbstractHttpClientResponseHandler<String> {
|
||||
|
||||
/**
|
||||
* Returns the entity as a body as a String.
|
|
@ -41,7 +41,7 @@ import org.apache.hc.core5.http.ClassicHttpRequest;
|
|||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
|
@ -126,11 +126,11 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
* response using the given response handler. The content entity associated
|
||||
* with the response is fully consumed and the underlying connection is
|
||||
* released back to the connection manager automatically in all cases
|
||||
* relieving individual {@link ResponseHandler}s from having to manage
|
||||
* relieving individual {@link HttpClientResponseHandler}s from having to manage
|
||||
* resource deallocation internally.
|
||||
*
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
*
|
||||
* @return the response object as generated by the response handler.
|
||||
* @throws IOException in case of a problem or the connection was aborted
|
||||
|
@ -138,8 +138,8 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
*/
|
||||
@Override
|
||||
public <T> T execute(final ClassicHttpRequest request,
|
||||
final ResponseHandler<? extends T> responseHandler) throws IOException {
|
||||
return execute(request, responseHandler, null);
|
||||
final HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException {
|
||||
return execute(request, HttpClientResponseHandler, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,11 +147,11 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
* response using the given response handler. The content entity associated
|
||||
* with the response is fully consumed and the underlying connection is
|
||||
* released back to the connection manager automatically in all cases
|
||||
* relieving individual {@link ResponseHandler}s from having to manage
|
||||
* relieving individual {@link HttpClientResponseHandler}s from having to manage
|
||||
* resource deallocation internally.
|
||||
*
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
* @param context the context to use for the execution, or
|
||||
* {@code null} to use the default context
|
||||
*
|
||||
|
@ -161,10 +161,10 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
*/
|
||||
@Override
|
||||
public <T> T execute(final ClassicHttpRequest request,
|
||||
final ResponseHandler<? extends T> responseHandler, final HttpContext context)
|
||||
final HttpClientResponseHandler<? extends T> HttpClientResponseHandler, final HttpContext context)
|
||||
throws IOException {
|
||||
final HttpHost target = determineTarget(request);
|
||||
return execute(target, request, responseHandler, context);
|
||||
return execute(target, request, HttpClientResponseHandler, context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,7 +172,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
* response using the given response handler. The content entity associated
|
||||
* with the response is fully consumed and the underlying connection is
|
||||
* released back to the connection manager automatically in all cases
|
||||
* relieving individual {@link ResponseHandler}s from having to manage
|
||||
* relieving individual {@link HttpClientResponseHandler}s from having to manage
|
||||
* resource deallocation internally.
|
||||
*
|
||||
* @param target the target host for the request.
|
||||
|
@ -180,7 +180,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
* if they can still determine a route, for example
|
||||
* to a default target or by inspecting the request.
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
*
|
||||
* @return the response object as generated by the response handler.
|
||||
* @throws IOException in case of a problem or the connection was aborted
|
||||
|
@ -188,8 +188,8 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
*/
|
||||
@Override
|
||||
public <T> T execute(final HttpHost target, final ClassicHttpRequest request,
|
||||
final ResponseHandler<? extends T> responseHandler) throws IOException {
|
||||
return execute(target, request, responseHandler, null);
|
||||
final HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException {
|
||||
return execute(target, request, HttpClientResponseHandler, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,7 +197,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
* response using the given response handler. The content entity associated
|
||||
* with the response is fully consumed and the underlying connection is
|
||||
* released back to the connection manager automatically in all cases
|
||||
* relieving individual {@link ResponseHandler}s from having to manage
|
||||
* relieving individual {@link HttpClientResponseHandler}s from having to manage
|
||||
* resource deallocation internally.
|
||||
*
|
||||
* @param target the target host for the request.
|
||||
|
@ -205,7 +205,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
* if they can still determine a route, for example
|
||||
* to a default target or by inspecting the request.
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
* @param context the context to use for the execution, or
|
||||
* {@code null} to use the default context
|
||||
*
|
||||
|
@ -215,12 +215,12 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
|
|||
*/
|
||||
@Override
|
||||
public <T> T execute(final HttpHost target, final ClassicHttpRequest request,
|
||||
final ResponseHandler<? extends T> responseHandler, final HttpContext context) throws IOException {
|
||||
Args.notNull(responseHandler, "Response handler");
|
||||
final HttpClientResponseHandler<? extends T> HttpClientResponseHandler, final HttpContext context) throws IOException {
|
||||
Args.notNull(HttpClientResponseHandler, "Response handler");
|
||||
|
||||
try (final CloseableHttpResponse response = execute(target, request, context)) {
|
||||
try {
|
||||
final T result = responseHandler.handleResponse(response);
|
||||
final T result = HttpClientResponseHandler.handleResponse(response);
|
||||
final HttpEntity entity = response.getEntity();
|
||||
EntityUtils.consume(entity);
|
||||
return result;
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.apache.hc.core5.annotation.Contract;
|
|||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
|
@ -78,15 +78,15 @@ public class FutureRequestExecutionService implements Closeable {
|
|||
*
|
||||
* @param request
|
||||
* request to execute
|
||||
* @param responseHandler
|
||||
* @param HttpClientResponseHandler
|
||||
* handler that will process the response.
|
||||
* @return HttpAsyncClientFutureTask for the scheduled request.
|
||||
*/
|
||||
public <T> HttpRequestFutureTask<T> execute(
|
||||
final ClassicHttpRequest request,
|
||||
final HttpContext context,
|
||||
final ResponseHandler<T> responseHandler) {
|
||||
return execute(request, context, responseHandler, null);
|
||||
final HttpClientResponseHandler<T> HttpClientResponseHandler) {
|
||||
return execute(request, context, HttpClientResponseHandler, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +98,7 @@ public class FutureRequestExecutionService implements Closeable {
|
|||
* request to execute
|
||||
* @param context
|
||||
* optional context; use null if not needed.
|
||||
* @param responseHandler
|
||||
* @param HttpClientResponseHandler
|
||||
* handler that will process the response.
|
||||
* @param callback
|
||||
* callback handler that will be called when the request is scheduled,
|
||||
|
@ -108,14 +108,14 @@ public class FutureRequestExecutionService implements Closeable {
|
|||
public <T> HttpRequestFutureTask<T> execute(
|
||||
final ClassicHttpRequest request,
|
||||
final HttpContext context,
|
||||
final ResponseHandler<T> responseHandler,
|
||||
final HttpClientResponseHandler<T> HttpClientResponseHandler,
|
||||
final FutureCallback<T> callback) {
|
||||
if(closed.get()) {
|
||||
throw new IllegalStateException("Close has been called on this httpclient instance.");
|
||||
}
|
||||
metrics.getScheduledConnections().incrementAndGet();
|
||||
final HttpRequestTaskCallable<T> callable = new HttpRequestTaskCallable<>(
|
||||
httpclient, request, context, responseHandler, callback, metrics);
|
||||
httpclient, request, context, HttpClientResponseHandler, callback, metrics);
|
||||
final HttpRequestFutureTask<T> httpRequestFutureTask = new HttpRequestFutureTask<>(
|
||||
request, callable);
|
||||
executorService.execute(httpRequestFutureTask);
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.apache.hc.client5.http.impl.DefaultConnectionKeepAliveStrategy;
|
|||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
|
||||
import org.apache.hc.client5.http.impl.DefaultUserTokenHandler;
|
||||
import org.apache.hc.client5.http.impl.IdleConnectionEvictor;
|
||||
import org.apache.hc.client5.http.impl.NamedElementChain;
|
||||
import org.apache.hc.client5.http.impl.NoopUserTokenHandler;
|
||||
import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
|
||||
import org.apache.hc.client5.http.impl.auth.CredSspSchemeFactory;
|
||||
|
@ -93,6 +92,7 @@ import org.apache.hc.core5.http.HttpRequestInterceptor;
|
|||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.config.NamedElementChain;
|
||||
import org.apache.hc.core5.http.config.Registry;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
||||
|
|
|
@ -32,7 +32,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import org.apache.hc.client5.http.sync.HttpClient;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
|
||||
class HttpRequestTaskCallable<V> implements Callable<V> {
|
||||
|
@ -46,7 +46,7 @@ class HttpRequestTaskCallable<V> implements Callable<V> {
|
|||
private long ended = -1;
|
||||
|
||||
private final HttpContext context;
|
||||
private final ResponseHandler<V> responseHandler;
|
||||
private final HttpClientResponseHandler<V> responseHandler;
|
||||
private final FutureCallback<V> callback;
|
||||
|
||||
private final FutureRequestExecutionMetrics metrics;
|
||||
|
@ -55,7 +55,7 @@ class HttpRequestTaskCallable<V> implements Callable<V> {
|
|||
final HttpClient httpClient,
|
||||
final ClassicHttpRequest request,
|
||||
final HttpContext context,
|
||||
final ResponseHandler<V> responseHandler,
|
||||
final HttpClientResponseHandler<V> responseHandler,
|
||||
final FutureCallback<V> callback,
|
||||
final FutureRequestExecutionMetrics metrics) {
|
||||
this.httpclient = httpClient;
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.hc.core5.concurrent.FutureCallback;
|
|||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.reactor.ConnectionInitiator;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Represents a manager of persistent non-blocking client connections.
|
||||
|
@ -76,7 +77,7 @@ public interface AsyncClientConnectionManager extends Closeable {
|
|||
Future<AsyncConnectionEndpoint> lease(
|
||||
HttpRoute route,
|
||||
Object state,
|
||||
TimeValue timeout,
|
||||
Timeout timeout,
|
||||
FutureCallback<AsyncConnectionEndpoint> callback);
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.apache.hc.core5.http.ClassicHttpRequest;
|
|||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
|
||||
/**
|
||||
|
@ -121,17 +121,17 @@ public interface HttpClient {
|
|||
* Implementing classes are required to ensure that the content entity
|
||||
* associated with the response is fully consumed and the underlying
|
||||
* connection is released back to the connection manager automatically
|
||||
* in all cases relieving individual {@link ResponseHandler}s from
|
||||
* in all cases relieving individual {@link HttpClientResponseHandler}s from
|
||||
* having to manage resource deallocation internally.
|
||||
* </p>
|
||||
*
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
*
|
||||
* @return the response object as generated by the response handler.
|
||||
* @throws IOException in case of a problem or the connection was aborted
|
||||
*/
|
||||
<T> T execute(ClassicHttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException;
|
||||
<T> T execute(ClassicHttpRequest request, HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException;
|
||||
|
||||
/**
|
||||
* Executes HTTP request using the given context and processes the
|
||||
|
@ -140,19 +140,19 @@ public interface HttpClient {
|
|||
* Implementing classes are required to ensure that the content entity
|
||||
* associated with the response is fully consumed and the underlying
|
||||
* connection is released back to the connection manager automatically
|
||||
* in all cases relieving individual {@link ResponseHandler}s from
|
||||
* in all cases relieving individual {@link HttpClientResponseHandler}s from
|
||||
* having to manage resource deallocation internally.
|
||||
* </p>
|
||||
*
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
* @param context the context to use for the execution, or
|
||||
* {@code null} to use the default context
|
||||
*
|
||||
* @return the response object as generated by the response handler.
|
||||
* @throws IOException in case of a problem or the connection was aborted
|
||||
*/
|
||||
<T> T execute(ClassicHttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException;
|
||||
<T> T execute(ClassicHttpRequest request, HttpClientResponseHandler<? extends T> HttpClientResponseHandler, HttpContext context) throws IOException;
|
||||
|
||||
/**
|
||||
* Executes HTTP request to the target using the default context and
|
||||
|
@ -161,7 +161,7 @@ public interface HttpClient {
|
|||
* Implementing classes are required to ensure that the content entity
|
||||
* associated with the response is fully consumed and the underlying
|
||||
* connection is released back to the connection manager automatically
|
||||
* in all cases relieving individual {@link ResponseHandler}s from
|
||||
* in all cases relieving individual {@link HttpClientResponseHandler}s from
|
||||
* having to manage resource deallocation internally.
|
||||
* </p>
|
||||
*
|
||||
|
@ -170,12 +170,12 @@ public interface HttpClient {
|
|||
* if they can still determine a route, for example
|
||||
* to a default target or by inspecting the request.
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
*
|
||||
* @return the response object as generated by the response handler.
|
||||
* @throws IOException in case of a problem or the connection was aborted
|
||||
*/
|
||||
<T> T execute(HttpHost target, ClassicHttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException;
|
||||
<T> T execute(HttpHost target, ClassicHttpRequest request, HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException;
|
||||
|
||||
/**
|
||||
* Executes HTTP request to the target using the given context and
|
||||
|
@ -184,7 +184,7 @@ public interface HttpClient {
|
|||
* Implementing classes are required to ensure that the content entity
|
||||
* associated with the response is fully consumed and the underlying
|
||||
* connection is released back to the connection manager automatically
|
||||
* in all cases relieving individual {@link ResponseHandler}s from
|
||||
* in all cases relieving individual {@link HttpClientResponseHandler}s from
|
||||
* having to manage resource deallocation internally.
|
||||
* </p>
|
||||
*
|
||||
|
@ -193,7 +193,7 @@ public interface HttpClient {
|
|||
* if they can still determine a route, for example
|
||||
* to a default target or by inspecting the request.
|
||||
* @param request the request to execute
|
||||
* @param responseHandler the response handler
|
||||
* @param HttpClientResponseHandler the response handler
|
||||
* @param context the context to use for the execution, or
|
||||
* {@code null} to use the default context
|
||||
*
|
||||
|
@ -203,7 +203,7 @@ public interface HttpClient {
|
|||
<T> T execute(
|
||||
HttpHost target,
|
||||
ClassicHttpRequest request,
|
||||
ResponseHandler<? extends T> responseHandler,
|
||||
HttpClientResponseHandler<? extends T> HttpClientResponseHandler,
|
||||
HttpContext context) throws IOException;
|
||||
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public class URIUtils {
|
|||
uribuilder.setPort(target.getPort());
|
||||
} else {
|
||||
uribuilder.setScheme(null);
|
||||
uribuilder.setHost(null);
|
||||
uribuilder.setHost((String) null);
|
||||
uribuilder.setPort(-1);
|
||||
}
|
||||
if (dropFragment) {
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -47,9 +48,9 @@ public class TestRequestConfig {
|
|||
@Test
|
||||
public void testDefaults() {
|
||||
final RequestConfig config = RequestConfig.DEFAULT;
|
||||
Assert.assertEquals(TimeValue.NEG_ONE_MILLISECONDS, config.getSocketTimeout());
|
||||
Assert.assertEquals(TimeValue.ofMinutes(3), config.getConnectTimeout());
|
||||
Assert.assertEquals(TimeValue.ofMinutes(3), config.getConnectionRequestTimeout());
|
||||
Assert.assertEquals(Timeout.ZERO_MILLISECONDS, config.getSocketTimeout());
|
||||
Assert.assertEquals(Timeout.ofMinutes(3), config.getConnectTimeout());
|
||||
Assert.assertEquals(Timeout.ofMinutes(3), config.getConnectionRequestTimeout());
|
||||
Assert.assertEquals(false, config.isExpectContinueEnabled());
|
||||
Assert.assertEquals(true, config.isAuthenticationEnabled());
|
||||
Assert.assertEquals(true, config.isRedirectsEnabled());
|
||||
|
|
|
@ -30,8 +30,8 @@ package org.apache.hc.client5.http.impl;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.hc.client5.http.impl.sync.AbstractResponseHandler;
|
||||
import org.apache.hc.client5.http.impl.sync.BasicResponseHandler;
|
||||
import org.apache.hc.client5.http.impl.sync.AbstractHttpClientResponseHandler;
|
||||
import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
|
||||
import org.apache.hc.client5.http.protocol.HttpResponseException;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
|
@ -42,9 +42,9 @@ import org.junit.Test;
|
|||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BasicResponseHandler}.
|
||||
* Unit tests for {@link BasicHttpClientResponseHandler}.
|
||||
*/
|
||||
public class TestAbstractResponseHandler {
|
||||
public class TestAbstractHttpClientResponseHandler {
|
||||
|
||||
@Test
|
||||
public void testSuccessfulResponse() throws Exception {
|
||||
|
@ -53,7 +53,7 @@ public class TestAbstractResponseHandler {
|
|||
Mockito.when(response.getCode()).thenReturn(200);
|
||||
Mockito.when(response.getEntity()).thenReturn(entity);
|
||||
|
||||
final AbstractResponseHandler<Integer> handler = new AbstractResponseHandler<Integer>() {
|
||||
final AbstractHttpClientResponseHandler<Integer> handler = new AbstractHttpClientResponseHandler<Integer>() {
|
||||
|
||||
@Override
|
||||
public Integer handleEntity(final HttpEntity entity) throws IOException {
|
||||
|
@ -75,7 +75,7 @@ public class TestAbstractResponseHandler {
|
|||
Mockito.when(response.getCode()).thenReturn(404);
|
||||
Mockito.when(response.getEntity()).thenReturn(entity);
|
||||
|
||||
final BasicResponseHandler handler = new BasicResponseHandler();
|
||||
final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
|
||||
try {
|
||||
handler.handleResponse(response);
|
||||
Assert.fail("HttpResponseException expected");
|
|
@ -29,7 +29,7 @@ package org.apache.hc.client5.http.impl;
|
|||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.hc.client5.http.impl.sync.BasicResponseHandler;
|
||||
import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
|
||||
import org.apache.hc.client5.http.protocol.HttpResponseException;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
|
@ -39,7 +39,7 @@ import org.junit.Test;
|
|||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BasicResponseHandler}.
|
||||
* Unit tests for {@link BasicHttpClientResponseHandler}.
|
||||
*/
|
||||
@SuppressWarnings("boxing") // test code
|
||||
public class TestBasicResponseHandler {
|
||||
|
@ -51,7 +51,7 @@ public class TestBasicResponseHandler {
|
|||
Mockito.when(response.getCode()).thenReturn(200);
|
||||
Mockito.when(response.getEntity()).thenReturn(entity);
|
||||
|
||||
final BasicResponseHandler handler = new BasicResponseHandler();
|
||||
final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
|
||||
final String s = handler.handleResponse(response);
|
||||
Assert.assertEquals("stuff", s);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class TestBasicResponseHandler {
|
|||
Mockito.when(response.getCode()).thenReturn(404);
|
||||
Mockito.when(response.getEntity()).thenReturn(entity);
|
||||
|
||||
final BasicResponseHandler handler = new BasicResponseHandler();
|
||||
final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
|
||||
try {
|
||||
handler.handleResponse(response);
|
||||
Assert.fail("HttpResponseException expected");
|
||||
|
|
|
@ -1,97 +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.http.impl;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link NamedElementChain}.
|
||||
*/
|
||||
public class TestNamedElementChain {
|
||||
|
||||
@Test
|
||||
public void testBasics() {
|
||||
final NamedElementChain<Character> list = new NamedElementChain<>();
|
||||
Assert.assertThat(list.getFirst(), CoreMatchers.nullValue());
|
||||
Assert.assertThat(list.getLast(), CoreMatchers.nullValue());
|
||||
|
||||
final NamedElementChain<Character>.Node nodeA = list.addFirst('a', "a");
|
||||
|
||||
Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeA));
|
||||
Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeA));
|
||||
|
||||
final NamedElementChain<Character>.Node nodeB = list.addLast('b', "b");
|
||||
|
||||
Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeA));
|
||||
Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeB));
|
||||
|
||||
final NamedElementChain<Character>.Node nodeZ = list.addLast('z', "z");
|
||||
|
||||
Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeA));
|
||||
Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeZ));
|
||||
|
||||
Assert.assertThat(nodeA.getPrevious(), CoreMatchers.nullValue());
|
||||
Assert.assertThat(nodeA.getNext(), CoreMatchers.sameInstance(nodeB));
|
||||
Assert.assertThat(nodeB.getPrevious(), CoreMatchers.sameInstance(nodeA));
|
||||
Assert.assertThat(nodeB.getNext(), CoreMatchers.sameInstance(nodeZ));
|
||||
Assert.assertThat(nodeZ.getPrevious(), CoreMatchers.sameInstance(nodeB));
|
||||
Assert.assertThat(nodeZ.getNext(), CoreMatchers.nullValue());
|
||||
|
||||
final NamedElementChain<Character>.Node nodeD = list.addAfter("b", 'd', "d");
|
||||
Assert.assertThat(nodeD.getPrevious(), CoreMatchers.sameInstance(nodeB));
|
||||
Assert.assertThat(nodeD.getNext(), CoreMatchers.sameInstance(nodeZ));
|
||||
Assert.assertThat(nodeB.getNext(), CoreMatchers.sameInstance(nodeD));
|
||||
Assert.assertThat(nodeZ.getPrevious(), CoreMatchers.sameInstance(nodeD));
|
||||
|
||||
final NamedElementChain<Character>.Node nodeC = list.addBefore("d", 'c', "c");
|
||||
Assert.assertThat(nodeC.getPrevious(), CoreMatchers.sameInstance(nodeB));
|
||||
Assert.assertThat(nodeC.getNext(), CoreMatchers.sameInstance(nodeD));
|
||||
Assert.assertThat(nodeB.getNext(), CoreMatchers.sameInstance(nodeC));
|
||||
Assert.assertThat(nodeD.getPrevious(), CoreMatchers.sameInstance(nodeC));
|
||||
Assert.assertThat(list.getSize(), CoreMatchers.equalTo(5));
|
||||
|
||||
Assert.assertThat(list.remove("a"), CoreMatchers.is(true));
|
||||
Assert.assertThat(list.remove("z"), CoreMatchers.is(true));
|
||||
Assert.assertThat(list.remove("c"), CoreMatchers.is(true));
|
||||
Assert.assertThat(list.remove("c"), CoreMatchers.is(false));
|
||||
Assert.assertThat(list.remove("blah"), CoreMatchers.is(false));
|
||||
|
||||
Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeB));
|
||||
Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeD));
|
||||
|
||||
Assert.assertThat(list.getSize(), CoreMatchers.equalTo(2));
|
||||
Assert.assertThat(list.addBefore("blah", 'e', "e"), CoreMatchers.nullValue());
|
||||
Assert.assertThat(list.getSize(), CoreMatchers.equalTo(2));
|
||||
|
||||
Assert.assertThat(list.addAfter("yada", 'e', "e"), CoreMatchers.nullValue());
|
||||
Assert.assertThat(list.getSize(), CoreMatchers.equalTo(2));
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,7 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
|
|||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
@ -119,7 +119,7 @@ public class TestCloseableHttpClient {
|
|||
Mockito.when(client.doExecute(
|
||||
new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
|
||||
|
||||
final ResponseHandler<HttpResponse> handler = Mockito.mock(ResponseHandler.class);
|
||||
final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
|
||||
|
||||
client.execute(httpget, handler);
|
||||
|
||||
|
@ -139,7 +139,7 @@ public class TestCloseableHttpClient {
|
|||
Mockito.when(client.doExecute(
|
||||
new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
|
||||
|
||||
final ResponseHandler<HttpResponse> handler = Mockito.mock(ResponseHandler.class);
|
||||
final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
|
||||
|
||||
Mockito.when(handler.handleResponse(response)).thenThrow(new IOException());
|
||||
|
||||
|
@ -163,7 +163,7 @@ public class TestCloseableHttpClient {
|
|||
Mockito.when(client.doExecute(
|
||||
new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
|
||||
|
||||
final ResponseHandler<HttpResponse> handler = Mockito.mock(ResponseHandler.class);
|
||||
final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
|
||||
|
||||
Mockito.when(handler.handleResponse(response)).thenThrow(new RuntimeException());
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
|
|||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
||||
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||
import org.apache.hc.core5.http.io.ResponseHandler;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
|
@ -69,7 +69,7 @@ public class TestFutureRequestExecutionService {
|
|||
@Before
|
||||
public void before() throws Exception {
|
||||
this.localServer = ServerBootstrap.bootstrap()
|
||||
.registerHandler("/wait", new HttpRequestHandler() {
|
||||
.register("/wait", new HttpRequestHandler() {
|
||||
|
||||
@Override
|
||||
public void handle(
|
||||
|
@ -190,7 +190,7 @@ public class TestFutureRequestExecutionService {
|
|||
}
|
||||
|
||||
|
||||
private final class OkidokiHandler implements ResponseHandler<Boolean> {
|
||||
private final class OkidokiHandler implements HttpClientResponseHandler<Boolean> {
|
||||
@Override
|
||||
public Boolean handleResponse(
|
||||
final ClassicHttpResponse response) throws IOException {
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -68,7 +68,7 @@
|
|||
<properties>
|
||||
<maven.compiler.source>1.7</maven.compiler.source>
|
||||
<maven.compiler.target>1.7</maven.compiler.target>
|
||||
<httpcore.version>5.0-alpha3</httpcore.version>
|
||||
<httpcore.version>5.0-alpha4</httpcore.version>
|
||||
<log4j.version>2.8.2</log4j.version>
|
||||
<commons-codec.version>1.10</commons-codec.version>
|
||||
<ehcache.version>2.6.11</ehcache.version>
|
||||
|
|
Loading…
Reference in New Issue