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