Home | History | Annotate | Download | only in client
      1 /*
      2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java $
      3  * $Revision: 677250 $
      4  * $Date: 2008-07-16 04:45:47 -0700 (Wed, 16 Jul 2008) $
      5  *
      6  * ====================================================================
      7  * Licensed to the Apache Software Foundation (ASF) under one
      8  * or more contributor license agreements.  See the NOTICE file
      9  * distributed with this work for additional information
     10  * regarding copyright ownership.  The ASF licenses this file
     11  * to you under the Apache License, Version 2.0 (the
     12  * "License"); you may not use this file except in compliance
     13  * with the License.  You may obtain a copy of the License at
     14  *
     15  *   http://www.apache.org/licenses/LICENSE-2.0
     16  *
     17  * Unless required by applicable law or agreed to in writing,
     18  * software distributed under the License is distributed on an
     19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     20  * KIND, either express or implied.  See the License for the
     21  * specific language governing permissions and limitations
     22  * under the License.
     23  * ====================================================================
     24  *
     25  * This software consists of voluntary contributions made by many
     26  * individuals on behalf of the Apache Software Foundation.  For more
     27  * information on the Apache Software Foundation, please see
     28  * <http://www.apache.org/>.
     29  *
     30  */
     31 
     32 package org.apache.http.impl.client;
     33 
     34 import java.io.IOException;
     35 import java.net.URI;
     36 import java.lang.reflect.UndeclaredThrowableException;
     37 
     38 import org.apache.commons.logging.Log;
     39 import org.apache.commons.logging.LogFactory;
     40 import org.apache.http.ConnectionReuseStrategy;
     41 import org.apache.http.HttpException;
     42 import org.apache.http.HttpHost;
     43 import org.apache.http.HttpRequest;
     44 import org.apache.http.HttpRequestInterceptor;
     45 import org.apache.http.HttpResponse;
     46 import org.apache.http.HttpResponseInterceptor;
     47 import org.apache.http.HttpEntity;
     48 import org.apache.http.auth.AuthSchemeRegistry;
     49 import org.apache.http.client.AuthenticationHandler;
     50 import org.apache.http.client.ClientProtocolException;
     51 import org.apache.http.client.RequestDirector;
     52 import org.apache.http.client.ResponseHandler;
     53 import org.apache.http.client.CookieStore;
     54 import org.apache.http.client.CredentialsProvider;
     55 import org.apache.http.client.HttpClient;
     56 import org.apache.http.client.HttpRequestRetryHandler;
     57 import org.apache.http.client.RedirectHandler;
     58 import org.apache.http.client.UserTokenHandler;
     59 import org.apache.http.client.methods.HttpUriRequest;
     60 import org.apache.http.conn.ClientConnectionManager;
     61 import org.apache.http.conn.ConnectionKeepAliveStrategy;
     62 import org.apache.http.conn.routing.HttpRoutePlanner;
     63 import org.apache.http.cookie.CookieSpecRegistry;
     64 import org.apache.http.params.HttpParams;
     65 import org.apache.http.protocol.BasicHttpProcessor;
     66 import org.apache.http.protocol.DefaultedHttpContext;
     67 import org.apache.http.protocol.HttpContext;
     68 import org.apache.http.protocol.HttpProcessor;
     69 import org.apache.http.protocol.HttpRequestExecutor;
     70 
     71 /**
     72  * Convenience base class for HTTP client implementations.
     73  *
     74  * @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
     75  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
     76  *
     77  * <!-- empty lines to avoid svn diff problems -->
     78  * @version   $Revision: 677250 $
     79  *
     80  * @since 4.0
     81  *
     82  * @deprecated Please use {@link java.net.URL#openConnection} instead.
     83  *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
     84  *     for further details.
     85  */
     86 @Deprecated
     87 public abstract class AbstractHttpClient implements HttpClient {
     88 
     89     private final Log log = LogFactory.getLog(getClass());
     90 
     91     /** The parameters. */
     92     private HttpParams defaultParams;
     93 
     94     /** The request executor. */
     95     private HttpRequestExecutor requestExec;
     96 
     97     /** The connection manager. */
     98     private ClientConnectionManager connManager;
     99 
    100     /** The connection re-use strategy. */
    101     private ConnectionReuseStrategy reuseStrategy;
    102 
    103     /** The connection keep-alive strategy. */
    104     private ConnectionKeepAliveStrategy keepAliveStrategy;
    105 
    106     /** The cookie spec registry. */
    107     private CookieSpecRegistry supportedCookieSpecs;
    108 
    109     /** The authentication scheme registry. */
    110     private AuthSchemeRegistry supportedAuthSchemes;
    111 
    112     /** The HTTP processor. */
    113     private BasicHttpProcessor httpProcessor;
    114 
    115     /** The request retry handler. */
    116     private HttpRequestRetryHandler retryHandler;
    117 
    118     /** The redirect handler. */
    119     private RedirectHandler redirectHandler;
    120 
    121     /** The target authentication handler. */
    122     private AuthenticationHandler targetAuthHandler;
    123 
    124     /** The proxy authentication handler. */
    125     private AuthenticationHandler proxyAuthHandler;
    126 
    127     /** The cookie store. */
    128     private CookieStore cookieStore;
    129 
    130     /** The credentials provider. */
    131     private CredentialsProvider credsProvider;
    132 
    133     /** The route planner. */
    134     private HttpRoutePlanner routePlanner;
    135 
    136     /** The user token handler. */
    137     private UserTokenHandler userTokenHandler;
    138 
    139 
    140     /**
    141      * Creates a new HTTP client.
    142      *
    143      * @param conman    the connection manager
    144      * @param params    the parameters
    145      */
    146     protected AbstractHttpClient(
    147             final ClientConnectionManager conman,
    148             final HttpParams params) {
    149         defaultParams        = params;
    150         connManager          = conman;
    151     } // constructor
    152 
    153     protected abstract HttpParams createHttpParams();
    154 
    155 
    156     protected abstract HttpContext createHttpContext();
    157 
    158 
    159     protected abstract HttpRequestExecutor createRequestExecutor();
    160 
    161 
    162     protected abstract ClientConnectionManager createClientConnectionManager();
    163 
    164 
    165     protected abstract AuthSchemeRegistry createAuthSchemeRegistry();
    166 
    167 
    168     protected abstract CookieSpecRegistry createCookieSpecRegistry();
    169 
    170 
    171     protected abstract ConnectionReuseStrategy createConnectionReuseStrategy();
    172 
    173 
    174     protected abstract ConnectionKeepAliveStrategy createConnectionKeepAliveStrategy();
    175 
    176 
    177     protected abstract BasicHttpProcessor createHttpProcessor();
    178 
    179 
    180     protected abstract HttpRequestRetryHandler createHttpRequestRetryHandler();
    181 
    182 
    183     protected abstract RedirectHandler createRedirectHandler();
    184 
    185 
    186     protected abstract AuthenticationHandler createTargetAuthenticationHandler();
    187 
    188 
    189     protected abstract AuthenticationHandler createProxyAuthenticationHandler();
    190 
    191 
    192     protected abstract CookieStore createCookieStore();
    193 
    194 
    195     protected abstract CredentialsProvider createCredentialsProvider();
    196 
    197 
    198     protected abstract HttpRoutePlanner createHttpRoutePlanner();
    199 
    200 
    201     protected abstract UserTokenHandler createUserTokenHandler();
    202 
    203 
    204     // non-javadoc, see interface HttpClient
    205     public synchronized final HttpParams getParams() {
    206         if (defaultParams == null) {
    207             defaultParams = createHttpParams();
    208         }
    209         return defaultParams;
    210     }
    211 
    212 
    213     /**
    214      * Replaces the parameters.
    215      * The implementation here does not update parameters of dependent objects.
    216      *
    217      * @param params    the new default parameters
    218      */
    219     public synchronized void setParams(HttpParams params) {
    220         defaultParams = params;
    221     }
    222 
    223 
    224     public synchronized final ClientConnectionManager getConnectionManager() {
    225         if (connManager == null) {
    226             connManager = createClientConnectionManager();
    227         }
    228         return connManager;
    229     }
    230 
    231 
    232     public synchronized final HttpRequestExecutor getRequestExecutor() {
    233         if (requestExec == null) {
    234             requestExec = createRequestExecutor();
    235         }
    236         return requestExec;
    237     }
    238 
    239 
    240     public synchronized final AuthSchemeRegistry getAuthSchemes() {
    241         if (supportedAuthSchemes == null) {
    242             supportedAuthSchemes = createAuthSchemeRegistry();
    243         }
    244         return supportedAuthSchemes;
    245     }
    246 
    247 
    248     public synchronized void setAuthSchemes(final AuthSchemeRegistry authSchemeRegistry) {
    249         supportedAuthSchemes = authSchemeRegistry;
    250     }
    251 
    252 
    253     public synchronized final CookieSpecRegistry getCookieSpecs() {
    254         if (supportedCookieSpecs == null) {
    255             supportedCookieSpecs = createCookieSpecRegistry();
    256         }
    257         return supportedCookieSpecs;
    258     }
    259 
    260 
    261     public synchronized void setCookieSpecs(final CookieSpecRegistry cookieSpecRegistry) {
    262         supportedCookieSpecs = cookieSpecRegistry;
    263     }
    264 
    265 
    266     public synchronized final ConnectionReuseStrategy getConnectionReuseStrategy() {
    267         if (reuseStrategy == null) {
    268             reuseStrategy = createConnectionReuseStrategy();
    269         }
    270         return reuseStrategy;
    271     }
    272 
    273 
    274     public synchronized void setReuseStrategy(final ConnectionReuseStrategy reuseStrategy) {
    275         this.reuseStrategy = reuseStrategy;
    276     }
    277 
    278 
    279     public synchronized final ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
    280         if (keepAliveStrategy == null) {
    281             keepAliveStrategy = createConnectionKeepAliveStrategy();
    282         }
    283         return keepAliveStrategy;
    284     }
    285 
    286 
    287     public synchronized void setKeepAliveStrategy(final ConnectionKeepAliveStrategy keepAliveStrategy) {
    288         this.keepAliveStrategy = keepAliveStrategy;
    289     }
    290 
    291 
    292     public synchronized final HttpRequestRetryHandler getHttpRequestRetryHandler() {
    293         if (retryHandler == null) {
    294             retryHandler = createHttpRequestRetryHandler();
    295         }
    296         return retryHandler;
    297     }
    298 
    299 
    300     public synchronized void setHttpRequestRetryHandler(final HttpRequestRetryHandler retryHandler) {
    301         this.retryHandler = retryHandler;
    302     }
    303 
    304 
    305     public synchronized final RedirectHandler getRedirectHandler() {
    306         if (redirectHandler == null) {
    307             redirectHandler = createRedirectHandler();
    308         }
    309         return redirectHandler;
    310     }
    311 
    312 
    313     public synchronized void setRedirectHandler(final RedirectHandler redirectHandler) {
    314         this.redirectHandler = redirectHandler;
    315     }
    316 
    317 
    318     public synchronized final AuthenticationHandler getTargetAuthenticationHandler() {
    319         if (targetAuthHandler == null) {
    320             targetAuthHandler = createTargetAuthenticationHandler();
    321         }
    322         return targetAuthHandler;
    323     }
    324 
    325 
    326     public synchronized void setTargetAuthenticationHandler(
    327             final AuthenticationHandler targetAuthHandler) {
    328         this.targetAuthHandler = targetAuthHandler;
    329     }
    330 
    331 
    332     public synchronized final AuthenticationHandler getProxyAuthenticationHandler() {
    333         if (proxyAuthHandler == null) {
    334             proxyAuthHandler = createProxyAuthenticationHandler();
    335         }
    336         return proxyAuthHandler;
    337     }
    338 
    339 
    340     public synchronized void setProxyAuthenticationHandler(
    341             final AuthenticationHandler proxyAuthHandler) {
    342         this.proxyAuthHandler = proxyAuthHandler;
    343     }
    344 
    345 
    346     public synchronized final CookieStore getCookieStore() {
    347         if (cookieStore == null) {
    348             cookieStore = createCookieStore();
    349         }
    350         return cookieStore;
    351     }
    352 
    353 
    354     public synchronized void setCookieStore(final CookieStore cookieStore) {
    355         this.cookieStore = cookieStore;
    356     }
    357 
    358 
    359     public synchronized final CredentialsProvider getCredentialsProvider() {
    360         if (credsProvider == null) {
    361             credsProvider = createCredentialsProvider();
    362         }
    363         return credsProvider;
    364     }
    365 
    366 
    367     public synchronized void setCredentialsProvider(final CredentialsProvider credsProvider) {
    368         this.credsProvider = credsProvider;
    369     }
    370 
    371 
    372     public synchronized final HttpRoutePlanner getRoutePlanner() {
    373         if (this.routePlanner == null) {
    374             this.routePlanner = createHttpRoutePlanner();
    375         }
    376         return this.routePlanner;
    377     }
    378 
    379 
    380     public synchronized void setRoutePlanner(final HttpRoutePlanner routePlanner) {
    381         this.routePlanner = routePlanner;
    382     }
    383 
    384 
    385     public synchronized final UserTokenHandler getUserTokenHandler() {
    386         if (this.userTokenHandler == null) {
    387             this.userTokenHandler = createUserTokenHandler();
    388         }
    389         return this.userTokenHandler;
    390     }
    391 
    392 
    393     public synchronized void setUserTokenHandler(final UserTokenHandler userTokenHandler) {
    394         this.userTokenHandler = userTokenHandler;
    395     }
    396 
    397 
    398     protected synchronized final BasicHttpProcessor getHttpProcessor() {
    399         if (httpProcessor == null) {
    400             httpProcessor = createHttpProcessor();
    401         }
    402         return httpProcessor;
    403     }
    404 
    405 
    406     public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp) {
    407         getHttpProcessor().addInterceptor(itcp);
    408     }
    409 
    410 
    411     public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp, int index) {
    412         getHttpProcessor().addInterceptor(itcp, index);
    413     }
    414 
    415 
    416     public synchronized HttpResponseInterceptor getResponseInterceptor(int index) {
    417         return getHttpProcessor().getResponseInterceptor(index);
    418     }
    419 
    420 
    421     public synchronized int getResponseInterceptorCount() {
    422         return getHttpProcessor().getResponseInterceptorCount();
    423     }
    424 
    425 
    426     public synchronized void clearResponseInterceptors() {
    427         getHttpProcessor().clearResponseInterceptors();
    428     }
    429 
    430 
    431     public void removeResponseInterceptorByClass(Class<? extends HttpResponseInterceptor> clazz) {
    432         getHttpProcessor().removeResponseInterceptorByClass(clazz);
    433     }
    434 
    435 
    436     public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp) {
    437         getHttpProcessor().addInterceptor(itcp);
    438     }
    439 
    440 
    441     public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp, int index) {
    442         getHttpProcessor().addInterceptor(itcp, index);
    443     }
    444 
    445 
    446     public synchronized HttpRequestInterceptor getRequestInterceptor(int index) {
    447         return getHttpProcessor().getRequestInterceptor(index);
    448     }
    449 
    450 
    451     public synchronized int getRequestInterceptorCount() {
    452         return getHttpProcessor().getRequestInterceptorCount();
    453     }
    454 
    455 
    456     public synchronized void clearRequestInterceptors() {
    457         getHttpProcessor().clearRequestInterceptors();
    458     }
    459 
    460 
    461     public void removeRequestInterceptorByClass(Class<? extends HttpRequestInterceptor> clazz) {
    462         getHttpProcessor().removeRequestInterceptorByClass(clazz);
    463     }
    464 
    465 
    466     // non-javadoc, see interface HttpClient
    467     public final HttpResponse execute(HttpUriRequest request)
    468         throws IOException, ClientProtocolException {
    469 
    470         return execute(request, (HttpContext) null);
    471     }
    472 
    473 
    474     /**
    475      * Maps to {@link HttpClient#execute(HttpHost,HttpRequest,HttpContext)
    476      *                           execute(target, request, context)}.
    477      * The target is determined from the URI of the request.
    478      *
    479      * @param request   the request to execute
    480      * @param context   the request-specific execution context,
    481      *                  or <code>null</code> to use a default context
    482      */
    483     public final HttpResponse execute(HttpUriRequest request,
    484                                       HttpContext context)
    485         throws IOException, ClientProtocolException {
    486 
    487         if (request == null) {
    488             throw new IllegalArgumentException
    489                 ("Request must not be null.");
    490         }
    491 
    492         return execute(determineTarget(request), request, context);
    493     }
    494 
    495     private HttpHost determineTarget(HttpUriRequest request) {
    496         // A null target may be acceptable if there is a default target.
    497         // Otherwise, the null target is detected in the director.
    498         HttpHost target = null;
    499 
    500         URI requestURI = request.getURI();
    501         if (requestURI.isAbsolute()) {
    502             target = new HttpHost(
    503                     requestURI.getHost(),
    504                     requestURI.getPort(),
    505                     requestURI.getScheme());
    506         }
    507         return target;
    508     }
    509 
    510     // non-javadoc, see interface HttpClient
    511     public final HttpResponse execute(HttpHost target, HttpRequest request)
    512         throws IOException, ClientProtocolException {
    513 
    514         return execute(target, request, (HttpContext) null);
    515     }
    516 
    517 
    518     // non-javadoc, see interface HttpClient
    519     public final HttpResponse execute(HttpHost target, HttpRequest request,
    520                                       HttpContext context)
    521         throws IOException, ClientProtocolException {
    522 
    523         if (request == null) {
    524             throw new IllegalArgumentException
    525                 ("Request must not be null.");
    526         }
    527         // a null target may be acceptable, this depends on the route planner
    528         // a null context is acceptable, default context created below
    529 
    530         HttpContext execContext = null;
    531         RequestDirector director = null;
    532 
    533         // Initialize the request execution context making copies of
    534         // all shared objects that are potentially threading unsafe.
    535         synchronized (this) {
    536 
    537             HttpContext defaultContext = createHttpContext();
    538             if (context == null) {
    539                 execContext = defaultContext;
    540             } else {
    541                 execContext = new DefaultedHttpContext(context, defaultContext);
    542             }
    543             // Create a director for this request
    544             director = createClientRequestDirector(
    545                     getRequestExecutor(),
    546                     getConnectionManager(),
    547                     getConnectionReuseStrategy(),
    548                     getConnectionKeepAliveStrategy(),
    549                     getRoutePlanner(),
    550                     getHttpProcessor().copy(),
    551                     getHttpRequestRetryHandler(),
    552                     getRedirectHandler(),
    553                     getTargetAuthenticationHandler(),
    554                     getProxyAuthenticationHandler(),
    555                     getUserTokenHandler(),
    556                     determineParams(request));
    557         }
    558 
    559         try {
    560             return director.execute(target, request, execContext);
    561         } catch(HttpException httpException) {
    562             throw new ClientProtocolException(httpException);
    563         }
    564     } // execute
    565 
    566 
    567     protected RequestDirector createClientRequestDirector(
    568             final HttpRequestExecutor requestExec,
    569             final ClientConnectionManager conman,
    570             final ConnectionReuseStrategy reustrat,
    571             final ConnectionKeepAliveStrategy kastrat,
    572             final HttpRoutePlanner rouplan,
    573             final HttpProcessor httpProcessor,
    574             final HttpRequestRetryHandler retryHandler,
    575             final RedirectHandler redirectHandler,
    576             final AuthenticationHandler targetAuthHandler,
    577             final AuthenticationHandler proxyAuthHandler,
    578             final UserTokenHandler stateHandler,
    579             final HttpParams params) {
    580         return new DefaultRequestDirector(
    581                 requestExec,
    582                 conman,
    583                 reustrat,
    584                 kastrat,
    585                 rouplan,
    586                 httpProcessor,
    587                 retryHandler,
    588                 redirectHandler,
    589                 targetAuthHandler,
    590                 proxyAuthHandler,
    591                 stateHandler,
    592                 params);
    593     }
    594 
    595     /**
    596      * Obtains parameters for executing a request.
    597      * The default implementation in this class creates a new
    598      * {@link ClientParamsStack} from the request parameters
    599      * and the client parameters.
    600      * <br/>
    601      * This method is called by the default implementation of
    602      * {@link #execute(HttpHost,HttpRequest,HttpContext)}
    603      * to obtain the parameters for the
    604      * {@link DefaultRequestDirector}.
    605      *
    606      * @param req    the request that will be executed
    607      *
    608      * @return  the parameters to use
    609      */
    610     protected HttpParams determineParams(HttpRequest req) {
    611         return new ClientParamsStack
    612             (null, getParams(), req.getParams(), null);
    613     }
    614 
    615 
    616     // non-javadoc, see interface HttpClient
    617     public <T> T execute(
    618             final HttpUriRequest request,
    619             final ResponseHandler<? extends T> responseHandler)
    620                 throws IOException, ClientProtocolException {
    621         return execute(request, responseHandler, null);
    622     }
    623 
    624 
    625     // non-javadoc, see interface HttpClient
    626     public <T> T execute(
    627             final HttpUriRequest request,
    628             final ResponseHandler<? extends T> responseHandler,
    629             final HttpContext context)
    630                 throws IOException, ClientProtocolException {
    631         HttpHost target = determineTarget(request);
    632         return execute(target, request, responseHandler, context);
    633     }
    634 
    635 
    636     // non-javadoc, see interface HttpClient
    637     public <T> T execute(
    638             final HttpHost target,
    639             final HttpRequest request,
    640             final ResponseHandler<? extends T> responseHandler)
    641                 throws IOException, ClientProtocolException {
    642         return execute(target, request, responseHandler, null);
    643     }
    644 
    645 
    646     // non-javadoc, see interface HttpClient
    647     public <T> T execute(
    648             final HttpHost target,
    649             final HttpRequest request,
    650             final ResponseHandler<? extends T> responseHandler,
    651             final HttpContext context)
    652                 throws IOException, ClientProtocolException {
    653         if (responseHandler == null) {
    654             throw new IllegalArgumentException
    655                 ("Response handler must not be null.");
    656         }
    657 
    658         HttpResponse response = execute(target, request, context);
    659 
    660         T result;
    661         try {
    662             result = responseHandler.handleResponse(response);
    663         } catch (Throwable t) {
    664             HttpEntity entity = response.getEntity();
    665             if (entity != null) {
    666                 try {
    667                     entity.consumeContent();
    668                 } catch (Throwable t2) {
    669                     // Log this exception. The original exception is more
    670                     // important and will be thrown to the caller.
    671                     this.log.warn("Error consuming content after an exception.", t2);
    672                 }
    673             }
    674 
    675             if (t instanceof Error) {
    676                 throw (Error) t;
    677             }
    678 
    679             if (t instanceof RuntimeException) {
    680                 throw (RuntimeException) t;
    681             }
    682 
    683             if (t instanceof IOException) {
    684                 throw (IOException) t;
    685             }
    686 
    687             throw new UndeclaredThrowableException(t);
    688         }
    689 
    690         // Handling the response was successful. Ensure that the content has
    691         // been fully consumed.
    692         HttpEntity entity = response.getEntity();
    693         if (entity != null) {
    694             // Let this exception go to the caller.
    695             entity.consumeContent();
    696         }
    697 
    698         return result;
    699     }
    700 
    701 
    702 } // class AbstractHttpClient
    703