CloseableHttpAsyncClient to support explicit HttpHost execution parameter
This commit is contained in:
parent
d0541123c2
commit
f3c418c50a
|
@ -33,6 +33,7 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
|
|||
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.http.HttpHost;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
||||
|
@ -52,7 +53,8 @@ abstract class AbstractMinimalHttpAsyncClientBase extends AbstractHttpAsyncClien
|
|||
}
|
||||
|
||||
@Override
|
||||
public final <T> Future<T> execute(
|
||||
protected <T> Future<T> doExecute(
|
||||
final HttpHost httphost,
|
||||
final AsyncRequestProducer requestProducer,
|
||||
final AsyncResponseConsumer<T> responseConsumer,
|
||||
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
|
||||
|
|
|
@ -39,9 +39,11 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
|
|||
import org.apache.hc.core5.concurrent.BasicFuture;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.function.Supplier;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||
import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
||||
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
|
||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.io.CloseMode;
|
||||
import org.apache.hc.core5.io.ModalCloseable;
|
||||
|
@ -73,11 +75,45 @@ public abstract class CloseableHttpAsyncClient implements HttpAsyncClient, Modal
|
|||
close(closeMode);
|
||||
}
|
||||
|
||||
protected abstract <T> Future<T> doExecute(
|
||||
final HttpHost target,
|
||||
final AsyncRequestProducer requestProducer,
|
||||
final AsyncResponseConsumer<T> responseConsumer,
|
||||
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
|
||||
final HttpContext context,
|
||||
final FutureCallback<T> callback);
|
||||
|
||||
public final <T> Future<T> execute(
|
||||
final HttpHost target,
|
||||
final AsyncRequestProducer requestProducer,
|
||||
final AsyncResponseConsumer<T> responseConsumer,
|
||||
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
|
||||
final HttpContext context,
|
||||
final FutureCallback<T> callback) {
|
||||
Args.notNull(requestProducer, "Request producer");
|
||||
Args.notNull(responseConsumer, "Response consumer");
|
||||
return doExecute(target, requestProducer, responseConsumer, pushHandlerFactory, context, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> Future<T> execute(
|
||||
final AsyncRequestProducer requestProducer,
|
||||
final AsyncResponseConsumer<T> responseConsumer,
|
||||
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
|
||||
final HttpContext context,
|
||||
final FutureCallback<T> callback) {
|
||||
Args.notNull(requestProducer, "Request producer");
|
||||
Args.notNull(responseConsumer, "Response consumer");
|
||||
return doExecute(null, requestProducer, responseConsumer, pushHandlerFactory, context, callback);
|
||||
}
|
||||
|
||||
public final <T> Future<T> execute(
|
||||
final AsyncRequestProducer requestProducer,
|
||||
final AsyncResponseConsumer<T> responseConsumer,
|
||||
final HttpContext context,
|
||||
final FutureCallback<T> callback) {
|
||||
Args.notNull(requestProducer, "Request producer");
|
||||
Args.notNull(responseConsumer, "Response consumer");
|
||||
return execute(requestProducer, responseConsumer, null, context, callback);
|
||||
}
|
||||
|
||||
|
@ -85,6 +121,8 @@ public abstract class CloseableHttpAsyncClient implements HttpAsyncClient, Modal
|
|||
final AsyncRequestProducer requestProducer,
|
||||
final AsyncResponseConsumer<T> responseConsumer,
|
||||
final FutureCallback<T> callback) {
|
||||
Args.notNull(requestProducer, "Request producer");
|
||||
Args.notNull(responseConsumer, "Response consumer");
|
||||
return execute(requestProducer, responseConsumer, HttpClientContext.create(), callback);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,10 +48,12 @@ import org.apache.hc.client5.http.cookie.CookieStore;
|
|||
import org.apache.hc.client5.http.impl.ExecSupport;
|
||||
import org.apache.hc.client5.http.impl.RequestCopier;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.routing.RoutingSupport;
|
||||
import org.apache.hc.core5.concurrent.ComplexFuture;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
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.HttpResponse;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
|
@ -138,10 +140,11 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
|
|||
|
||||
abstract AsyncExecRuntime createAsyncExecRuntime(HandlerFactory<AsyncPushConsumer> pushHandlerFactory);
|
||||
|
||||
abstract HttpRoute determineRoute(HttpRequest request, HttpClientContext clientContext) throws HttpException;
|
||||
abstract HttpRoute determineRoute(HttpHost httpHost, HttpClientContext clientContext) throws HttpException;
|
||||
|
||||
@Override
|
||||
public <T> Future<T> execute(
|
||||
protected <T> Future<T> doExecute(
|
||||
final HttpHost httpHost,
|
||||
final AsyncRequestProducer requestProducer,
|
||||
final AsyncResponseConsumer<T> responseConsumer,
|
||||
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory,
|
||||
|
@ -150,7 +153,7 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
|
|||
ensureRunning();
|
||||
final ComplexFuture<T> future = new ComplexFuture<>(callback);
|
||||
try {
|
||||
final HttpClientContext clientContext = HttpClientContext.adapt(context);
|
||||
final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
|
||||
requestProducer.sendRequest(new RequestChannel() {
|
||||
|
||||
@Override
|
||||
|
@ -166,7 +169,9 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
|
|||
if (requestConfig != null) {
|
||||
clientContext.setRequestConfig(requestConfig);
|
||||
}
|
||||
final HttpRoute route = determineRoute(request, clientContext);
|
||||
final HttpRoute route = determineRoute(
|
||||
httpHost != null ? httpHost : RoutingSupport.determineHost(request),
|
||||
clientContext);
|
||||
final String exchangeId = ExecSupport.getNextExchangeId();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(exchangeId + ": preparing request execution");
|
||||
|
|
|
@ -39,12 +39,11 @@ import org.apache.hc.client5.http.cookie.CookieSpecProvider;
|
|||
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
|
||||
import org.apache.hc.client5.http.routing.RoutingSupport;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
||||
|
@ -93,8 +92,8 @@ public final class InternalH2AsyncClient extends InternalAbstractHttpAsyncClient
|
|||
}
|
||||
|
||||
@Override
|
||||
HttpRoute determineRoute(final HttpRequest request, final HttpClientContext clientContext) throws HttpException {
|
||||
final HttpRoute route = routePlanner.determineRoute(RoutingSupport.determineHost(request), clientContext);
|
||||
HttpRoute determineRoute(final HttpHost httpHost, final HttpClientContext clientContext) throws HttpException {
|
||||
final HttpRoute route = routePlanner.determineRoute(httpHost, clientContext);
|
||||
if (route.isTunnelled()) {
|
||||
throw new HttpException("HTTP/2 tunneling not supported");
|
||||
}
|
||||
|
|
|
@ -40,12 +40,11 @@ import org.apache.hc.client5.http.cookie.CookieStore;
|
|||
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
|
||||
import org.apache.hc.client5.http.routing.RoutingSupport;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpVersion;
|
||||
import org.apache.hc.core5.http.ProtocolVersion;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
|
@ -100,8 +99,8 @@ public final class InternalHttpAsyncClient extends InternalAbstractHttpAsyncClie
|
|||
}
|
||||
|
||||
@Override
|
||||
HttpRoute determineRoute(final HttpRequest request, final HttpClientContext clientContext) throws HttpException {
|
||||
final HttpRoute route = routePlanner.determineRoute(RoutingSupport.determineHost(request), clientContext);
|
||||
HttpRoute determineRoute(final HttpHost httpHost, final HttpClientContext clientContext) throws HttpException {
|
||||
final HttpRoute route = routePlanner.determineRoute(httpHost, clientContext);
|
||||
final ProtocolVersion protocolVersion = clientContext.getProtocolVersion();
|
||||
if (route.isTunnelled() && protocolVersion.greaterEquals(HttpVersion.HTTP_2_0)) {
|
||||
throw new HttpException("HTTP/2 tunneling not supported");
|
||||
|
|
|
@ -28,12 +28,10 @@
|
|||
package org.apache.hc.client5.http.impl.classic;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.hc.client5.http.ClientProtocolException;
|
||||
import org.apache.hc.client5.http.classic.HttpClient;
|
||||
import org.apache.hc.client5.http.utils.URIUtils;
|
||||
import org.apache.hc.client5.http.routing.RoutingSupport;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
|
@ -78,22 +76,11 @@ public abstract class CloseableHttpClient implements HttpClient, ModalCloseable
|
|||
}
|
||||
|
||||
private static HttpHost determineTarget(final ClassicHttpRequest request) throws ClientProtocolException {
|
||||
// A null target may be acceptable if there is a default target.
|
||||
// Otherwise, the null target is detected in the director.
|
||||
HttpHost target = null;
|
||||
URI requestURI = null;
|
||||
try {
|
||||
requestURI = request.getUri();
|
||||
} catch (final URISyntaxException ignore) {
|
||||
return RoutingSupport.determineHost(request);
|
||||
} catch (final HttpException ex) {
|
||||
throw new ClientProtocolException(ex);
|
||||
}
|
||||
if (requestURI != null && requestURI.isAbsolute()) {
|
||||
target = URIUtils.extractHost(requestURI);
|
||||
if (target == null) {
|
||||
throw new ClientProtocolException("URI does not specify a valid host name: "
|
||||
+ requestURI);
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,8 +26,12 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.routing;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.hc.client5.http.SchemePortResolver;
|
||||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
|
||||
import org.apache.hc.client5.http.utils.URIUtils;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
|
@ -47,6 +51,18 @@ public final class RoutingSupport {
|
|||
throw new ProtocolException("Protocol scheme is not specified");
|
||||
}
|
||||
return new HttpHost(scheme, authority);
|
||||
} else {
|
||||
try {
|
||||
final URI requestURI = request.getUri();
|
||||
if (requestURI.isAbsolute()) {
|
||||
final HttpHost httpHost = URIUtils.extractHost(requestURI);
|
||||
if (httpHost == null) {
|
||||
throw new ProtocolException("URI does not specify a valid host name: " + requestURI);
|
||||
}
|
||||
return httpHost;
|
||||
}
|
||||
} catch (final URISyntaxException ignore) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue