michael@0: /*
michael@0: * ====================================================================
michael@0: * Licensed to the Apache Software Foundation (ASF) under one
michael@0: * or more contributor license agreements. See the NOTICE file
michael@0: * distributed with this work for additional information
michael@0: * regarding copyright ownership. The ASF licenses this file
michael@0: * to you under the Apache License, Version 2.0 (the
michael@0: * "License"); you may not use this file except in compliance
michael@0: * with the License. You may obtain a copy of the License at
michael@0: *
michael@0: * http://www.apache.org/licenses/LICENSE-2.0
michael@0: *
michael@0: * Unless required by applicable law or agreed to in writing,
michael@0: * software distributed under the License is distributed on an
michael@0: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
michael@0: * KIND, either express or implied. See the License for the
michael@0: * specific language governing permissions and limitations
michael@0: * under the License.
michael@0: * ====================================================================
michael@0: *
michael@0: * This software consists of voluntary contributions made by many
michael@0: * individuals on behalf of the Apache Software Foundation. For more
michael@0: * information on the Apache Software Foundation, please see
michael@0: *
michael@0: * This class also maintains a list of protocol interceptors intended michael@0: * for processing outgoing requests and incoming responses and provides michael@0: * methods for managing those interceptors. New protocol interceptors can be michael@0: * introduced to the protocol processor chain or removed from it if needed. michael@0: * Internally protocol interceptors are stored in a simple michael@0: * {@link java.util.ArrayList}. They are executed in the same natural order michael@0: * as they are added to the list. michael@0: *
michael@0: * AbstractHttpClient is thread safe. It is recommended that the same
michael@0: * instance of this class is reused for multiple request executions.
michael@0: * When an instance of DefaultHttpClient is no longer needed and is about
michael@0: * to go out of scope the connection manager associated with it must be
michael@0: * shut down by calling {@link ClientConnectionManager#shutdown()}!
michael@0: *
michael@0: * @since 4.0
michael@0: */
michael@0: @ThreadSafe
michael@0: @SuppressWarnings("deprecation")
michael@0: public abstract class AbstractHttpClient implements HttpClient {
michael@0:
michael@0: public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
michael@0:
michael@0: /** The parameters. */
michael@0: @GuardedBy("this")
michael@0: private HttpParams defaultParams;
michael@0:
michael@0: /** The request executor. */
michael@0: @GuardedBy("this")
michael@0: private HttpRequestExecutor requestExec;
michael@0:
michael@0: /** The connection manager. */
michael@0: @GuardedBy("this")
michael@0: private ClientConnectionManager connManager;
michael@0:
michael@0: /** The connection re-use strategy. */
michael@0: @GuardedBy("this")
michael@0: private ConnectionReuseStrategy reuseStrategy;
michael@0:
michael@0: /** The connection keep-alive strategy. */
michael@0: @GuardedBy("this")
michael@0: private ConnectionKeepAliveStrategy keepAliveStrategy;
michael@0:
michael@0: /** The cookie spec registry. */
michael@0: @GuardedBy("this")
michael@0: private CookieSpecRegistry supportedCookieSpecs;
michael@0:
michael@0: /** The authentication scheme registry. */
michael@0: @GuardedBy("this")
michael@0: private AuthSchemeRegistry supportedAuthSchemes;
michael@0:
michael@0: /** The HTTP protocol processor and its immutable copy. */
michael@0: @GuardedBy("this")
michael@0: private BasicHttpProcessor mutableProcessor;
michael@0:
michael@0: @GuardedBy("this")
michael@0: private ImmutableHttpProcessor protocolProcessor;
michael@0:
michael@0: /** The request retry handler. */
michael@0: @GuardedBy("this")
michael@0: private HttpRequestRetryHandler retryHandler;
michael@0:
michael@0: /** The redirect handler. */
michael@0: @GuardedBy("this")
michael@0: private RedirectStrategy redirectStrategy;
michael@0:
michael@0: /** The target authentication handler. */
michael@0: @GuardedBy("this")
michael@0: private AuthenticationHandler targetAuthHandler;
michael@0:
michael@0: /** The proxy authentication handler. */
michael@0: @GuardedBy("this")
michael@0: private AuthenticationHandler proxyAuthHandler;
michael@0:
michael@0: /** The cookie store. */
michael@0: @GuardedBy("this")
michael@0: private CookieStore cookieStore;
michael@0:
michael@0: /** The credentials provider. */
michael@0: @GuardedBy("this")
michael@0: private CredentialsProvider credsProvider;
michael@0:
michael@0: /** The route planner. */
michael@0: @GuardedBy("this")
michael@0: private HttpRoutePlanner routePlanner;
michael@0:
michael@0: /** The user token handler. */
michael@0: @GuardedBy("this")
michael@0: private UserTokenHandler userTokenHandler;
michael@0:
michael@0:
michael@0: /**
michael@0: * Creates a new HTTP client.
michael@0: *
michael@0: * @param conman the connection manager
michael@0: * @param params the parameters
michael@0: */
michael@0: protected AbstractHttpClient(
michael@0: final ClientConnectionManager conman,
michael@0: final HttpParams params) {
michael@0: defaultParams = params;
michael@0: connManager = conman;
michael@0: } // constructor
michael@0:
michael@0:
michael@0: protected abstract HttpParams createHttpParams();
michael@0:
michael@0:
michael@0: protected abstract BasicHttpProcessor createHttpProcessor();
michael@0:
michael@0:
michael@0: protected HttpContext createHttpContext() {
michael@0: HttpContext context = new BasicHttpContext();
michael@0: context.setAttribute(
michael@0: ClientContext.SCHEME_REGISTRY,
michael@0: getConnectionManager().getSchemeRegistry());
michael@0: context.setAttribute(
michael@0: ClientContext.AUTHSCHEME_REGISTRY,
michael@0: getAuthSchemes());
michael@0: context.setAttribute(
michael@0: ClientContext.COOKIESPEC_REGISTRY,
michael@0: getCookieSpecs());
michael@0: context.setAttribute(
michael@0: ClientContext.COOKIE_STORE,
michael@0: getCookieStore());
michael@0: context.setAttribute(
michael@0: ClientContext.CREDS_PROVIDER,
michael@0: getCredentialsProvider());
michael@0: return context;
michael@0: }
michael@0:
michael@0:
michael@0: protected ClientConnectionManager createClientConnectionManager() {
michael@0: SchemeRegistry registry = SchemeRegistryFactory.createDefault();
michael@0:
michael@0: ClientConnectionManager connManager = null;
michael@0: HttpParams params = getParams();
michael@0:
michael@0: ClientConnectionManagerFactory factory = null;
michael@0:
michael@0: String className = (String) params.getParameter(
michael@0: ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME);
michael@0: if (className != null) {
michael@0: try {
michael@0: Class> clazz = Class.forName(className);
michael@0: factory = (ClientConnectionManagerFactory) clazz.newInstance();
michael@0: } catch (ClassNotFoundException ex) {
michael@0: throw new IllegalStateException("Invalid class name: " + className);
michael@0: } catch (IllegalAccessException ex) {
michael@0: throw new IllegalAccessError(ex.getMessage());
michael@0: } catch (InstantiationException ex) {
michael@0: throw new InstantiationError(ex.getMessage());
michael@0: }
michael@0: }
michael@0: if (factory != null) {
michael@0: connManager = factory.newInstance(params, registry);
michael@0: } else {
michael@0: connManager = new SingleClientConnManager(registry);
michael@0: }
michael@0:
michael@0: return connManager;
michael@0: }
michael@0:
michael@0:
michael@0: protected AuthSchemeRegistry createAuthSchemeRegistry() {
michael@0: AuthSchemeRegistry registry = new AuthSchemeRegistry();
michael@0: registry.register(
michael@0: AuthPolicy.BASIC,
michael@0: new BasicSchemeFactory());
michael@0: registry.register(
michael@0: AuthPolicy.DIGEST,
michael@0: new DigestSchemeFactory());
michael@0: registry.register(
michael@0: AuthPolicy.NTLM,
michael@0: new NTLMSchemeFactory());
michael@0: /* NegotiateSchemeFactory removed by HttpClient for Android script. */
michael@0: return registry;
michael@0: }
michael@0:
michael@0:
michael@0: protected CookieSpecRegistry createCookieSpecRegistry() {
michael@0: CookieSpecRegistry registry = new CookieSpecRegistry();
michael@0: registry.register(
michael@0: CookiePolicy.BEST_MATCH,
michael@0: new BestMatchSpecFactory());
michael@0: registry.register(
michael@0: CookiePolicy.BROWSER_COMPATIBILITY,
michael@0: new BrowserCompatSpecFactory());
michael@0: registry.register(
michael@0: CookiePolicy.NETSCAPE,
michael@0: new NetscapeDraftSpecFactory());
michael@0: registry.register(
michael@0: CookiePolicy.RFC_2109,
michael@0: new RFC2109SpecFactory());
michael@0: registry.register(
michael@0: CookiePolicy.RFC_2965,
michael@0: new RFC2965SpecFactory());
michael@0: registry.register(
michael@0: CookiePolicy.IGNORE_COOKIES,
michael@0: new IgnoreSpecFactory());
michael@0: return registry;
michael@0: }
michael@0:
michael@0:
michael@0: protected HttpRequestExecutor createRequestExecutor() {
michael@0: return new HttpRequestExecutor();
michael@0: }
michael@0:
michael@0:
michael@0: protected ConnectionReuseStrategy createConnectionReuseStrategy() {
michael@0: return new DefaultConnectionReuseStrategy();
michael@0: }
michael@0:
michael@0:
michael@0: protected ConnectionKeepAliveStrategy createConnectionKeepAliveStrategy() {
michael@0: return new DefaultConnectionKeepAliveStrategy();
michael@0: }
michael@0:
michael@0:
michael@0: protected HttpRequestRetryHandler createHttpRequestRetryHandler() {
michael@0: return new DefaultHttpRequestRetryHandler();
michael@0: }
michael@0:
michael@0:
michael@0: @Deprecated
michael@0: protected RedirectHandler createRedirectHandler() {
michael@0: return new DefaultRedirectHandler();
michael@0: }
michael@0:
michael@0:
michael@0: protected AuthenticationHandler createTargetAuthenticationHandler() {
michael@0: return new DefaultTargetAuthenticationHandler();
michael@0: }
michael@0:
michael@0:
michael@0: protected AuthenticationHandler createProxyAuthenticationHandler() {
michael@0: return new DefaultProxyAuthenticationHandler();
michael@0: }
michael@0:
michael@0:
michael@0: protected CookieStore createCookieStore() {
michael@0: return new BasicCookieStore();
michael@0: }
michael@0:
michael@0:
michael@0: protected CredentialsProvider createCredentialsProvider() {
michael@0: return new BasicCredentialsProvider();
michael@0: }
michael@0:
michael@0:
michael@0: protected HttpRoutePlanner createHttpRoutePlanner() {
michael@0: return new DefaultHttpRoutePlanner(getConnectionManager().getSchemeRegistry());
michael@0: }
michael@0:
michael@0:
michael@0: protected UserTokenHandler createUserTokenHandler() {
michael@0: return new DefaultUserTokenHandler();
michael@0: }
michael@0:
michael@0:
michael@0: // non-javadoc, see interface HttpClient
michael@0: public synchronized final HttpParams getParams() {
michael@0: if (defaultParams == null) {
michael@0: defaultParams = createHttpParams();
michael@0: }
michael@0: return defaultParams;
michael@0: }
michael@0:
michael@0:
michael@0: /**
michael@0: * Replaces the parameters.
michael@0: * The implementation here does not update parameters of dependent objects.
michael@0: *
michael@0: * @param params the new default parameters
michael@0: */
michael@0: public synchronized void setParams(HttpParams params) {
michael@0: defaultParams = params;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final ClientConnectionManager getConnectionManager() {
michael@0: if (connManager == null) {
michael@0: connManager = createClientConnectionManager();
michael@0: }
michael@0: return connManager;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final HttpRequestExecutor getRequestExecutor() {
michael@0: if (requestExec == null) {
michael@0: requestExec = createRequestExecutor();
michael@0: }
michael@0: return requestExec;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final AuthSchemeRegistry getAuthSchemes() {
michael@0: if (supportedAuthSchemes == null) {
michael@0: supportedAuthSchemes = createAuthSchemeRegistry();
michael@0: }
michael@0: return supportedAuthSchemes;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setAuthSchemes(final AuthSchemeRegistry authSchemeRegistry) {
michael@0: supportedAuthSchemes = authSchemeRegistry;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final CookieSpecRegistry getCookieSpecs() {
michael@0: if (supportedCookieSpecs == null) {
michael@0: supportedCookieSpecs = createCookieSpecRegistry();
michael@0: }
michael@0: return supportedCookieSpecs;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setCookieSpecs(final CookieSpecRegistry cookieSpecRegistry) {
michael@0: supportedCookieSpecs = cookieSpecRegistry;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final ConnectionReuseStrategy getConnectionReuseStrategy() {
michael@0: if (reuseStrategy == null) {
michael@0: reuseStrategy = createConnectionReuseStrategy();
michael@0: }
michael@0: return reuseStrategy;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setReuseStrategy(final ConnectionReuseStrategy reuseStrategy) {
michael@0: this.reuseStrategy = reuseStrategy;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
michael@0: if (keepAliveStrategy == null) {
michael@0: keepAliveStrategy = createConnectionKeepAliveStrategy();
michael@0: }
michael@0: return keepAliveStrategy;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setKeepAliveStrategy(final ConnectionKeepAliveStrategy keepAliveStrategy) {
michael@0: this.keepAliveStrategy = keepAliveStrategy;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final HttpRequestRetryHandler getHttpRequestRetryHandler() {
michael@0: if (retryHandler == null) {
michael@0: retryHandler = createHttpRequestRetryHandler();
michael@0: }
michael@0: return retryHandler;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setHttpRequestRetryHandler(final HttpRequestRetryHandler retryHandler) {
michael@0: this.retryHandler = retryHandler;
michael@0: }
michael@0:
michael@0:
michael@0: @Deprecated
michael@0: public synchronized final RedirectHandler getRedirectHandler() {
michael@0: return createRedirectHandler();
michael@0: }
michael@0:
michael@0:
michael@0: @Deprecated
michael@0: public synchronized void setRedirectHandler(final RedirectHandler redirectHandler) {
michael@0: this.redirectStrategy = new DefaultRedirectStrategyAdaptor(redirectHandler);
michael@0: }
michael@0:
michael@0: /**
michael@0: * @since 4.1
michael@0: */
michael@0: public synchronized final RedirectStrategy getRedirectStrategy() {
michael@0: if (redirectStrategy == null) {
michael@0: redirectStrategy = new DefaultRedirectStrategy();
michael@0: }
michael@0: return redirectStrategy;
michael@0: }
michael@0:
michael@0: /**
michael@0: * @since 4.1
michael@0: */
michael@0: public synchronized void setRedirectStrategy(final RedirectStrategy redirectStrategy) {
michael@0: this.redirectStrategy = redirectStrategy;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final AuthenticationHandler getTargetAuthenticationHandler() {
michael@0: if (targetAuthHandler == null) {
michael@0: targetAuthHandler = createTargetAuthenticationHandler();
michael@0: }
michael@0: return targetAuthHandler;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setTargetAuthenticationHandler(
michael@0: final AuthenticationHandler targetAuthHandler) {
michael@0: this.targetAuthHandler = targetAuthHandler;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final AuthenticationHandler getProxyAuthenticationHandler() {
michael@0: if (proxyAuthHandler == null) {
michael@0: proxyAuthHandler = createProxyAuthenticationHandler();
michael@0: }
michael@0: return proxyAuthHandler;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setProxyAuthenticationHandler(
michael@0: final AuthenticationHandler proxyAuthHandler) {
michael@0: this.proxyAuthHandler = proxyAuthHandler;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final CookieStore getCookieStore() {
michael@0: if (cookieStore == null) {
michael@0: cookieStore = createCookieStore();
michael@0: }
michael@0: return cookieStore;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setCookieStore(final CookieStore cookieStore) {
michael@0: this.cookieStore = cookieStore;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final CredentialsProvider getCredentialsProvider() {
michael@0: if (credsProvider == null) {
michael@0: credsProvider = createCredentialsProvider();
michael@0: }
michael@0: return credsProvider;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setCredentialsProvider(final CredentialsProvider credsProvider) {
michael@0: this.credsProvider = credsProvider;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final HttpRoutePlanner getRoutePlanner() {
michael@0: if (this.routePlanner == null) {
michael@0: this.routePlanner = createHttpRoutePlanner();
michael@0: }
michael@0: return this.routePlanner;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setRoutePlanner(final HttpRoutePlanner routePlanner) {
michael@0: this.routePlanner = routePlanner;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized final UserTokenHandler getUserTokenHandler() {
michael@0: if (this.userTokenHandler == null) {
michael@0: this.userTokenHandler = createUserTokenHandler();
michael@0: }
michael@0: return this.userTokenHandler;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void setUserTokenHandler(final UserTokenHandler userTokenHandler) {
michael@0: this.userTokenHandler = userTokenHandler;
michael@0: }
michael@0:
michael@0:
michael@0: protected synchronized final BasicHttpProcessor getHttpProcessor() {
michael@0: if (mutableProcessor == null) {
michael@0: mutableProcessor = createHttpProcessor();
michael@0: }
michael@0: return mutableProcessor;
michael@0: }
michael@0:
michael@0:
michael@0: private synchronized final HttpProcessor getProtocolProcessor() {
michael@0: if (protocolProcessor == null) {
michael@0: // Get mutable HTTP processor
michael@0: BasicHttpProcessor proc = getHttpProcessor();
michael@0: // and create an immutable copy of it
michael@0: int reqc = proc.getRequestInterceptorCount();
michael@0: HttpRequestInterceptor[] reqinterceptors = new HttpRequestInterceptor[reqc];
michael@0: for (int i = 0; i < reqc; i++) {
michael@0: reqinterceptors[i] = proc.getRequestInterceptor(i);
michael@0: }
michael@0: int resc = proc.getResponseInterceptorCount();
michael@0: HttpResponseInterceptor[] resinterceptors = new HttpResponseInterceptor[resc];
michael@0: for (int i = 0; i < resc; i++) {
michael@0: resinterceptors[i] = proc.getResponseInterceptor(i);
michael@0: }
michael@0: protocolProcessor = new ImmutableHttpProcessor(reqinterceptors, resinterceptors);
michael@0: }
michael@0: return protocolProcessor;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized int getResponseInterceptorCount() {
michael@0: return getHttpProcessor().getResponseInterceptorCount();
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized HttpResponseInterceptor getResponseInterceptor(int index) {
michael@0: return getHttpProcessor().getResponseInterceptor(index);
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized HttpRequestInterceptor getRequestInterceptor(int index) {
michael@0: return getHttpProcessor().getRequestInterceptor(index);
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized int getRequestInterceptorCount() {
michael@0: return getHttpProcessor().getRequestInterceptorCount();
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp) {
michael@0: getHttpProcessor().addInterceptor(itcp);
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp, int index) {
michael@0: getHttpProcessor().addInterceptor(itcp, index);
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void clearResponseInterceptors() {
michael@0: getHttpProcessor().clearResponseInterceptors();
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void removeResponseInterceptorByClass(Class extends HttpResponseInterceptor> clazz) {
michael@0: getHttpProcessor().removeResponseInterceptorByClass(clazz);
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp) {
michael@0: getHttpProcessor().addInterceptor(itcp);
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp, int index) {
michael@0: getHttpProcessor().addInterceptor(itcp, index);
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void clearRequestInterceptors() {
michael@0: getHttpProcessor().clearRequestInterceptors();
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0:
michael@0: public synchronized void removeRequestInterceptorByClass(Class extends HttpRequestInterceptor> clazz) {
michael@0: getHttpProcessor().removeRequestInterceptorByClass(clazz);
michael@0: protocolProcessor = null;
michael@0: }
michael@0:
michael@0: public final HttpResponse execute(HttpUriRequest request)
michael@0: throws IOException, ClientProtocolException {
michael@0:
michael@0: return execute(request, (HttpContext) null);
michael@0: }
michael@0:
michael@0:
michael@0: /**
michael@0: * Maps to {@link HttpClient#execute(HttpHost,HttpRequest,HttpContext)
michael@0: * execute(target, request, context)}.
michael@0: * The target is determined from the URI of the request.
michael@0: *
michael@0: * @param request the request to execute
michael@0: * @param context the request-specific execution context,
michael@0: * or null
to use a default context
michael@0: */
michael@0: public final HttpResponse execute(HttpUriRequest request,
michael@0: HttpContext context)
michael@0: throws IOException, ClientProtocolException {
michael@0:
michael@0: if (request == null) {
michael@0: throw new IllegalArgumentException
michael@0: ("Request must not be null.");
michael@0: }
michael@0:
michael@0: return execute(determineTarget(request), request, context);
michael@0: }
michael@0:
michael@0: private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException {
michael@0: // A null target may be acceptable if there is a default target.
michael@0: // Otherwise, the null target is detected in the director.
michael@0: HttpHost target = null;
michael@0:
michael@0: URI requestURI = request.getURI();
michael@0: if (requestURI.isAbsolute()) {
michael@0: target = URIUtils.extractHost(requestURI);
michael@0: if (target == null) {
michael@0: throw new ClientProtocolException(
michael@0: "URI does not specify a valid host name: " + requestURI);
michael@0: }
michael@0: }
michael@0: return target;
michael@0: }
michael@0:
michael@0: public final HttpResponse execute(HttpHost target, HttpRequest request)
michael@0: throws IOException, ClientProtocolException {
michael@0:
michael@0: return execute(target, request, (HttpContext) null);
michael@0: }
michael@0:
michael@0: public final HttpResponse execute(HttpHost target, HttpRequest request,
michael@0: HttpContext context)
michael@0: throws IOException, ClientProtocolException {
michael@0:
michael@0: if (request == null) {
michael@0: throw new IllegalArgumentException
michael@0: ("Request must not be null.");
michael@0: }
michael@0: // a null target may be acceptable, this depends on the route planner
michael@0: // a null context is acceptable, default context created below
michael@0:
michael@0: HttpContext execContext = null;
michael@0: RequestDirector director = null;
michael@0:
michael@0: // Initialize the request execution context making copies of
michael@0: // all shared objects that are potentially threading unsafe.
michael@0: synchronized (this) {
michael@0:
michael@0: HttpContext defaultContext = createHttpContext();
michael@0: if (context == null) {
michael@0: execContext = defaultContext;
michael@0: } else {
michael@0: execContext = new DefaultedHttpContext(context, defaultContext);
michael@0: }
michael@0: // Create a director for this request
michael@0: director = createClientRequestDirector(
michael@0: getRequestExecutor(),
michael@0: getConnectionManager(),
michael@0: getConnectionReuseStrategy(),
michael@0: getConnectionKeepAliveStrategy(),
michael@0: getRoutePlanner(),
michael@0: getProtocolProcessor(),
michael@0: getHttpRequestRetryHandler(),
michael@0: getRedirectStrategy(),
michael@0: getTargetAuthenticationHandler(),
michael@0: getProxyAuthenticationHandler(),
michael@0: getUserTokenHandler(),
michael@0: determineParams(request));
michael@0: }
michael@0:
michael@0: try {
michael@0: return director.execute(target, request, execContext);
michael@0: } catch(HttpException httpException) {
michael@0: throw new ClientProtocolException(httpException);
michael@0: }
michael@0: }
michael@0:
michael@0: @Deprecated
michael@0: protected RequestDirector createClientRequestDirector(
michael@0: final HttpRequestExecutor requestExec,
michael@0: final ClientConnectionManager conman,
michael@0: final ConnectionReuseStrategy reustrat,
michael@0: final ConnectionKeepAliveStrategy kastrat,
michael@0: final HttpRoutePlanner rouplan,
michael@0: final HttpProcessor httpProcessor,
michael@0: final HttpRequestRetryHandler retryHandler,
michael@0: final ch.boye.httpclientandroidlib.client.RedirectHandler redirectHandler,
michael@0: final AuthenticationHandler targetAuthHandler,
michael@0: final AuthenticationHandler proxyAuthHandler,
michael@0: final UserTokenHandler stateHandler,
michael@0: final HttpParams params) {
michael@0: return new DefaultRequestDirector(
michael@0: requestExec,
michael@0: conman,
michael@0: reustrat,
michael@0: kastrat,
michael@0: rouplan,
michael@0: httpProcessor,
michael@0: retryHandler,
michael@0: redirectHandler,
michael@0: targetAuthHandler,
michael@0: proxyAuthHandler,
michael@0: stateHandler,
michael@0: params);
michael@0: }
michael@0:
michael@0: /**
michael@0: * @since 4.1
michael@0: */
michael@0: protected RequestDirector createClientRequestDirector(
michael@0: final HttpRequestExecutor requestExec,
michael@0: final ClientConnectionManager conman,
michael@0: final ConnectionReuseStrategy reustrat,
michael@0: final ConnectionKeepAliveStrategy kastrat,
michael@0: final HttpRoutePlanner rouplan,
michael@0: final HttpProcessor httpProcessor,
michael@0: final HttpRequestRetryHandler retryHandler,
michael@0: final RedirectStrategy redirectStrategy,
michael@0: final AuthenticationHandler targetAuthHandler,
michael@0: final AuthenticationHandler proxyAuthHandler,
michael@0: final UserTokenHandler stateHandler,
michael@0: final HttpParams params) {
michael@0: return new DefaultRequestDirector(
michael@0: log,
michael@0: requestExec,
michael@0: conman,
michael@0: reustrat,
michael@0: kastrat,
michael@0: rouplan,
michael@0: httpProcessor,
michael@0: retryHandler,
michael@0: redirectStrategy,
michael@0: targetAuthHandler,
michael@0: proxyAuthHandler,
michael@0: stateHandler,
michael@0: params);
michael@0: }
michael@0: /**
michael@0: * Obtains parameters for executing a request.
michael@0: * The default implementation in this class creates a new
michael@0: * {@link ClientParamsStack} from the request parameters
michael@0: * and the client parameters.
michael@0: *
michael@0: * This method is called by the default implementation of
michael@0: * {@link #execute(HttpHost,HttpRequest,HttpContext)}
michael@0: * to obtain the parameters for the
michael@0: * {@link DefaultRequestDirector}.
michael@0: *
michael@0: * @param req the request that will be executed
michael@0: *
michael@0: * @return the parameters to use
michael@0: */
michael@0: protected HttpParams determineParams(HttpRequest req) {
michael@0: return new ClientParamsStack
michael@0: (null, getParams(), req.getParams(), null);
michael@0: }
michael@0:
michael@0: public