Changelog:
* Removed static instances from SchemeRegistry, CookieSpecRegistry and AuthSchemeRegistry * Made sure there is only one instance of SchemeRegistry per HttpClient / ClientConnectionManager * HostConfiguration, HttpRoute and RouteTracker no longer implement Cloneable as they do not override #clone() method * AbstractHttpClient should now be threading safe * DefaultHttpClient populates HTTP execution context with data required for request execution git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@534769 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9fb978483a
commit
7cda278cd5
|
@ -50,12 +50,6 @@ import org.apache.http.message.BasicHttpRequest;
|
|||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.params.HttpProtocolParams;
|
||||
import org.apache.http.protocol.BasicHttpProcessor;
|
||||
import org.apache.http.protocol.RequestConnControl;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.protocol.RequestExpectContinue;
|
||||
import org.apache.http.protocol.RequestTargetHost;
|
||||
import org.apache.http.protocol.RequestUserAgent;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
|
||||
|
@ -139,16 +133,7 @@ public class ClientExecuteDirect {
|
|||
// new SingleClientConnManager(getParams(), supportedSchemes);
|
||||
|
||||
DefaultHttpClient dhc =
|
||||
new DefaultHttpClient(getParams(), ccm, supportedSchemes);
|
||||
|
||||
BasicHttpProcessor bhp = dhc.getProcessor();
|
||||
// Required protocol interceptors
|
||||
bhp.addInterceptor(new RequestContent());
|
||||
bhp.addInterceptor(new RequestTargetHost());
|
||||
// Recommended protocol interceptors
|
||||
bhp.addInterceptor(new RequestConnControl());
|
||||
bhp.addInterceptor(new RequestUserAgent());
|
||||
bhp.addInterceptor(new RequestExpectContinue());
|
||||
new DefaultHttpClient(ccm, getParams());
|
||||
|
||||
return dhc;
|
||||
}
|
||||
|
|
|
@ -53,12 +53,6 @@ import org.apache.http.message.BasicHttpRequest;
|
|||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.params.HttpProtocolParams;
|
||||
import org.apache.http.protocol.BasicHttpProcessor;
|
||||
import org.apache.http.protocol.RequestConnControl;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.protocol.RequestExpectContinue;
|
||||
import org.apache.http.protocol.RequestTargetHost;
|
||||
import org.apache.http.protocol.RequestUserAgent;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
|
||||
|
@ -151,16 +145,7 @@ public class ClientExecuteProxy {
|
|||
// new SingleClientConnManager(getParams(), supportedSchemes);
|
||||
|
||||
DefaultHttpClient dhc =
|
||||
new DefaultHttpClient(getParams(), ccm, supportedSchemes);
|
||||
|
||||
BasicHttpProcessor bhp = dhc.getProcessor();
|
||||
// Required protocol interceptors
|
||||
bhp.addInterceptor(new RequestContent());
|
||||
bhp.addInterceptor(new RequestTargetHost());
|
||||
// Recommended protocol interceptors
|
||||
bhp.addInterceptor(new RequestConnControl());
|
||||
bhp.addInterceptor(new RequestUserAgent());
|
||||
bhp.addInterceptor(new RequestExpectContinue());
|
||||
new DefaultHttpClient(ccm, getParams());
|
||||
|
||||
return dhc;
|
||||
}
|
||||
|
|
|
@ -35,20 +35,15 @@ import org.apache.http.HttpEntity;
|
|||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.conn.PlainSocketFactory;
|
||||
import org.apache.http.conn.Scheme;
|
||||
import org.apache.http.conn.SchemeRegistry;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.impl.conn.SingleClientConnManager;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.params.HttpProtocolParams;
|
||||
import org.apache.http.protocol.RequestConnControl;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.protocol.RequestExpectContinue;
|
||||
import org.apache.http.protocol.RequestTargetHost;
|
||||
import org.apache.http.protocol.RequestUserAgent;
|
||||
|
||||
/**
|
||||
* How to abort an HTTP method before its normal completion.
|
||||
|
@ -74,19 +69,7 @@ public class MethodAbort {
|
|||
HttpProtocolParams.setContentCharset(params, "UTF-8");
|
||||
HttpProtocolParams.setUserAgent(params, "Jakarta-HttpClient/4.0");
|
||||
|
||||
DefaultHttpClient httpclient = new DefaultHttpClient(
|
||||
params,
|
||||
new SingleClientConnManager(params, supportedSchemes),
|
||||
supportedSchemes);
|
||||
|
||||
// Required protocol interceptors
|
||||
httpclient.getProcessor().addInterceptor(new RequestContent());
|
||||
httpclient.getProcessor().addInterceptor(new RequestTargetHost());
|
||||
// Recommended protocol interceptors
|
||||
httpclient.getProcessor().addInterceptor(new RequestConnControl());
|
||||
httpclient.getProcessor().addInterceptor(new RequestUserAgent());
|
||||
httpclient.getProcessor().addInterceptor(new RequestExpectContinue());
|
||||
|
||||
HttpClient httpclient = new DefaultHttpClient(params);
|
||||
|
||||
HttpHost target = new HttpHost("www.apache.org", 80, "http");
|
||||
|
||||
|
|
|
@ -48,8 +48,6 @@ import org.apache.http.params.HttpParams;
|
|||
*/
|
||||
public final class AuthSchemeRegistry {
|
||||
|
||||
public final static AuthSchemeRegistry DEFAULT = new AuthSchemeRegistry();
|
||||
|
||||
private final Map registeredSchemes = new LinkedHashMap();
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* $HeadURL$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* ====================================================================
|
||||
* 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.http.client.protocol;
|
||||
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.HttpExecutionContext;
|
||||
|
||||
public class HttpClientContext extends HttpExecutionContext {
|
||||
|
||||
public static final String SCHEME_REGISTRY = "http.scheme-registry";
|
||||
public static final String COOKIESPEC_REGISTRY = "http.cookiespec-registry";
|
||||
public static final String AUTHSCHEME_REGISTRY = "http.authscheme-registry";
|
||||
public static final String HTTP_STATE = "http.state";
|
||||
|
||||
public HttpClientContext(final HttpContext parentContext) {
|
||||
super(parentContext);
|
||||
}
|
||||
|
||||
}
|
|
@ -49,6 +49,8 @@ package org.apache.http.conn;
|
|||
*/
|
||||
public interface ClientConnectionManager {
|
||||
|
||||
SchemeRegistry getSchemeRegistry();
|
||||
|
||||
/**
|
||||
* Obtains a connection.
|
||||
* This method will block until a connection becomes available
|
||||
|
|
|
@ -54,7 +54,7 @@ import org.apache.http.util.LangUtils;
|
|||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class HostConfiguration implements Cloneable {
|
||||
public class HostConfiguration {
|
||||
|
||||
/**
|
||||
* Constant representing a configuration for <i>any</i> host.
|
||||
|
|
|
@ -50,7 +50,7 @@ import org.apache.http.util.CharArrayBuffer;
|
|||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class HttpRoute implements Cloneable {
|
||||
public final class HttpRoute {
|
||||
|
||||
/** The target host to connect to. */
|
||||
private final HttpHost targetHost;
|
||||
|
|
|
@ -48,7 +48,7 @@ import org.apache.http.util.CharArrayBuffer;
|
|||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class RouteTracker implements Cloneable {
|
||||
public final class RouteTracker {
|
||||
|
||||
/** The target host to connect to. */
|
||||
private final HttpHost targetHost;
|
||||
|
|
|
@ -52,17 +52,6 @@ import org.apache.http.HttpHost;
|
|||
*/
|
||||
public final class SchemeRegistry {
|
||||
|
||||
/**
|
||||
* A default scheme registry.
|
||||
* It is empty by default, but can be initialized by any application.
|
||||
* The default scheme registry should only be used by applications that
|
||||
* know for sure that this class is NOT shared with any other application.
|
||||
* For example a Servlet, Portlet or EJB should not rely on being the
|
||||
* only user of this class.
|
||||
*/
|
||||
public final static SchemeRegistry DEFAULT = new SchemeRegistry();
|
||||
|
||||
|
||||
/** The available schemes in this registry. */
|
||||
private final Map registeredSchemes;
|
||||
|
||||
|
|
|
@ -51,8 +51,6 @@ import org.apache.http.params.HttpParams;
|
|||
*/
|
||||
public final class CookieSpecRegistry {
|
||||
|
||||
public final static CookieSpecRegistry DEFAULT = new CookieSpecRegistry();
|
||||
|
||||
private final Map registeredSpecs;
|
||||
|
||||
public CookieSpecRegistry() {
|
||||
|
|
|
@ -32,21 +32,29 @@
|
|||
package org.apache.http.impl.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.ConnectionReuseStrategy;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpRequestInterceptor;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.ConnectionReuseStrategy;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.SyncHttpExecutionContext;
|
||||
import org.apache.http.protocol.BasicHttpProcessor;
|
||||
import org.apache.http.conn.SchemeRegistry;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
|
||||
import org.apache.http.HttpResponseInterceptor;
|
||||
import org.apache.http.auth.AuthSchemeRegistry;
|
||||
import org.apache.http.client.ClientRequestDirector;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.HttpState;
|
||||
import org.apache.http.client.RoutedRequest;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.cookie.CookieSpecRegistry;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.protocol.BasicHttpProcessor;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.HttpExecutionContext;
|
||||
import org.apache.http.protocol.HttpRequestExecutor;
|
||||
import org.apache.http.protocol.HttpRequestInterceptorList;
|
||||
import org.apache.http.protocol.HttpResponseInterceptorList;
|
||||
|
||||
|
||||
|
||||
|
@ -62,84 +70,79 @@ import org.apache.http.client.RoutedRequest;
|
|||
* @since 4.0
|
||||
*/
|
||||
public abstract class AbstractHttpClient
|
||||
implements HttpClient {
|
||||
implements HttpClient, HttpRequestInterceptorList, HttpResponseInterceptorList {
|
||||
|
||||
|
||||
/** The default context. */
|
||||
protected HttpContext defaultContext;
|
||||
private HttpContext defaultContext;
|
||||
|
||||
/** The parameters. */
|
||||
protected HttpParams defaultParams;
|
||||
private HttpParams defaultParams;
|
||||
|
||||
/** The connection manager. */
|
||||
protected ClientConnectionManager connManager;
|
||||
private ClientConnectionManager connManager;
|
||||
|
||||
/** The connection re-use strategy. */
|
||||
protected ConnectionReuseStrategy reuseStrategy;
|
||||
private ConnectionReuseStrategy reuseStrategy;
|
||||
|
||||
/** The HTTP processor, if defined. */
|
||||
protected BasicHttpProcessor httpProcessor;
|
||||
/** The cookie spec registry. */
|
||||
private CookieSpecRegistry supportedCookieSpecs;
|
||||
|
||||
/** The scheme registry. */
|
||||
protected SchemeRegistry supportedSchemes;
|
||||
/** The authentication scheme registry. */
|
||||
private AuthSchemeRegistry supportedAuthSchemes;
|
||||
|
||||
/** The HTTP processor. */
|
||||
private BasicHttpProcessor httpProcessor;
|
||||
|
||||
/** The default HTTP state. */
|
||||
private HttpState defaultState;
|
||||
|
||||
/**
|
||||
* Creates a new HTTP client.
|
||||
*
|
||||
* @param context the context, or <code>null</code> to use an instance of
|
||||
* {@link SyncHttpExecutionContext SyncHttpExecutionContext}
|
||||
* @param params the parameters
|
||||
* @param conman the connection manager
|
||||
* @param schemes the scheme registry, or
|
||||
* <code>null</code> to use the
|
||||
* {@link SchemeRegistry#DEFAULT default}
|
||||
* @param params the parameters
|
||||
*/
|
||||
protected AbstractHttpClient(HttpContext context, HttpParams params,
|
||||
ClientConnectionManager conman,
|
||||
SchemeRegistry schemes) {
|
||||
if (params == null)
|
||||
throw new IllegalArgumentException
|
||||
("Parameters must not be null.");
|
||||
if (conman == null)
|
||||
throw new IllegalArgumentException
|
||||
("Connection manager must not be null.");
|
||||
|
||||
defaultContext = (context != null) ?
|
||||
context : new SyncHttpExecutionContext(null);
|
||||
defaultParams = params;
|
||||
connManager = conman;
|
||||
supportedSchemes = (schemes != null) ?
|
||||
schemes : SchemeRegistry.DEFAULT;
|
||||
|
||||
// to be initialized by derived class constructors, if needed:
|
||||
reuseStrategy = null;
|
||||
httpProcessor = null;
|
||||
|
||||
protected AbstractHttpClient(
|
||||
final ClientConnectionManager conman,
|
||||
final HttpParams params) {
|
||||
defaultParams = params;
|
||||
connManager = conman;
|
||||
} // constructor
|
||||
|
||||
|
||||
// non-javadoc, see interface HttpClient
|
||||
public final HttpContext getContext() {
|
||||
return defaultContext;
|
||||
}
|
||||
protected abstract HttpParams createHttpParams();
|
||||
|
||||
|
||||
/**
|
||||
* Replaces the default context.
|
||||
*
|
||||
* @param context the new default context
|
||||
*/
|
||||
public void setContext(HttpContext context) {
|
||||
if (context == null)
|
||||
throw new IllegalArgumentException
|
||||
("Context must not be null.");
|
||||
defaultContext = context;
|
||||
}
|
||||
protected abstract HttpContext createHttpContext();
|
||||
|
||||
|
||||
protected abstract ClientConnectionManager createClientConnectionManager();
|
||||
|
||||
|
||||
protected abstract AuthSchemeRegistry createAuthSchemeRegistry();
|
||||
|
||||
|
||||
protected abstract CookieSpecRegistry createCookieSpecRegistry();
|
||||
|
||||
|
||||
protected abstract ConnectionReuseStrategy createConnectionReuseStrategy();
|
||||
|
||||
|
||||
protected abstract BasicHttpProcessor createHttpProcessor();
|
||||
|
||||
|
||||
protected abstract HttpState createHttpState();
|
||||
|
||||
|
||||
protected abstract void populateContext(HttpContext context);
|
||||
|
||||
|
||||
// non-javadoc, see interface HttpClient
|
||||
public final HttpParams getParams() {
|
||||
public synchronized final HttpParams getParams() {
|
||||
if (defaultParams == null) {
|
||||
defaultParams = createHttpParams();
|
||||
}
|
||||
return defaultParams;
|
||||
}
|
||||
|
||||
|
@ -150,16 +153,16 @@ public abstract class AbstractHttpClient
|
|||
*
|
||||
* @param params the new default parameters
|
||||
*/
|
||||
public void setParams(HttpParams params) {
|
||||
if (params == null)
|
||||
throw new IllegalArgumentException
|
||||
("Parameters must not be null.");
|
||||
public synchronized void setParams(HttpParams params) {
|
||||
defaultParams = params;
|
||||
}
|
||||
|
||||
|
||||
// non-javadoc, see interface HttpClient
|
||||
public final ClientConnectionManager getConnectionManager() {
|
||||
public synchronized final ClientConnectionManager getConnectionManager() {
|
||||
if (connManager == null) {
|
||||
connManager = createClientConnectionManager();
|
||||
}
|
||||
return connManager;
|
||||
}
|
||||
|
||||
|
@ -168,23 +171,116 @@ public abstract class AbstractHttpClient
|
|||
// derived classes may offer that method at their own risk
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the HTTP processor.
|
||||
*
|
||||
* @return the HTTP processor, or <code>null</code> if not set
|
||||
*/
|
||||
public BasicHttpProcessor getProcessor() {
|
||||
public synchronized final AuthSchemeRegistry getAuthSchemes() {
|
||||
if (supportedAuthSchemes == null) {
|
||||
supportedAuthSchemes = createAuthSchemeRegistry();
|
||||
}
|
||||
return supportedAuthSchemes;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void setAuthSchemes(final AuthSchemeRegistry authSchemeRegistry) {
|
||||
supportedAuthSchemes = authSchemeRegistry;
|
||||
}
|
||||
|
||||
|
||||
public synchronized final CookieSpecRegistry getCookieSpecs() {
|
||||
if (supportedCookieSpecs == null) {
|
||||
supportedCookieSpecs = createCookieSpecRegistry();
|
||||
}
|
||||
return supportedCookieSpecs;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void setCookieSpecs(final CookieSpecRegistry cookieSpecRegistry) {
|
||||
supportedCookieSpecs = cookieSpecRegistry;
|
||||
}
|
||||
|
||||
|
||||
public synchronized final ConnectionReuseStrategy getConnectionReuseStrategy() {
|
||||
if (reuseStrategy == null) {
|
||||
reuseStrategy = createConnectionReuseStrategy();
|
||||
}
|
||||
return reuseStrategy;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void setReuseStrategy(final ConnectionReuseStrategy reuseStrategy) {
|
||||
this.reuseStrategy = reuseStrategy;
|
||||
}
|
||||
|
||||
|
||||
public synchronized final HttpState getState() {
|
||||
if (defaultState == null) {
|
||||
defaultState = createHttpState();
|
||||
}
|
||||
return defaultState;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void setState(final HttpState state) {
|
||||
defaultState = state;
|
||||
}
|
||||
|
||||
|
||||
protected synchronized final BasicHttpProcessor getHttpProcessor() {
|
||||
if (httpProcessor == null) {
|
||||
httpProcessor = createHttpProcessor();
|
||||
}
|
||||
return httpProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies the HTTP processor.
|
||||
*
|
||||
* @param hproc the HTTP processor, or <code>null</code> to unset
|
||||
*/
|
||||
public void setProcessor(BasicHttpProcessor hproc) {
|
||||
httpProcessor = hproc;
|
||||
public synchronized final HttpContext getContext() {
|
||||
if (defaultContext == null) {
|
||||
defaultContext = createHttpContext();
|
||||
}
|
||||
return defaultContext;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp) {
|
||||
getHttpProcessor().addInterceptor(itcp);
|
||||
}
|
||||
|
||||
|
||||
public synchronized void clearResponseInterceptors() {
|
||||
getHttpProcessor().clearResponseInterceptors();
|
||||
}
|
||||
|
||||
|
||||
public synchronized HttpResponseInterceptor getResponseInterceptor(int index) {
|
||||
return getHttpProcessor().getResponseInterceptor(index);
|
||||
}
|
||||
|
||||
|
||||
public synchronized int getResponseInterceptorCount() {
|
||||
return getHttpProcessor().getResponseInterceptorCount();
|
||||
}
|
||||
|
||||
|
||||
public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp) {
|
||||
getHttpProcessor().addInterceptor(itcp);
|
||||
}
|
||||
|
||||
|
||||
public synchronized void clearRequestInterceptors() {
|
||||
getHttpProcessor().clearRequestInterceptors();
|
||||
}
|
||||
|
||||
|
||||
public synchronized HttpRequestInterceptor getRequestInterceptor(int index) {
|
||||
return getHttpProcessor().getRequestInterceptor(index);
|
||||
}
|
||||
|
||||
|
||||
public synchronized int getRequestInterceptorCount() {
|
||||
return getHttpProcessor().getRequestInterceptorCount();
|
||||
}
|
||||
|
||||
|
||||
public synchronized void setInterceptors(final List itcps) {
|
||||
getHttpProcessor().setInterceptors(itcps);
|
||||
}
|
||||
|
||||
|
||||
|
@ -204,7 +300,7 @@ public abstract class AbstractHttpClient
|
|||
public final HttpResponse execute(HttpHost target, HttpRequest request)
|
||||
throws HttpException, IOException {
|
||||
|
||||
return execute(target, request, defaultContext);
|
||||
return execute(target, request, null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -229,12 +325,63 @@ public abstract class AbstractHttpClient
|
|||
// Otherwise, the null target is detected in determineRoute().
|
||||
|
||||
if (context == null)
|
||||
context = defaultContext;
|
||||
context = new HttpExecutionContext(getContext());
|
||||
|
||||
RoutedRequest roureq = determineRoute(target, request, context);
|
||||
return execute(roureq, context);
|
||||
}
|
||||
|
||||
// non-javadoc, see interface HttpClient
|
||||
public final HttpResponse execute(RoutedRequest roureq, HttpContext context)
|
||||
throws HttpException, IOException {
|
||||
|
||||
if (roureq == null) {
|
||||
throw new IllegalArgumentException
|
||||
("Routed request must not be null.");
|
||||
}
|
||||
if (roureq.getRequest() == null) {
|
||||
throw new IllegalArgumentException
|
||||
("Request must not be null.");
|
||||
}
|
||||
if (roureq.getRoute() == null) {
|
||||
throw new IllegalArgumentException
|
||||
("Route must not be null.");
|
||||
}
|
||||
|
||||
if (context == null)
|
||||
context = new HttpExecutionContext(getContext());
|
||||
|
||||
ClientRequestDirector director = null;
|
||||
|
||||
// Initialize the request execution context making copies of
|
||||
// all shared objects that are potentially threading unsafe.
|
||||
synchronized (this) {
|
||||
// Populate the context for this request
|
||||
populateContext(context);
|
||||
// Create a copy of the HTTP processor
|
||||
BasicHttpProcessor httpproc = getHttpProcessor().copy();
|
||||
// Create an HTTP request executor for this request
|
||||
HttpRequestExecutor reqexec = new HttpRequestExecutor(httpproc);
|
||||
reqexec.setParams(getParams());
|
||||
// Create a director for this request
|
||||
director = new DefaultClientRequestDirector(
|
||||
getConnectionManager(),
|
||||
getConnectionReuseStrategy(),
|
||||
reqexec);
|
||||
}
|
||||
|
||||
HttpResponse response = director.execute(roureq, context);
|
||||
// If the response depends on the connection, the director
|
||||
// will have set up an auto-release input stream.
|
||||
//@@@ or move that logic here into the client?
|
||||
|
||||
//@@@ "finalize" response, to allow for buffering of entities?
|
||||
//@@@ here or in director?
|
||||
|
||||
return response;
|
||||
|
||||
} // execute
|
||||
|
||||
|
||||
/**
|
||||
* Determines the route for a request.
|
||||
|
|
|
@ -48,7 +48,6 @@ import org.apache.http.conn.HttpRoute;
|
|||
import org.apache.http.conn.ManagedClientConnection;
|
||||
import org.apache.http.conn.RouteDirector;
|
||||
import org.apache.http.message.BasicHttpRequest;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.HttpExecutionContext;
|
||||
import org.apache.http.protocol.HttpRequestExecutor;
|
||||
|
@ -80,22 +79,17 @@ public class DefaultClientRequestDirector
|
|||
/** The request executor. */
|
||||
protected final HttpRequestExecutor requestExec;
|
||||
|
||||
/** The parameters. */
|
||||
protected final HttpParams defaultParams;
|
||||
|
||||
/** The currently allocated connection. */
|
||||
protected ManagedClientConnection managedConn;
|
||||
|
||||
|
||||
public DefaultClientRequestDirector(ClientConnectionManager conman,
|
||||
ConnectionReuseStrategy reustrat,
|
||||
HttpRequestExecutor reqexec,
|
||||
HttpParams params) {
|
||||
HttpRequestExecutor reqexec) {
|
||||
|
||||
this.connManager = conman;
|
||||
this.reuseStrategy = reustrat;
|
||||
this.requestExec = reqexec;
|
||||
this.defaultParams = params;
|
||||
|
||||
this.managedConn = null;
|
||||
|
||||
|
@ -224,16 +218,16 @@ public class DefaultClientRequestDirector
|
|||
|
||||
case RouteDirector.CONNECT_TARGET:
|
||||
case RouteDirector.CONNECT_PROXY:
|
||||
managedConn.open(route, context, defaultParams);
|
||||
managedConn.open(route, context, requestExec.getParams());
|
||||
break;
|
||||
|
||||
case RouteDirector.CREATE_TUNNEL:
|
||||
boolean secure = createTunnel(route, context);
|
||||
managedConn.tunnelCreated(secure, defaultParams);
|
||||
managedConn.tunnelCreated(secure, requestExec.getParams());
|
||||
break;
|
||||
|
||||
case RouteDirector.LAYER_PROTOCOL:
|
||||
managedConn.layerProtocol(context, defaultParams);
|
||||
managedConn.layerProtocol(context, requestExec.getParams());
|
||||
break;
|
||||
|
||||
case RouteDirector.UNREACHABLE:
|
||||
|
|
|
@ -31,24 +31,33 @@
|
|||
|
||||
package org.apache.http.impl.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.http.ConnectionReuseStrategy;
|
||||
import org.apache.http.HttpException;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientRequestDirector;
|
||||
import org.apache.http.auth.AuthSchemeRegistry;
|
||||
import org.apache.http.client.HttpState;
|
||||
import org.apache.http.client.RoutedRequest;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.conn.HttpRoute;
|
||||
import org.apache.http.conn.PlainSocketFactory;
|
||||
import org.apache.http.conn.Scheme;
|
||||
import org.apache.http.conn.SchemeRegistry;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.cookie.CookieSpecRegistry;
|
||||
import org.apache.http.impl.DefaultConnectionReuseStrategy;
|
||||
import org.apache.http.impl.conn.SingleClientConnManager;
|
||||
import org.apache.http.params.BasicHttpParams;
|
||||
import org.apache.http.params.HttpParams;
|
||||
import org.apache.http.protocol.BasicHttpProcessor;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.HttpRequestExecutor;
|
||||
import org.apache.http.protocol.RequestConnControl;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.protocol.RequestExpectContinue;
|
||||
import org.apache.http.protocol.RequestTargetHost;
|
||||
import org.apache.http.protocol.RequestUserAgent;
|
||||
import org.apache.http.protocol.SyncHttpExecutionContext;
|
||||
|
||||
|
||||
|
||||
|
@ -77,79 +86,88 @@ public class DefaultHttpClient extends AbstractHttpClient {
|
|||
* <code>null</code> to use the
|
||||
* {@link SchemeRegistry#DEFAULT default}
|
||||
*/
|
||||
public DefaultHttpClient(HttpParams params,
|
||||
ClientConnectionManager conman,
|
||||
SchemeRegistry schemes) {
|
||||
|
||||
super(null, params, conman, schemes);
|
||||
|
||||
httpProcessor = createProcessor();
|
||||
reuseStrategy = createReuseStrategy();
|
||||
public DefaultHttpClient(
|
||||
final ClientConnectionManager conman,
|
||||
final HttpParams params) {
|
||||
super(conman, params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and initializes an HTTP processor.
|
||||
* This method is typically called by the constructor,
|
||||
* after the base class has been initialized.
|
||||
*
|
||||
* @return a new, initialized HTTP processor
|
||||
*/
|
||||
protected BasicHttpProcessor createProcessor() {
|
||||
|
||||
BasicHttpProcessor bhp = new BasicHttpProcessor();
|
||||
//@@@ evaluate defaultParams to initialize interceptors
|
||||
|
||||
return bhp;
|
||||
public DefaultHttpClient(final HttpParams params) {
|
||||
super(null, params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a connection reuse strategy.
|
||||
* This method is typically called by the constructor,
|
||||
* after the base class has been initialized.
|
||||
*/
|
||||
protected ConnectionReuseStrategy createReuseStrategy() {
|
||||
|
||||
//@@@ evaluate defaultParams to determine implementation
|
||||
ConnectionReuseStrategy rus = new DefaultConnectionReuseStrategy();
|
||||
|
||||
return rus;
|
||||
protected HttpParams createHttpParams() {
|
||||
return new BasicHttpParams();
|
||||
}
|
||||
|
||||
|
||||
// non-javadoc, see interface HttpClient
|
||||
public HttpResponse execute(RoutedRequest roureq, HttpContext context)
|
||||
throws HttpException, IOException {
|
||||
protected ClientConnectionManager createClientConnectionManager() {
|
||||
SchemeRegistry registry = new SchemeRegistry();
|
||||
registry.register(
|
||||
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
|
||||
registry.register(
|
||||
new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
|
||||
|
||||
if (roureq == null) {
|
||||
throw new IllegalArgumentException
|
||||
("Routed request must not be null.");
|
||||
}
|
||||
if (roureq.getRequest() == null) {
|
||||
throw new IllegalArgumentException
|
||||
("Request must not be null.");
|
||||
}
|
||||
if (roureq.getRoute() == null) {
|
||||
throw new IllegalArgumentException
|
||||
("Route must not be null.");
|
||||
}
|
||||
return new SingleClientConnManager(getParams(), registry);
|
||||
}
|
||||
|
||||
if (context == null)
|
||||
context = defaultContext;
|
||||
|
||||
ClientRequestDirector director = createDirector(context);
|
||||
HttpResponse response = director.execute(roureq, context);
|
||||
// If the response depends on the connection, the director
|
||||
// will have set up an auto-release input stream.
|
||||
//@@@ or move that logic here into the client?
|
||||
protected HttpContext createHttpContext() {
|
||||
return new SyncHttpExecutionContext(null);
|
||||
}
|
||||
|
||||
//@@@ "finalize" response, to allow for buffering of entities?
|
||||
//@@@ here or in director?
|
||||
|
||||
return response;
|
||||
protected ConnectionReuseStrategy createConnectionReuseStrategy() {
|
||||
return new DefaultConnectionReuseStrategy();
|
||||
}
|
||||
|
||||
} // execute
|
||||
|
||||
protected AuthSchemeRegistry createAuthSchemeRegistry() {
|
||||
AuthSchemeRegistry registry = new AuthSchemeRegistry();
|
||||
return registry;
|
||||
}
|
||||
|
||||
|
||||
protected CookieSpecRegistry createCookieSpecRegistry() {
|
||||
CookieSpecRegistry registry = new CookieSpecRegistry();
|
||||
return registry;
|
||||
}
|
||||
|
||||
|
||||
protected BasicHttpProcessor createHttpProcessor() {
|
||||
BasicHttpProcessor httpproc = new BasicHttpProcessor();
|
||||
// Required protocol interceptors
|
||||
httpproc.addInterceptor(new RequestContent());
|
||||
httpproc.addInterceptor(new RequestTargetHost());
|
||||
// Recommended protocol interceptors
|
||||
httpproc.addInterceptor(new RequestConnControl());
|
||||
httpproc.addInterceptor(new RequestUserAgent());
|
||||
httpproc.addInterceptor(new RequestExpectContinue());
|
||||
return httpproc;
|
||||
}
|
||||
|
||||
|
||||
protected HttpState createHttpState() {
|
||||
return new HttpState();
|
||||
}
|
||||
|
||||
|
||||
protected void populateContext(final HttpContext context) {
|
||||
context.setAttribute(
|
||||
HttpClientContext.SCHEME_REGISTRY,
|
||||
getConnectionManager().getSchemeRegistry());
|
||||
context.setAttribute(
|
||||
HttpClientContext.AUTHSCHEME_REGISTRY,
|
||||
getAuthSchemes());
|
||||
context.setAttribute(
|
||||
HttpClientContext.COOKIESPEC_REGISTRY,
|
||||
getCookieSpecs());
|
||||
context.setAttribute(
|
||||
HttpClientContext.HTTP_STATE,
|
||||
getState());
|
||||
}
|
||||
|
||||
|
||||
// non-javadoc, see base class AbstractHttpClient
|
||||
|
@ -165,7 +183,8 @@ public class DefaultHttpClient extends AbstractHttpClient {
|
|||
("Target host must not be null.");
|
||||
}
|
||||
|
||||
Scheme schm = supportedSchemes.getScheme(target.getSchemeName());
|
||||
SchemeRegistry schemeRegistry = getConnectionManager().getSchemeRegistry();
|
||||
Scheme schm = schemeRegistry.getScheme(target.getSchemeName());
|
||||
// as it is typically used for TLS/SSL, we assume that
|
||||
// a layered scheme implies a secure connection
|
||||
HttpRoute route = new HttpRoute(target, null, schm.isLayered());
|
||||
|
@ -174,23 +193,4 @@ public class DefaultHttpClient extends AbstractHttpClient {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new director for a request execution.
|
||||
*
|
||||
* @param context the context to use for the execution,
|
||||
* never <code>null</code>
|
||||
*
|
||||
* @return the new director for executing a method in the given context
|
||||
*/
|
||||
protected ClientRequestDirector createDirector(HttpContext context) {
|
||||
|
||||
//@@@ can we use a single reqexec without sacrificing thread safety?
|
||||
//@@@ it seems wasteful to throw away both director and reqexec
|
||||
HttpRequestExecutor reqexec = new HttpRequestExecutor(httpProcessor);
|
||||
reqexec.setParams(defaultParams);
|
||||
|
||||
return new DefaultClientRequestDirector
|
||||
(connManager, reuseStrategy, reqexec, defaultParams);
|
||||
}
|
||||
|
||||
} // class DefaultHttpClient
|
||||
|
|
|
@ -86,7 +86,11 @@ public class DefaultClientConnectionOperator
|
|||
* {@link SchemeRegistry#DEFAULT SchemeRegistry.DEFAULT}
|
||||
*/
|
||||
public DefaultClientConnectionOperator(SchemeRegistry schemes) {
|
||||
schemeRegistry = (schemes != null) ? schemes : SchemeRegistry.DEFAULT;
|
||||
if (schemes == null) {
|
||||
throw new IllegalArgumentException
|
||||
("Scheme registry must not be null.");
|
||||
}
|
||||
schemeRegistry = schemes;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ public class SingleClientConnManager implements ClientConnectionManager {
|
|||
"Make sure to release the connection before allocating another one.";
|
||||
|
||||
|
||||
/** The schemes supported by this connection manager. */
|
||||
protected SchemeRegistry schemeRegistry;
|
||||
|
||||
/** The parameters of this connection manager. */
|
||||
protected HttpParams params = new BasicHttpParams();
|
||||
|
||||
|
@ -115,7 +118,11 @@ public class SingleClientConnManager implements ClientConnectionManager {
|
|||
if (params == null) {
|
||||
throw new IllegalArgumentException("Parameters must not be null.");
|
||||
}
|
||||
if (schreg == null) {
|
||||
throw new IllegalArgumentException("Scheme registry must not be null.");
|
||||
}
|
||||
this.params = params;
|
||||
this.schemeRegistry = schreg;
|
||||
this.connOperator = createConnectionOperator(schreg);
|
||||
this.uniquePoolEntry = new PoolEntry(connOperator.createConnection());
|
||||
this.managedConn = null;
|
||||
|
@ -126,6 +133,11 @@ public class SingleClientConnManager implements ClientConnectionManager {
|
|||
} // <constructor>
|
||||
|
||||
|
||||
public SchemeRegistry getSchemeRegistry() {
|
||||
return this.schemeRegistry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook for creating the connection operator.
|
||||
* It is called by the constructor.
|
||||
|
|
|
@ -104,6 +104,9 @@ public class ThreadSafeClientConnManager
|
|||
private static WeakHashMap ALL_CONNECTION_MANAGERS = new WeakHashMap();
|
||||
|
||||
|
||||
/** The schemes supported by this connection manager. */
|
||||
protected SchemeRegistry schemeRegistry;
|
||||
|
||||
/** The parameters of this connection manager. */
|
||||
private HttpParams params = new BasicHttpParams();
|
||||
|
||||
|
@ -133,6 +136,7 @@ public class ThreadSafeClientConnManager
|
|||
throw new IllegalArgumentException("Parameters must not be null.");
|
||||
}
|
||||
this.params = params;
|
||||
this.schemeRegistry = schreg;
|
||||
this.connectionPool = new ConnectionPool();
|
||||
this.connOperator = createConnectionOperator(schreg);
|
||||
this.isShutDown = false;
|
||||
|
@ -143,6 +147,10 @@ public class ThreadSafeClientConnManager
|
|||
} // <constructor>
|
||||
|
||||
|
||||
public SchemeRegistry getSchemeRegistry() {
|
||||
return this.schemeRegistry;
|
||||
}
|
||||
|
||||
|
||||
// non-javadoc, see interface ClientConnectionManager
|
||||
public ManagedClientConnection getConnection(HttpRoute route) {
|
||||
|
|
|
@ -63,7 +63,7 @@ public class TestCookiePolicy extends TestCase {
|
|||
}
|
||||
|
||||
public void testRegisterUnregisterCookieSpecFactory() {
|
||||
CookieSpecRegistry registry = CookieSpecRegistry.DEFAULT;
|
||||
CookieSpecRegistry registry = new CookieSpecRegistry();
|
||||
List names = registry.getSpecNames();
|
||||
assertNotNull(names);
|
||||
assertEquals(0, names.size());
|
||||
|
@ -98,7 +98,7 @@ public class TestCookiePolicy extends TestCase {
|
|||
}
|
||||
|
||||
public void testGetNewCookieSpec() {
|
||||
CookieSpecRegistry registry = CookieSpecRegistry.DEFAULT;
|
||||
CookieSpecRegistry registry = new CookieSpecRegistry();
|
||||
registry.register(CookieSpecParams.BROWSER_COMPATIBILITY,
|
||||
new BrowserCompatSpecFactory());
|
||||
registry.register(CookieSpecParams.NETSCAPE,
|
||||
|
@ -131,7 +131,7 @@ public class TestCookiePolicy extends TestCase {
|
|||
}
|
||||
|
||||
public void testInvalidInput() {
|
||||
CookieSpecRegistry registry = CookieSpecRegistry.DEFAULT;
|
||||
CookieSpecRegistry registry = new CookieSpecRegistry();
|
||||
try {
|
||||
registry.register(null, null);
|
||||
fail("IllegalArgumentException should have been thrown");
|
||||
|
|
|
@ -147,7 +147,7 @@ public class TestTSCCMNoServer extends TestCase {
|
|||
}
|
||||
mgr = null;
|
||||
|
||||
mgr = new ThreadSafeClientConnManager(params, null);
|
||||
mgr = new ThreadSafeClientConnManager(params, schreg);
|
||||
assertNotNull(mgr);
|
||||
assertNotNull(mgr.getParams());
|
||||
assertEquals(paramval, mgr.getParams().getParameter(paramkey));
|
||||
|
|
Loading…
Reference in New Issue