mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/client/AbstractHttpClient.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/impl/client/AbstractHttpClient.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,976 @@
     1.4 +/*
     1.5 + * ====================================================================
     1.6 + * Licensed to the Apache Software Foundation (ASF) under one
     1.7 + * or more contributor license agreements.  See the NOTICE file
     1.8 + * distributed with this work for additional information
     1.9 + * regarding copyright ownership.  The ASF licenses this file
    1.10 + * to you under the Apache License, Version 2.0 (the
    1.11 + * "License"); you may not use this file except in compliance
    1.12 + * with the License.  You may obtain a copy of the License at
    1.13 + *
    1.14 + *   http://www.apache.org/licenses/LICENSE-2.0
    1.15 + *
    1.16 + * Unless required by applicable law or agreed to in writing,
    1.17 + * software distributed under the License is distributed on an
    1.18 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    1.19 + * KIND, either express or implied.  See the License for the
    1.20 + * specific language governing permissions and limitations
    1.21 + * under the License.
    1.22 + * ====================================================================
    1.23 + *
    1.24 + * This software consists of voluntary contributions made by many
    1.25 + * individuals on behalf of the Apache Software Foundation.  For more
    1.26 + * information on the Apache Software Foundation, please see
    1.27 + * <http://www.apache.org/>.
    1.28 + *
    1.29 + */
    1.30 +
    1.31 +package ch.boye.httpclientandroidlib.impl.client;
    1.32 +
    1.33 +import java.io.IOException;
    1.34 +import java.lang.reflect.UndeclaredThrowableException;
    1.35 +import java.net.URI;
    1.36 +
    1.37 +import ch.boye.httpclientandroidlib.androidextra.HttpClientAndroidLog;
    1.38 +/* LogFactory removed by HttpClient for Android script. */
    1.39 +import ch.boye.httpclientandroidlib.ConnectionReuseStrategy;
    1.40 +import ch.boye.httpclientandroidlib.HttpEntity;
    1.41 +import ch.boye.httpclientandroidlib.HttpException;
    1.42 +import ch.boye.httpclientandroidlib.HttpHost;
    1.43 +import ch.boye.httpclientandroidlib.HttpRequest;
    1.44 +import ch.boye.httpclientandroidlib.HttpRequestInterceptor;
    1.45 +import ch.boye.httpclientandroidlib.HttpResponse;
    1.46 +import ch.boye.httpclientandroidlib.HttpResponseInterceptor;
    1.47 +import ch.boye.httpclientandroidlib.annotation.GuardedBy;
    1.48 +import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
    1.49 +import ch.boye.httpclientandroidlib.auth.AuthSchemeRegistry;
    1.50 +import ch.boye.httpclientandroidlib.client.AuthenticationHandler;
    1.51 +import ch.boye.httpclientandroidlib.client.ClientProtocolException;
    1.52 +import ch.boye.httpclientandroidlib.client.CookieStore;
    1.53 +import ch.boye.httpclientandroidlib.client.CredentialsProvider;
    1.54 +import ch.boye.httpclientandroidlib.client.HttpClient;
    1.55 +import ch.boye.httpclientandroidlib.client.HttpRequestRetryHandler;
    1.56 +import ch.boye.httpclientandroidlib.client.RedirectHandler;
    1.57 +import ch.boye.httpclientandroidlib.client.RedirectStrategy;
    1.58 +import ch.boye.httpclientandroidlib.client.RequestDirector;
    1.59 +import ch.boye.httpclientandroidlib.client.ResponseHandler;
    1.60 +import ch.boye.httpclientandroidlib.client.UserTokenHandler;
    1.61 +import ch.boye.httpclientandroidlib.client.methods.HttpUriRequest;
    1.62 +import ch.boye.httpclientandroidlib.client.params.AuthPolicy;
    1.63 +import ch.boye.httpclientandroidlib.client.params.ClientPNames;
    1.64 +import ch.boye.httpclientandroidlib.client.params.CookiePolicy;
    1.65 +import ch.boye.httpclientandroidlib.client.protocol.ClientContext;
    1.66 +import ch.boye.httpclientandroidlib.client.utils.URIUtils;
    1.67 +import ch.boye.httpclientandroidlib.conn.ClientConnectionManager;
    1.68 +import ch.boye.httpclientandroidlib.conn.ClientConnectionManagerFactory;
    1.69 +import ch.boye.httpclientandroidlib.conn.ConnectionKeepAliveStrategy;
    1.70 +import ch.boye.httpclientandroidlib.conn.routing.HttpRoutePlanner;
    1.71 +import ch.boye.httpclientandroidlib.conn.scheme.SchemeRegistry;
    1.72 +import ch.boye.httpclientandroidlib.cookie.CookieSpecRegistry;
    1.73 +import ch.boye.httpclientandroidlib.impl.DefaultConnectionReuseStrategy;
    1.74 +import ch.boye.httpclientandroidlib.impl.auth.BasicSchemeFactory;
    1.75 +import ch.boye.httpclientandroidlib.impl.auth.DigestSchemeFactory;
    1.76 +import ch.boye.httpclientandroidlib.impl.auth.NTLMSchemeFactory;
    1.77 +/* NegotiateSchemeFactory removed by HttpClient for Android script. */
    1.78 +import ch.boye.httpclientandroidlib.impl.conn.DefaultHttpRoutePlanner;
    1.79 +import ch.boye.httpclientandroidlib.impl.conn.SchemeRegistryFactory;
    1.80 +import ch.boye.httpclientandroidlib.impl.conn.SingleClientConnManager;
    1.81 +import ch.boye.httpclientandroidlib.impl.cookie.BestMatchSpecFactory;
    1.82 +import ch.boye.httpclientandroidlib.impl.cookie.BrowserCompatSpecFactory;
    1.83 +import ch.boye.httpclientandroidlib.impl.cookie.IgnoreSpecFactory;
    1.84 +import ch.boye.httpclientandroidlib.impl.cookie.NetscapeDraftSpecFactory;
    1.85 +import ch.boye.httpclientandroidlib.impl.cookie.RFC2109SpecFactory;
    1.86 +import ch.boye.httpclientandroidlib.impl.cookie.RFC2965SpecFactory;
    1.87 +import ch.boye.httpclientandroidlib.params.HttpParams;
    1.88 +import ch.boye.httpclientandroidlib.protocol.BasicHttpContext;
    1.89 +import ch.boye.httpclientandroidlib.protocol.BasicHttpProcessor;
    1.90 +import ch.boye.httpclientandroidlib.protocol.DefaultedHttpContext;
    1.91 +import ch.boye.httpclientandroidlib.protocol.HttpContext;
    1.92 +import ch.boye.httpclientandroidlib.protocol.HttpProcessor;
    1.93 +import ch.boye.httpclientandroidlib.protocol.HttpRequestExecutor;
    1.94 +import ch.boye.httpclientandroidlib.protocol.ImmutableHttpProcessor;
    1.95 +import ch.boye.httpclientandroidlib.util.EntityUtils;
    1.96 +
    1.97 +/**
    1.98 + * Base class for {@link HttpClient} implementations. This class acts as
    1.99 + * a facade to a number of special purpose handler or strategy
   1.100 + * implementations responsible for handling of a particular aspect of
   1.101 + * the HTTP protocol such as redirect or authentication handling or
   1.102 + * making decision about connection persistence and keep alive duration.
   1.103 + * This enables the users to selectively replace default implementation
   1.104 + * of those aspects with custom, application specific ones. This class
   1.105 + * also provides factory methods to instantiate those objects:
   1.106 + * <ul>
   1.107 + *   <li>{@link HttpRequestExecutor}</li> object used to transmit messages
   1.108 + *    over HTTP connections. The {@link #createRequestExecutor()} must be
   1.109 + *    implemented by concrete super classes to instantiate this object.
   1.110 + *   <li>{@link BasicHttpProcessor}</li> object to manage a list of protocol
   1.111 + *    interceptors and apply cross-cutting protocol logic to all incoming
   1.112 + *    and outgoing HTTP messages. The {@link #createHttpProcessor()} must be
   1.113 + *    implemented by concrete super classes to instantiate this object.
   1.114 + *   <li>{@link HttpRequestRetryHandler}</li> object used to decide whether
   1.115 + *    or not a failed HTTP request is safe to retry automatically.
   1.116 + *    The {@link #createHttpRequestRetryHandler()} must be
   1.117 + *    implemented by concrete super classes to instantiate this object.
   1.118 + *   <li>{@link ClientConnectionManager}</li> object used to manage
   1.119 + *    persistent HTTP connections.
   1.120 + *   <li>{@link ConnectionReuseStrategy}</li> object used to decide whether
   1.121 + *    or not a HTTP connection can be kept alive and re-used for subsequent
   1.122 + *    HTTP requests. The {@link #createConnectionReuseStrategy()} must be
   1.123 + *    implemented by concrete super classes to instantiate this object.
   1.124 + *   <li>{@link ConnectionKeepAliveStrategy}</li> object used to decide how
   1.125 + *    long a persistent HTTP connection can be kept alive.
   1.126 + *    The {@link #createConnectionKeepAliveStrategy()} must be
   1.127 + *    implemented by concrete super classes to instantiate this object.
   1.128 + *   <li>{@link CookieSpecRegistry}</li> object used to maintain a list of
   1.129 + *    supported cookie specifications.
   1.130 + *    The {@link #createCookieSpecRegistry()} must be implemented by concrete
   1.131 + *    super classes to instantiate this object.
   1.132 + *   <li>{@link CookieStore}</li> object used to maintain a collection of
   1.133 + *    cookies. The {@link #createCookieStore()} must be implemented by
   1.134 + *    concrete super classes to instantiate this object.
   1.135 + *   <li>{@link AuthSchemeRegistry}</li> object used to maintain a list of
   1.136 + *    supported authentication schemes.
   1.137 + *    The {@link #createAuthSchemeRegistry()} must be implemented by concrete
   1.138 + *    super classes to instantiate this object.
   1.139 + *   <li>{@link CredentialsProvider}</li> object used to maintain
   1.140 + *    a collection user credentials. The {@link #createCredentialsProvider()}
   1.141 + *    must be implemented by concrete super classes to instantiate
   1.142 + *    this object.
   1.143 + *   <li>{@link AuthenticationHandler}</li> object used to authenticate
   1.144 + *    against the target host.
   1.145 + *    The {@link #createTargetAuthenticationHandler()} must be implemented
   1.146 + *    by concrete super classes to instantiate this object.
   1.147 + *   <li>{@link AuthenticationHandler}</li> object used to authenticate
   1.148 + *    against the proxy host.
   1.149 + *    The {@link #createProxyAuthenticationHandler()} must be implemented
   1.150 + *    by concrete super classes to instantiate this object.
   1.151 + *   <li>{@link HttpRoutePlanner}</li> object used to calculate a route
   1.152 + *    for establishing a connection to the target host. The route
   1.153 + *    may involve multiple intermediate hops.
   1.154 + *    The {@link #createHttpRoutePlanner()} must be implemented
   1.155 + *    by concrete super classes to instantiate this object.
   1.156 + *   <li>{@link RedirectStrategy}</li> object used to determine if an HTTP
   1.157 + *    request should be redirected to a new location in response to an HTTP
   1.158 + *    response received from the target server.
   1.159 + *   <li>{@link UserTokenHandler}</li> object used to determine if the
   1.160 + *    execution context is user identity specific.
   1.161 + *    The {@link #createUserTokenHandler()} must be implemented by
   1.162 + *    concrete super classes to instantiate this object.
   1.163 + * </ul>
   1.164 + * <p>
   1.165 + *   This class also maintains a list of protocol interceptors intended
   1.166 + *   for processing outgoing requests and incoming responses and provides
   1.167 + *   methods for managing those interceptors. New protocol interceptors can be
   1.168 + *   introduced to the protocol processor chain or removed from it if needed.
   1.169 + *   Internally protocol interceptors are stored in a simple
   1.170 + *   {@link java.util.ArrayList}. They are executed in the same natural order
   1.171 + *   as they are added to the list.
   1.172 + * <p>
   1.173 + *   AbstractHttpClient is thread safe. It is recommended that the same
   1.174 + *   instance of this class is reused for multiple request executions.
   1.175 + *   When an instance of DefaultHttpClient is no longer needed and is about
   1.176 + *   to go out of scope the connection manager associated with it must be
   1.177 + *   shut down by calling {@link ClientConnectionManager#shutdown()}!
   1.178 + *
   1.179 + * @since 4.0
   1.180 + */
   1.181 +@ThreadSafe
   1.182 +@SuppressWarnings("deprecation")
   1.183 +public abstract class AbstractHttpClient implements HttpClient {
   1.184 +
   1.185 +    public HttpClientAndroidLog log = new HttpClientAndroidLog(getClass());
   1.186 +
   1.187 +    /** The parameters. */
   1.188 +    @GuardedBy("this")
   1.189 +    private HttpParams defaultParams;
   1.190 +
   1.191 +    /** The request executor. */
   1.192 +    @GuardedBy("this")
   1.193 +    private HttpRequestExecutor requestExec;
   1.194 +
   1.195 +    /** The connection manager. */
   1.196 +    @GuardedBy("this")
   1.197 +    private ClientConnectionManager connManager;
   1.198 +
   1.199 +    /** The connection re-use strategy. */
   1.200 +    @GuardedBy("this")
   1.201 +    private ConnectionReuseStrategy reuseStrategy;
   1.202 +
   1.203 +    /** The connection keep-alive strategy. */
   1.204 +    @GuardedBy("this")
   1.205 +    private ConnectionKeepAliveStrategy keepAliveStrategy;
   1.206 +
   1.207 +    /** The cookie spec registry. */
   1.208 +    @GuardedBy("this")
   1.209 +    private CookieSpecRegistry supportedCookieSpecs;
   1.210 +
   1.211 +    /** The authentication scheme registry. */
   1.212 +    @GuardedBy("this")
   1.213 +    private AuthSchemeRegistry supportedAuthSchemes;
   1.214 +
   1.215 +    /** The HTTP protocol processor and its immutable copy. */
   1.216 +    @GuardedBy("this")
   1.217 +    private BasicHttpProcessor mutableProcessor;
   1.218 +
   1.219 +    @GuardedBy("this")
   1.220 +    private ImmutableHttpProcessor protocolProcessor;
   1.221 +
   1.222 +    /** The request retry handler. */
   1.223 +    @GuardedBy("this")
   1.224 +    private HttpRequestRetryHandler retryHandler;
   1.225 +
   1.226 +    /** The redirect handler. */
   1.227 +    @GuardedBy("this")
   1.228 +    private RedirectStrategy redirectStrategy;
   1.229 +
   1.230 +    /** The target authentication handler. */
   1.231 +    @GuardedBy("this")
   1.232 +    private AuthenticationHandler targetAuthHandler;
   1.233 +
   1.234 +    /** The proxy authentication handler. */
   1.235 +    @GuardedBy("this")
   1.236 +    private AuthenticationHandler proxyAuthHandler;
   1.237 +
   1.238 +    /** The cookie store. */
   1.239 +    @GuardedBy("this")
   1.240 +    private CookieStore cookieStore;
   1.241 +
   1.242 +    /** The credentials provider. */
   1.243 +    @GuardedBy("this")
   1.244 +    private CredentialsProvider credsProvider;
   1.245 +
   1.246 +    /** The route planner. */
   1.247 +    @GuardedBy("this")
   1.248 +    private HttpRoutePlanner routePlanner;
   1.249 +
   1.250 +    /** The user token handler. */
   1.251 +    @GuardedBy("this")
   1.252 +    private UserTokenHandler userTokenHandler;
   1.253 +
   1.254 +
   1.255 +    /**
   1.256 +     * Creates a new HTTP client.
   1.257 +     *
   1.258 +     * @param conman    the connection manager
   1.259 +     * @param params    the parameters
   1.260 +     */
   1.261 +    protected AbstractHttpClient(
   1.262 +            final ClientConnectionManager conman,
   1.263 +            final HttpParams params) {
   1.264 +        defaultParams        = params;
   1.265 +        connManager          = conman;
   1.266 +    } // constructor
   1.267 +
   1.268 +
   1.269 +    protected abstract HttpParams createHttpParams();
   1.270 +
   1.271 +
   1.272 +    protected abstract BasicHttpProcessor createHttpProcessor();
   1.273 +
   1.274 +
   1.275 +    protected HttpContext createHttpContext() {
   1.276 +        HttpContext context = new BasicHttpContext();
   1.277 +        context.setAttribute(
   1.278 +                ClientContext.SCHEME_REGISTRY,
   1.279 +                getConnectionManager().getSchemeRegistry());
   1.280 +        context.setAttribute(
   1.281 +                ClientContext.AUTHSCHEME_REGISTRY,
   1.282 +                getAuthSchemes());
   1.283 +        context.setAttribute(
   1.284 +                ClientContext.COOKIESPEC_REGISTRY,
   1.285 +                getCookieSpecs());
   1.286 +        context.setAttribute(
   1.287 +                ClientContext.COOKIE_STORE,
   1.288 +                getCookieStore());
   1.289 +        context.setAttribute(
   1.290 +                ClientContext.CREDS_PROVIDER,
   1.291 +                getCredentialsProvider());
   1.292 +        return context;
   1.293 +    }
   1.294 +
   1.295 +
   1.296 +    protected ClientConnectionManager createClientConnectionManager() {
   1.297 +        SchemeRegistry registry = SchemeRegistryFactory.createDefault();
   1.298 +
   1.299 +        ClientConnectionManager connManager = null;
   1.300 +        HttpParams params = getParams();
   1.301 +
   1.302 +        ClientConnectionManagerFactory factory = null;
   1.303 +
   1.304 +        String className = (String) params.getParameter(
   1.305 +                ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME);
   1.306 +        if (className != null) {
   1.307 +            try {
   1.308 +                Class<?> clazz = Class.forName(className);
   1.309 +                factory = (ClientConnectionManagerFactory) clazz.newInstance();
   1.310 +            } catch (ClassNotFoundException ex) {
   1.311 +                throw new IllegalStateException("Invalid class name: " + className);
   1.312 +            } catch (IllegalAccessException ex) {
   1.313 +                throw new IllegalAccessError(ex.getMessage());
   1.314 +            } catch (InstantiationException ex) {
   1.315 +                throw new InstantiationError(ex.getMessage());
   1.316 +            }
   1.317 +        }
   1.318 +        if (factory != null) {
   1.319 +            connManager = factory.newInstance(params, registry);
   1.320 +        } else {
   1.321 +            connManager = new SingleClientConnManager(registry);
   1.322 +        }
   1.323 +
   1.324 +        return connManager;
   1.325 +    }
   1.326 +
   1.327 +
   1.328 +    protected AuthSchemeRegistry createAuthSchemeRegistry() {
   1.329 +        AuthSchemeRegistry registry = new AuthSchemeRegistry();
   1.330 +        registry.register(
   1.331 +                AuthPolicy.BASIC,
   1.332 +                new BasicSchemeFactory());
   1.333 +        registry.register(
   1.334 +                AuthPolicy.DIGEST,
   1.335 +                new DigestSchemeFactory());
   1.336 +        registry.register(
   1.337 +                AuthPolicy.NTLM,
   1.338 +                new NTLMSchemeFactory());
   1.339 +        /* NegotiateSchemeFactory removed by HttpClient for Android script. */
   1.340 +        return registry;
   1.341 +    }
   1.342 +
   1.343 +
   1.344 +    protected CookieSpecRegistry createCookieSpecRegistry() {
   1.345 +        CookieSpecRegistry registry = new CookieSpecRegistry();
   1.346 +        registry.register(
   1.347 +                CookiePolicy.BEST_MATCH,
   1.348 +                new BestMatchSpecFactory());
   1.349 +        registry.register(
   1.350 +                CookiePolicy.BROWSER_COMPATIBILITY,
   1.351 +                new BrowserCompatSpecFactory());
   1.352 +        registry.register(
   1.353 +                CookiePolicy.NETSCAPE,
   1.354 +                new NetscapeDraftSpecFactory());
   1.355 +        registry.register(
   1.356 +                CookiePolicy.RFC_2109,
   1.357 +                new RFC2109SpecFactory());
   1.358 +        registry.register(
   1.359 +                CookiePolicy.RFC_2965,
   1.360 +                new RFC2965SpecFactory());
   1.361 +        registry.register(
   1.362 +                CookiePolicy.IGNORE_COOKIES,
   1.363 +                new IgnoreSpecFactory());
   1.364 +        return registry;
   1.365 +    }
   1.366 +
   1.367 +
   1.368 +    protected HttpRequestExecutor createRequestExecutor() {
   1.369 +        return new HttpRequestExecutor();
   1.370 +    }
   1.371 +
   1.372 +
   1.373 +    protected ConnectionReuseStrategy createConnectionReuseStrategy() {
   1.374 +        return new DefaultConnectionReuseStrategy();
   1.375 +    }
   1.376 +
   1.377 +
   1.378 +    protected ConnectionKeepAliveStrategy createConnectionKeepAliveStrategy() {
   1.379 +        return new DefaultConnectionKeepAliveStrategy();
   1.380 +    }
   1.381 +
   1.382 +
   1.383 +    protected HttpRequestRetryHandler createHttpRequestRetryHandler() {
   1.384 +        return new DefaultHttpRequestRetryHandler();
   1.385 +    }
   1.386 +
   1.387 +
   1.388 +    @Deprecated
   1.389 +    protected RedirectHandler createRedirectHandler() {
   1.390 +        return new DefaultRedirectHandler();
   1.391 +    }
   1.392 +
   1.393 +
   1.394 +    protected AuthenticationHandler createTargetAuthenticationHandler() {
   1.395 +        return new DefaultTargetAuthenticationHandler();
   1.396 +    }
   1.397 +
   1.398 +
   1.399 +    protected AuthenticationHandler createProxyAuthenticationHandler() {
   1.400 +        return new DefaultProxyAuthenticationHandler();
   1.401 +    }
   1.402 +
   1.403 +
   1.404 +    protected CookieStore createCookieStore() {
   1.405 +        return new BasicCookieStore();
   1.406 +    }
   1.407 +
   1.408 +
   1.409 +    protected CredentialsProvider createCredentialsProvider() {
   1.410 +        return new BasicCredentialsProvider();
   1.411 +    }
   1.412 +
   1.413 +
   1.414 +    protected HttpRoutePlanner createHttpRoutePlanner() {
   1.415 +        return new DefaultHttpRoutePlanner(getConnectionManager().getSchemeRegistry());
   1.416 +    }
   1.417 +
   1.418 +
   1.419 +    protected UserTokenHandler createUserTokenHandler() {
   1.420 +        return new DefaultUserTokenHandler();
   1.421 +    }
   1.422 +
   1.423 +
   1.424 +    // non-javadoc, see interface HttpClient
   1.425 +    public synchronized final HttpParams getParams() {
   1.426 +        if (defaultParams == null) {
   1.427 +            defaultParams = createHttpParams();
   1.428 +        }
   1.429 +        return defaultParams;
   1.430 +    }
   1.431 +
   1.432 +
   1.433 +    /**
   1.434 +     * Replaces the parameters.
   1.435 +     * The implementation here does not update parameters of dependent objects.
   1.436 +     *
   1.437 +     * @param params    the new default parameters
   1.438 +     */
   1.439 +    public synchronized void setParams(HttpParams params) {
   1.440 +        defaultParams = params;
   1.441 +    }
   1.442 +
   1.443 +
   1.444 +    public synchronized final ClientConnectionManager getConnectionManager() {
   1.445 +        if (connManager == null) {
   1.446 +            connManager = createClientConnectionManager();
   1.447 +        }
   1.448 +        return connManager;
   1.449 +    }
   1.450 +
   1.451 +
   1.452 +    public synchronized final HttpRequestExecutor getRequestExecutor() {
   1.453 +        if (requestExec == null) {
   1.454 +            requestExec = createRequestExecutor();
   1.455 +        }
   1.456 +        return requestExec;
   1.457 +    }
   1.458 +
   1.459 +
   1.460 +    public synchronized final AuthSchemeRegistry getAuthSchemes() {
   1.461 +        if (supportedAuthSchemes == null) {
   1.462 +            supportedAuthSchemes = createAuthSchemeRegistry();
   1.463 +        }
   1.464 +        return supportedAuthSchemes;
   1.465 +    }
   1.466 +
   1.467 +
   1.468 +    public synchronized void setAuthSchemes(final AuthSchemeRegistry authSchemeRegistry) {
   1.469 +        supportedAuthSchemes = authSchemeRegistry;
   1.470 +    }
   1.471 +
   1.472 +
   1.473 +    public synchronized final CookieSpecRegistry getCookieSpecs() {
   1.474 +        if (supportedCookieSpecs == null) {
   1.475 +            supportedCookieSpecs = createCookieSpecRegistry();
   1.476 +        }
   1.477 +        return supportedCookieSpecs;
   1.478 +    }
   1.479 +
   1.480 +
   1.481 +    public synchronized void setCookieSpecs(final CookieSpecRegistry cookieSpecRegistry) {
   1.482 +        supportedCookieSpecs = cookieSpecRegistry;
   1.483 +    }
   1.484 +
   1.485 +
   1.486 +    public synchronized final ConnectionReuseStrategy getConnectionReuseStrategy() {
   1.487 +        if (reuseStrategy == null) {
   1.488 +            reuseStrategy = createConnectionReuseStrategy();
   1.489 +        }
   1.490 +        return reuseStrategy;
   1.491 +    }
   1.492 +
   1.493 +
   1.494 +    public synchronized void setReuseStrategy(final ConnectionReuseStrategy reuseStrategy) {
   1.495 +        this.reuseStrategy = reuseStrategy;
   1.496 +    }
   1.497 +
   1.498 +
   1.499 +    public synchronized final ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
   1.500 +        if (keepAliveStrategy == null) {
   1.501 +            keepAliveStrategy = createConnectionKeepAliveStrategy();
   1.502 +        }
   1.503 +        return keepAliveStrategy;
   1.504 +    }
   1.505 +
   1.506 +
   1.507 +    public synchronized void setKeepAliveStrategy(final ConnectionKeepAliveStrategy keepAliveStrategy) {
   1.508 +        this.keepAliveStrategy = keepAliveStrategy;
   1.509 +    }
   1.510 +
   1.511 +
   1.512 +    public synchronized final HttpRequestRetryHandler getHttpRequestRetryHandler() {
   1.513 +        if (retryHandler == null) {
   1.514 +            retryHandler = createHttpRequestRetryHandler();
   1.515 +        }
   1.516 +        return retryHandler;
   1.517 +    }
   1.518 +
   1.519 +
   1.520 +    public synchronized void setHttpRequestRetryHandler(final HttpRequestRetryHandler retryHandler) {
   1.521 +        this.retryHandler = retryHandler;
   1.522 +    }
   1.523 +
   1.524 +
   1.525 +    @Deprecated
   1.526 +    public synchronized final RedirectHandler getRedirectHandler() {
   1.527 +        return createRedirectHandler();
   1.528 +    }
   1.529 +
   1.530 +
   1.531 +    @Deprecated
   1.532 +    public synchronized void setRedirectHandler(final RedirectHandler redirectHandler) {
   1.533 +        this.redirectStrategy = new DefaultRedirectStrategyAdaptor(redirectHandler);
   1.534 +    }
   1.535 +
   1.536 +    /**
   1.537 +     * @since 4.1
   1.538 +     */
   1.539 +    public synchronized final RedirectStrategy getRedirectStrategy() {
   1.540 +        if (redirectStrategy == null) {
   1.541 +            redirectStrategy = new DefaultRedirectStrategy();
   1.542 +        }
   1.543 +        return redirectStrategy;
   1.544 +    }
   1.545 +
   1.546 +    /**
   1.547 +     * @since 4.1
   1.548 +     */
   1.549 +    public synchronized void setRedirectStrategy(final RedirectStrategy redirectStrategy) {
   1.550 +        this.redirectStrategy = redirectStrategy;
   1.551 +    }
   1.552 +
   1.553 +
   1.554 +    public synchronized final AuthenticationHandler getTargetAuthenticationHandler() {
   1.555 +        if (targetAuthHandler == null) {
   1.556 +            targetAuthHandler = createTargetAuthenticationHandler();
   1.557 +        }
   1.558 +        return targetAuthHandler;
   1.559 +    }
   1.560 +
   1.561 +
   1.562 +    public synchronized void setTargetAuthenticationHandler(
   1.563 +            final AuthenticationHandler targetAuthHandler) {
   1.564 +        this.targetAuthHandler = targetAuthHandler;
   1.565 +    }
   1.566 +
   1.567 +
   1.568 +    public synchronized final AuthenticationHandler getProxyAuthenticationHandler() {
   1.569 +        if (proxyAuthHandler == null) {
   1.570 +            proxyAuthHandler = createProxyAuthenticationHandler();
   1.571 +        }
   1.572 +        return proxyAuthHandler;
   1.573 +    }
   1.574 +
   1.575 +
   1.576 +    public synchronized void setProxyAuthenticationHandler(
   1.577 +            final AuthenticationHandler proxyAuthHandler) {
   1.578 +        this.proxyAuthHandler = proxyAuthHandler;
   1.579 +    }
   1.580 +
   1.581 +
   1.582 +    public synchronized final CookieStore getCookieStore() {
   1.583 +        if (cookieStore == null) {
   1.584 +            cookieStore = createCookieStore();
   1.585 +        }
   1.586 +        return cookieStore;
   1.587 +    }
   1.588 +
   1.589 +
   1.590 +    public synchronized void setCookieStore(final CookieStore cookieStore) {
   1.591 +        this.cookieStore = cookieStore;
   1.592 +    }
   1.593 +
   1.594 +
   1.595 +    public synchronized final CredentialsProvider getCredentialsProvider() {
   1.596 +        if (credsProvider == null) {
   1.597 +            credsProvider = createCredentialsProvider();
   1.598 +        }
   1.599 +        return credsProvider;
   1.600 +    }
   1.601 +
   1.602 +
   1.603 +    public synchronized void setCredentialsProvider(final CredentialsProvider credsProvider) {
   1.604 +        this.credsProvider = credsProvider;
   1.605 +    }
   1.606 +
   1.607 +
   1.608 +    public synchronized final HttpRoutePlanner getRoutePlanner() {
   1.609 +        if (this.routePlanner == null) {
   1.610 +            this.routePlanner = createHttpRoutePlanner();
   1.611 +        }
   1.612 +        return this.routePlanner;
   1.613 +    }
   1.614 +
   1.615 +
   1.616 +    public synchronized void setRoutePlanner(final HttpRoutePlanner routePlanner) {
   1.617 +        this.routePlanner = routePlanner;
   1.618 +    }
   1.619 +
   1.620 +
   1.621 +    public synchronized final UserTokenHandler getUserTokenHandler() {
   1.622 +        if (this.userTokenHandler == null) {
   1.623 +            this.userTokenHandler = createUserTokenHandler();
   1.624 +        }
   1.625 +        return this.userTokenHandler;
   1.626 +    }
   1.627 +
   1.628 +
   1.629 +    public synchronized void setUserTokenHandler(final UserTokenHandler userTokenHandler) {
   1.630 +        this.userTokenHandler = userTokenHandler;
   1.631 +    }
   1.632 +
   1.633 +
   1.634 +    protected synchronized final BasicHttpProcessor getHttpProcessor() {
   1.635 +        if (mutableProcessor == null) {
   1.636 +            mutableProcessor = createHttpProcessor();
   1.637 +        }
   1.638 +        return mutableProcessor;
   1.639 +    }
   1.640 +
   1.641 +
   1.642 +    private synchronized final HttpProcessor getProtocolProcessor() {
   1.643 +        if (protocolProcessor == null) {
   1.644 +            // Get mutable HTTP processor
   1.645 +            BasicHttpProcessor proc = getHttpProcessor();
   1.646 +            // and create an immutable copy of it
   1.647 +            int reqc = proc.getRequestInterceptorCount();
   1.648 +            HttpRequestInterceptor[] reqinterceptors = new HttpRequestInterceptor[reqc];
   1.649 +            for (int i = 0; i < reqc; i++) {
   1.650 +                reqinterceptors[i] = proc.getRequestInterceptor(i);
   1.651 +            }
   1.652 +            int resc = proc.getResponseInterceptorCount();
   1.653 +            HttpResponseInterceptor[] resinterceptors = new HttpResponseInterceptor[resc];
   1.654 +            for (int i = 0; i < resc; i++) {
   1.655 +                resinterceptors[i] = proc.getResponseInterceptor(i);
   1.656 +            }
   1.657 +            protocolProcessor = new ImmutableHttpProcessor(reqinterceptors, resinterceptors);
   1.658 +        }
   1.659 +        return protocolProcessor;
   1.660 +    }
   1.661 +
   1.662 +
   1.663 +    public synchronized int getResponseInterceptorCount() {
   1.664 +        return getHttpProcessor().getResponseInterceptorCount();
   1.665 +    }
   1.666 +
   1.667 +
   1.668 +    public synchronized HttpResponseInterceptor getResponseInterceptor(int index) {
   1.669 +        return getHttpProcessor().getResponseInterceptor(index);
   1.670 +    }
   1.671 +
   1.672 +
   1.673 +    public synchronized HttpRequestInterceptor getRequestInterceptor(int index) {
   1.674 +        return getHttpProcessor().getRequestInterceptor(index);
   1.675 +    }
   1.676 +
   1.677 +
   1.678 +    public synchronized int getRequestInterceptorCount() {
   1.679 +        return getHttpProcessor().getRequestInterceptorCount();
   1.680 +    }
   1.681 +
   1.682 +
   1.683 +    public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp) {
   1.684 +        getHttpProcessor().addInterceptor(itcp);
   1.685 +        protocolProcessor = null;
   1.686 +    }
   1.687 +
   1.688 +
   1.689 +    public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp, int index) {
   1.690 +        getHttpProcessor().addInterceptor(itcp, index);
   1.691 +        protocolProcessor = null;
   1.692 +    }
   1.693 +
   1.694 +
   1.695 +    public synchronized void clearResponseInterceptors() {
   1.696 +        getHttpProcessor().clearResponseInterceptors();
   1.697 +        protocolProcessor = null;
   1.698 +    }
   1.699 +
   1.700 +
   1.701 +    public synchronized void removeResponseInterceptorByClass(Class<? extends HttpResponseInterceptor> clazz) {
   1.702 +        getHttpProcessor().removeResponseInterceptorByClass(clazz);
   1.703 +        protocolProcessor = null;
   1.704 +    }
   1.705 +
   1.706 +
   1.707 +    public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp) {
   1.708 +        getHttpProcessor().addInterceptor(itcp);
   1.709 +        protocolProcessor = null;
   1.710 +    }
   1.711 +
   1.712 +
   1.713 +    public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp, int index) {
   1.714 +        getHttpProcessor().addInterceptor(itcp, index);
   1.715 +        protocolProcessor = null;
   1.716 +    }
   1.717 +
   1.718 +
   1.719 +    public synchronized void clearRequestInterceptors() {
   1.720 +        getHttpProcessor().clearRequestInterceptors();
   1.721 +        protocolProcessor = null;
   1.722 +    }
   1.723 +
   1.724 +
   1.725 +    public synchronized void removeRequestInterceptorByClass(Class<? extends HttpRequestInterceptor> clazz) {
   1.726 +        getHttpProcessor().removeRequestInterceptorByClass(clazz);
   1.727 +        protocolProcessor = null;
   1.728 +    }
   1.729 +
   1.730 +    public final HttpResponse execute(HttpUriRequest request)
   1.731 +        throws IOException, ClientProtocolException {
   1.732 +
   1.733 +        return execute(request, (HttpContext) null);
   1.734 +    }
   1.735 +
   1.736 +
   1.737 +    /**
   1.738 +     * Maps to {@link HttpClient#execute(HttpHost,HttpRequest,HttpContext)
   1.739 +     *                           execute(target, request, context)}.
   1.740 +     * The target is determined from the URI of the request.
   1.741 +     *
   1.742 +     * @param request   the request to execute
   1.743 +     * @param context   the request-specific execution context,
   1.744 +     *                  or <code>null</code> to use a default context
   1.745 +     */
   1.746 +    public final HttpResponse execute(HttpUriRequest request,
   1.747 +                                      HttpContext context)
   1.748 +        throws IOException, ClientProtocolException {
   1.749 +
   1.750 +        if (request == null) {
   1.751 +            throw new IllegalArgumentException
   1.752 +                ("Request must not be null.");
   1.753 +        }
   1.754 +
   1.755 +        return execute(determineTarget(request), request, context);
   1.756 +    }
   1.757 +
   1.758 +    private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException {
   1.759 +        // A null target may be acceptable if there is a default target.
   1.760 +        // Otherwise, the null target is detected in the director.
   1.761 +        HttpHost target = null;
   1.762 +
   1.763 +        URI requestURI = request.getURI();
   1.764 +        if (requestURI.isAbsolute()) {
   1.765 +            target = URIUtils.extractHost(requestURI);
   1.766 +            if (target == null) {
   1.767 +                throw new ClientProtocolException(
   1.768 +                        "URI does not specify a valid host name: " + requestURI);
   1.769 +            }
   1.770 +        }
   1.771 +        return target;
   1.772 +    }
   1.773 +
   1.774 +    public final HttpResponse execute(HttpHost target, HttpRequest request)
   1.775 +        throws IOException, ClientProtocolException {
   1.776 +
   1.777 +        return execute(target, request, (HttpContext) null);
   1.778 +    }
   1.779 +
   1.780 +    public final HttpResponse execute(HttpHost target, HttpRequest request,
   1.781 +                                      HttpContext context)
   1.782 +        throws IOException, ClientProtocolException {
   1.783 +
   1.784 +        if (request == null) {
   1.785 +            throw new IllegalArgumentException
   1.786 +                ("Request must not be null.");
   1.787 +        }
   1.788 +        // a null target may be acceptable, this depends on the route planner
   1.789 +        // a null context is acceptable, default context created below
   1.790 +
   1.791 +        HttpContext execContext = null;
   1.792 +        RequestDirector director = null;
   1.793 +
   1.794 +        // Initialize the request execution context making copies of
   1.795 +        // all shared objects that are potentially threading unsafe.
   1.796 +        synchronized (this) {
   1.797 +
   1.798 +            HttpContext defaultContext = createHttpContext();
   1.799 +            if (context == null) {
   1.800 +                execContext = defaultContext;
   1.801 +            } else {
   1.802 +                execContext = new DefaultedHttpContext(context, defaultContext);
   1.803 +            }
   1.804 +            // Create a director for this request
   1.805 +            director = createClientRequestDirector(
   1.806 +                    getRequestExecutor(),
   1.807 +                    getConnectionManager(),
   1.808 +                    getConnectionReuseStrategy(),
   1.809 +                    getConnectionKeepAliveStrategy(),
   1.810 +                    getRoutePlanner(),
   1.811 +                    getProtocolProcessor(),
   1.812 +                    getHttpRequestRetryHandler(),
   1.813 +                    getRedirectStrategy(),
   1.814 +                    getTargetAuthenticationHandler(),
   1.815 +                    getProxyAuthenticationHandler(),
   1.816 +                    getUserTokenHandler(),
   1.817 +                    determineParams(request));
   1.818 +        }
   1.819 +
   1.820 +        try {
   1.821 +            return director.execute(target, request, execContext);
   1.822 +        } catch(HttpException httpException) {
   1.823 +            throw new ClientProtocolException(httpException);
   1.824 +        }
   1.825 +    }
   1.826 +
   1.827 +    @Deprecated
   1.828 +    protected RequestDirector createClientRequestDirector(
   1.829 +            final HttpRequestExecutor requestExec,
   1.830 +            final ClientConnectionManager conman,
   1.831 +            final ConnectionReuseStrategy reustrat,
   1.832 +            final ConnectionKeepAliveStrategy kastrat,
   1.833 +            final HttpRoutePlanner rouplan,
   1.834 +            final HttpProcessor httpProcessor,
   1.835 +            final HttpRequestRetryHandler retryHandler,
   1.836 +            final ch.boye.httpclientandroidlib.client.RedirectHandler redirectHandler,
   1.837 +            final AuthenticationHandler targetAuthHandler,
   1.838 +            final AuthenticationHandler proxyAuthHandler,
   1.839 +            final UserTokenHandler stateHandler,
   1.840 +            final HttpParams params) {
   1.841 +        return new DefaultRequestDirector(
   1.842 +                requestExec,
   1.843 +                conman,
   1.844 +                reustrat,
   1.845 +                kastrat,
   1.846 +                rouplan,
   1.847 +                httpProcessor,
   1.848 +                retryHandler,
   1.849 +                redirectHandler,
   1.850 +                targetAuthHandler,
   1.851 +                proxyAuthHandler,
   1.852 +                stateHandler,
   1.853 +                params);
   1.854 +    }
   1.855 +
   1.856 +    /**
   1.857 +     * @since 4.1
   1.858 +     */
   1.859 +    protected RequestDirector createClientRequestDirector(
   1.860 +            final HttpRequestExecutor requestExec,
   1.861 +            final ClientConnectionManager conman,
   1.862 +            final ConnectionReuseStrategy reustrat,
   1.863 +            final ConnectionKeepAliveStrategy kastrat,
   1.864 +            final HttpRoutePlanner rouplan,
   1.865 +            final HttpProcessor httpProcessor,
   1.866 +            final HttpRequestRetryHandler retryHandler,
   1.867 +            final RedirectStrategy redirectStrategy,
   1.868 +            final AuthenticationHandler targetAuthHandler,
   1.869 +            final AuthenticationHandler proxyAuthHandler,
   1.870 +            final UserTokenHandler stateHandler,
   1.871 +            final HttpParams params) {
   1.872 +        return new DefaultRequestDirector(
   1.873 +                log,
   1.874 +                requestExec,
   1.875 +                conman,
   1.876 +                reustrat,
   1.877 +                kastrat,
   1.878 +                rouplan,
   1.879 +                httpProcessor,
   1.880 +                retryHandler,
   1.881 +                redirectStrategy,
   1.882 +                targetAuthHandler,
   1.883 +                proxyAuthHandler,
   1.884 +                stateHandler,
   1.885 +                params);
   1.886 +    }
   1.887 +    /**
   1.888 +     * Obtains parameters for executing a request.
   1.889 +     * The default implementation in this class creates a new
   1.890 +     * {@link ClientParamsStack} from the request parameters
   1.891 +     * and the client parameters.
   1.892 +     * <br/>
   1.893 +     * This method is called by the default implementation of
   1.894 +     * {@link #execute(HttpHost,HttpRequest,HttpContext)}
   1.895 +     * to obtain the parameters for the
   1.896 +     * {@link DefaultRequestDirector}.
   1.897 +     *
   1.898 +     * @param req    the request that will be executed
   1.899 +     *
   1.900 +     * @return  the parameters to use
   1.901 +     */
   1.902 +    protected HttpParams determineParams(HttpRequest req) {
   1.903 +        return new ClientParamsStack
   1.904 +            (null, getParams(), req.getParams(), null);
   1.905 +    }
   1.906 +
   1.907 +    public <T> T execute(
   1.908 +            final HttpUriRequest request,
   1.909 +            final ResponseHandler<? extends T> responseHandler)
   1.910 +                throws IOException, ClientProtocolException {
   1.911 +        return execute(request, responseHandler, null);
   1.912 +    }
   1.913 +
   1.914 +    public <T> T execute(
   1.915 +            final HttpUriRequest request,
   1.916 +            final ResponseHandler<? extends T> responseHandler,
   1.917 +            final HttpContext context)
   1.918 +                throws IOException, ClientProtocolException {
   1.919 +        HttpHost target = determineTarget(request);
   1.920 +        return execute(target, request, responseHandler, context);
   1.921 +    }
   1.922 +
   1.923 +    public <T> T execute(
   1.924 +            final HttpHost target,
   1.925 +            final HttpRequest request,
   1.926 +            final ResponseHandler<? extends T> responseHandler)
   1.927 +                throws IOException, ClientProtocolException {
   1.928 +        return execute(target, request, responseHandler, null);
   1.929 +    }
   1.930 +
   1.931 +    public <T> T execute(
   1.932 +            final HttpHost target,
   1.933 +            final HttpRequest request,
   1.934 +            final ResponseHandler<? extends T> responseHandler,
   1.935 +            final HttpContext context)
   1.936 +                throws IOException, ClientProtocolException {
   1.937 +        if (responseHandler == null) {
   1.938 +            throw new IllegalArgumentException
   1.939 +                ("Response handler must not be null.");
   1.940 +        }
   1.941 +
   1.942 +        HttpResponse response = execute(target, request, context);
   1.943 +
   1.944 +        T result;
   1.945 +        try {
   1.946 +            result = responseHandler.handleResponse(response);
   1.947 +        } catch (Throwable t) {
   1.948 +            HttpEntity entity = response.getEntity();
   1.949 +            try {
   1.950 +                EntityUtils.consume(entity);
   1.951 +            } catch (Exception t2) {
   1.952 +                // Log this exception. The original exception is more
   1.953 +                // important and will be thrown to the caller.
   1.954 +                this.log.warn("Error consuming content after an exception.", t2);
   1.955 +            }
   1.956 +
   1.957 +            if (t instanceof Error) {
   1.958 +                throw (Error) t;
   1.959 +            }
   1.960 +
   1.961 +            if (t instanceof RuntimeException) {
   1.962 +                throw (RuntimeException) t;
   1.963 +            }
   1.964 +
   1.965 +            if (t instanceof IOException) {
   1.966 +                throw (IOException) t;
   1.967 +            }
   1.968 +
   1.969 +            throw new UndeclaredThrowableException(t);
   1.970 +        }
   1.971 +
   1.972 +        // Handling the response was successful. Ensure that the content has
   1.973 +        // been fully consumed.
   1.974 +        HttpEntity entity = response.getEntity();
   1.975 +        EntityUtils.consume(entity);
   1.976 +        return result;
   1.977 +    }
   1.978 +
   1.979 +}

mercurial