HTTPCLIENT-714: computation of original route moved to director

git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@603965 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Roland Weber 2007-12-13 17:51:03 +00:00
parent be0227d72a
commit 6d57a9d5a8
4 changed files with 107 additions and 83 deletions

View File

@ -33,11 +33,11 @@ package org.apache.http.client;
import java.io.IOException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpException;
import org.apache.http.protocol.HttpContext;
import org.apache.http.conn.HttpRoute; //@@@ replace by HttpTarget
import org.apache.http.conn.ManagedClientConnection;
@ -80,8 +80,11 @@ public interface ClientRequestDirector {
* This is the same behavior as for <code>HttpMethodDirector</code>
* in HttpClient 3.
*
* @param target the target host for the request.
* Implementations may accept <code>null</code>
* 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 route the route to the target of the request
* @param context the context for executing the request
*
* @return the final response to the request.
@ -91,7 +94,7 @@ public interface ClientRequestDirector {
* @throws IOException in case of an IO problem
* @throws InterruptedException in case of an interrupt
*/
HttpResponse execute(HttpRequest request, HttpRoute route,
HttpResponse execute(HttpHost target, HttpRequest request,
HttpContext context)
throws HttpException, IOException, InterruptedException
;

View File

@ -424,9 +424,9 @@ public abstract class AbstractHttpClient implements HttpClient {
/**
* Maps to {@link HttpClient#execute(RoutedRequest,HttpContext)
* execute(roureq, context)}.
* The route is computed by {@link #determineRoute determineRoute}.
* Maps to {@link HttpClient#execute(HttpHost,HttpRequest,HttpContext)
* execute(target, request, context)}.
* The target is determined from the URI of the request.
*
* @param request the request to execute
* @param context the request-specific execution context,
@ -442,7 +442,7 @@ public abstract class AbstractHttpClient implements HttpClient {
}
// A null target may be acceptable if there is a default target.
// Otherwise, the null target is detected in determineRoute().
// Otherwise, the null target is detected in the director.
HttpHost target = null;
URI requestURI = request.getURI();
@ -453,24 +453,17 @@ public abstract class AbstractHttpClient implements HttpClient {
requestURI.getScheme());
}
synchronized (this) {
if (context == null) {
context = new BasicHttpContext(getDefaultContext());
}
}
RoutedRequest roureq = determineRoute(target, request, context);
return execute(roureq, context);
return execute(target, request, context);
}
//@@@ to be removed with HTTPCLIENT-715
public HttpResponse execute(RoutedRequest roureq)
throws HttpException, IOException, InterruptedException {
return execute(roureq, null);
}
// non-javadoc, see interface HttpClient
//@@@ to be removed with HTTPCLIENT-715
public final HttpResponse execute(RoutedRequest roureq,
HttpContext context)
throws HttpException, IOException, InterruptedException {
@ -488,6 +481,26 @@ public abstract class AbstractHttpClient implements HttpClient {
("Route must not be null.");
}
//@@@ this is a temporary violation of the API
//@@@ this method will be removed with HTTPCLIENT-715
return execute(roureq.getRoute().getTargetHost(),
roureq.getRequest(), context);
}
// non-javadoc, see interface HttpClient
//@@@ currently not in interface, will be changed with HTTPCLIENT-715
public final HttpResponse execute(HttpHost target, HttpRequest request,
HttpContext context)
throws HttpException, IOException, InterruptedException {
if (request == null) {
throw new IllegalArgumentException
("Request must not be null.");
}
// a null target may be acceptable, this depends on the route planner
// a null context is acceptable, default context created below
ClientRequestDirector director = null;
// Initialize the request execution context making copies of
@ -500,16 +513,16 @@ public abstract class AbstractHttpClient implements HttpClient {
director = new DefaultClientRequestDirector(
getConnectionManager(),
getConnectionReuseStrategy(),
getRoutePlanner(),
getHttpProcessor().copy(),
getHttpRequestRetryHandler(),
getRedirectHandler(),
getTargetAuthenticationHandler(),
getProxyAuthenticationHandler(),
determineParams(roureq.getRequest()));
determineParams(request));
}
HttpResponse response = director.execute(roureq.getRequest(),
roureq.getRoute(), context);
HttpResponse response = director.execute(target, request, context);
// If the response depends on the connection, the director
// will have set up an auto-release input stream.
@ -542,30 +555,4 @@ public abstract class AbstractHttpClient implements HttpClient {
}
/**
* Determines the route for a request.
* Called by {@link #execute(HttpUriRequest,HttpContext)
* execute(urirequest, context)}
* to map to {@link HttpClient#execute(RoutedRequest,HttpContext)
* execute(roureq, context)}.
*
* @param target the target host for the request.
* Implementations may accept <code>null</code>
* 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 context the context to use for the execution,
* never <code>null</code>
*
* @return the request along with the route it should take
*
* @throws HttpException in case of a problem
*/
protected abstract RoutedRequest determineRoute(HttpHost target,
HttpRequest request,
HttpContext context)
throws HttpException
;
} // class AbstractHttpClient

View File

@ -71,6 +71,7 @@ import org.apache.http.conn.BasicManagedEntity;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.HttpRoute;
import org.apache.http.conn.HttpRoutePlanner;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.HttpRouteDirector;
import org.apache.http.conn.BasicRouteDirector;
@ -108,6 +109,9 @@ public class DefaultClientRequestDirector
/** The connection manager. */
protected final ClientConnectionManager connManager;
/** The route planner. */
protected final HttpRoutePlanner routePlanner;
/** The connection re-use strategy. */
protected final ConnectionReuseStrategy reuseStrategy;
@ -146,6 +150,7 @@ public class DefaultClientRequestDirector
public DefaultClientRequestDirector(
final ClientConnectionManager conman,
final ConnectionReuseStrategy reustrat,
final HttpRoutePlanner rouplan,
final HttpProcessor httpProcessor,
final HttpRequestRetryHandler retryHandler,
final RedirectHandler redirectHandler,
@ -154,31 +159,44 @@ public class DefaultClientRequestDirector
final HttpParams params) {
if (conman == null) {
throw new IllegalArgumentException("Client connection manager may not be null");
throw new IllegalArgumentException
("Client connection manager may not be null.");
}
if (reustrat == null) {
throw new IllegalArgumentException("Connection reuse strategy may not be null");
throw new IllegalArgumentException
("Connection reuse strategy may not be null.");
}
if (rouplan == null) {
throw new IllegalArgumentException
("Route planner may not be null.");
}
if (httpProcessor == null) {
throw new IllegalArgumentException("HTTP protocol processor may not be null");
throw new IllegalArgumentException
("HTTP protocol processor may not be null.");
}
if (retryHandler == null) {
throw new IllegalArgumentException("HTTP request retry handler may not be null");
throw new IllegalArgumentException
("HTTP request retry handler may not be null.");
}
if (redirectHandler == null) {
throw new IllegalArgumentException("Redirect handler may not be null");
throw new IllegalArgumentException
("Redirect handler may not be null.");
}
if (targetAuthHandler == null) {
throw new IllegalArgumentException("Target authentication handler may not be null");
throw new IllegalArgumentException
("Target authentication handler may not be null.");
}
if (proxyAuthHandler == null) {
throw new IllegalArgumentException("Proxy authentication handler may not be null");
throw new IllegalArgumentException
("Proxy authentication handler may not be null.");
}
if (params == null) {
throw new IllegalArgumentException("HTTP parameters may not be null");
throw new IllegalArgumentException
("HTTP parameters may not be null");
}
this.connManager = conman;
this.reuseStrategy = reustrat;
this.routePlanner = rouplan;
this.httpProcessor = httpProcessor;
this.retryHandler = retryHandler;
this.redirectHandler = redirectHandler;
@ -258,11 +276,11 @@ public class DefaultClientRequestDirector
// non-javadoc, see interface ClientRequestDirector
public HttpResponse execute(HttpRequest request, HttpRoute route,
public HttpResponse execute(HttpHost target, HttpRequest request,
HttpContext context)
throws HttpException, IOException, InterruptedException {
RoutedRequest roureq = new RoutedRequest.Impl(request, route);
RoutedRequest roureq = determineRoute(target, request, context);
final HttpRequest orig = request;
@ -279,7 +297,7 @@ public class DefaultClientRequestDirector
// in the method arguments will be replaced. The original
// request is still available in 'orig'.
route = roureq.getRoute();
HttpRoute route = roureq.getRoute();
// Allocate connection if needed
if (managedConn == null) {
@ -316,17 +334,17 @@ public class DefaultClientRequestDirector
// Re-write request URI if needed
rewriteRequestURI(reqwrap, route);
// Use virtual host if set
HttpHost target = (HttpHost) reqwrap.getParams().getParameter(
target = (HttpHost) reqwrap.getParams().getParameter(
ClientPNames.VIRTUAL_HOST);
if (target == null) {
target = route.getTargetHost();
}
HttpHost proxy = route.getProxyHost();
// Populate the execution context
context.setAttribute(ExecutionContext.HTTP_TARGET_HOST,
target);
@ -443,6 +461,44 @@ public class DefaultClientRequestDirector
} // execute
/**
* Determines the route for a request.
* Called by {@link #execute}
* to determine the route for either the original or a followup request.
*
* @param target the target host for the request.
* Implementations may accept <code>null</code>
* 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 context the context to use for the execution,
* never <code>null</code>
*
* @return the request along with the route it should take
*
* @throws HttpException in case of a problem
*/
protected RoutedRequest determineRoute(HttpHost target,
HttpRequest request,
HttpContext context)
throws HttpException {
if (target == null) {
target = (HttpHost) request.getParams().getParameter(
ClientPNames.DEFAULT_HOST);
}
if (target == null) {
throw new IllegalStateException
("Target host must not be null, or set in parameters.");
}
final HttpRoute route =
this.routePlanner.determineRoute(target, request, context);
return new RoutedRequest.Impl(request, route);
}
/**
* Obtains a connection for the target route.
*

View File

@ -285,28 +285,6 @@ public class DefaultHttpClient extends AbstractHttpClient {
}
// non-javadoc, see base class AbstractHttpClient
protected RoutedRequest determineRoute(HttpHost target,
HttpRequest request,
HttpContext context)
throws HttpException {
if (target == null) {
target = (HttpHost) request.getParams().getParameter(
ClientPNames.DEFAULT_HOST);
}
if (target == null) {
throw new IllegalStateException
("Target host must not be null, or set in parameters.");
}
HttpRoute route = getRoutePlanner()
.determineRoute(target, request, context);
return new RoutedRequest.Impl(request, route);
}
// non-javadoc, see base class AbstractHttpClient
protected HttpRoutePlanner createHttpRoutePlanner() {
return new DefaultHttpRoutePlanner(getConnectionManager());