Return-Path: X-Original-To: apmail-hc-commits-archive@www.apache.org Delivered-To: apmail-hc-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 49B7E917B for ; Thu, 21 Jun 2012 14:49:44 +0000 (UTC) Received: (qmail 65572 invoked by uid 500); 21 Jun 2012 14:49:44 -0000 Delivered-To: apmail-hc-commits-archive@hc.apache.org Received: (qmail 65517 invoked by uid 500); 21 Jun 2012 14:49:43 -0000 Mailing-List: contact commits-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list commits@hc.apache.org Received: (qmail 65507 invoked by uid 99); 21 Jun 2012 14:49:43 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 21 Jun 2012 14:49:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 21 Jun 2012 14:49:40 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 684772388A33 for ; Thu, 21 Jun 2012 14:49:20 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1352545 - in /httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client: ./ exec/ Date: Thu, 21 Jun 2012 14:49:19 -0000 To: commits@hc.apache.org From: olegk@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120621144920.684772388A33@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: olegk Date: Thu Jun 21 14:49:19 2012 New Revision: 1352545 URL: http://svn.apache.org/viewvc?rev=1352545&view=rev Log: Initial implementation of HttpClientBuilder Added: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractBasicHttpClient.java - copied, changed from r1351453, httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java (with props) httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java (contents, props changed) - copied, changed from r1351453, httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java Removed: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/ContentEncodingHttpClient.java httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DecompressingHttpClient.java httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/SystemDefaultHttpClient.java httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainClientExec.java Copied: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractBasicHttpClient.java (from r1351453, httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java) URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractBasicHttpClient.java?p2=httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractBasicHttpClient.java&p1=httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java&r1=1351453&r2=1352545&rev=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractBasicHttpClient.java Thu Jun 21 14:49:19 2012 @@ -25,7 +25,7 @@ * */ -package org.apache.http.impl.client.exec; +package org.apache.http.impl.client; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; @@ -34,26 +34,15 @@ import java.net.URI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpEntity; -import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.annotation.ThreadSafe; -import org.apache.http.auth.AuthState; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; -import org.apache.http.client.methods.HttpExecutionAware; import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.params.ClientPNames; -import org.apache.http.client.protocol.ClientContext; import org.apache.http.client.utils.URIUtils; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.conn.routing.HttpRoutePlanner; -import org.apache.http.impl.client.ClientParamsStack; -import org.apache.http.impl.client.RequestAbortedException; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; @@ -61,28 +50,11 @@ import org.apache.http.util.EntityUtils; * @since 4.3 */ @ThreadSafe -public abstract class BasicHttpClient implements HttpClient { +public abstract class AbstractBasicHttpClient implements HttpClient { private final Log log = LogFactory.getLog(getClass()); - private final ClientExecChain requestExecutor; - private final HttpRoutePlanner routePlanner; - - public BasicHttpClient( - final ClientExecChain requestExecutor, - final HttpRoutePlanner routePlanner) { - super(); - if (requestExecutor == null) { - throw new IllegalArgumentException("HTTP client request executor may not be null"); - } - if (routePlanner == null) { - throw new IllegalArgumentException("HTTP route planner may not be null"); - } - this.requestExecutor = requestExecutor; - this.routePlanner = routePlanner; - } - - public final HttpResponse execute( + public HttpResponse execute( final HttpUriRequest request, final HttpContext context) throws IOException, ClientProtocolException { if (request == null) { @@ -107,65 +79,17 @@ public abstract class BasicHttpClient im return target; } - private HttpRoute determineRoute( - final HttpHost target, - final HttpRequest request, - final HttpContext context) throws HttpException { - HttpHost host = target; - if (host == null) { - host = (HttpHost) request.getParams().getParameter(ClientPNames.DEFAULT_HOST); - } - if (host == null) { - throw new IllegalStateException("Target host may not be null"); - } - return this.routePlanner.determineRoute(host, request, context); - } - - private void setupContext(final HttpContext context) { - if (context.getAttribute(ClientContext.TARGET_AUTH_STATE) == null) { - context.setAttribute(ClientContext.TARGET_AUTH_STATE, new AuthState()); - } - if (context.getAttribute(ClientContext.PROXY_AUTH_STATE) == null) { - context.setAttribute(ClientContext.PROXY_AUTH_STATE, new AuthState()); - } + public HttpResponse execute( + final HttpUriRequest request) throws IOException, ClientProtocolException { + return execute(request, (HttpContext) null); } - public final HttpResponse execute( + public HttpResponse execute( final HttpHost target, final HttpRequest request) throws IOException, ClientProtocolException { return execute(target, request, (HttpContext) null); } - public final HttpResponse execute( - final HttpHost target, - final HttpRequest request, - final HttpContext context) throws IOException, ClientProtocolException { - if (request == null) { - throw new IllegalArgumentException("Request must not be null."); - } - try { - HttpContext execContext = context != null ? context : new BasicHttpContext(); - setupContext(context); - HttpParams params = new ClientParamsStack(null, getParams(), request.getParams(), null); - HttpHost virtualHost = (HttpHost) params.getParameter(ClientPNames.VIRTUAL_HOST); - - HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(request); - wrapper.setParams(params); - wrapper.setVirtualHost(virtualHost); - HttpExecutionAware execListner = null; - if (request instanceof HttpExecutionAware) { - execListner = (HttpExecutionAware) request; - if (execListner.isAborted()) { - throw new RequestAbortedException("Request aborted"); - } - } - HttpRoute route = determineRoute(target, request, context); - return this.requestExecutor.execute(route, wrapper, execContext, execListner); - } catch (HttpException httpException) { - throw new ClientProtocolException(httpException); - } - } - public T execute(final HttpUriRequest request, final ResponseHandler responseHandler) throws IOException, ClientProtocolException { Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java?rev=1352545&r1=1352544&r2=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java Thu Jun 21 14:49:19 2012 @@ -29,12 +29,10 @@ package org.apache.http.impl.client; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; -import java.net.URI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.ConnectionReuseStrategy; -import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; @@ -56,14 +54,11 @@ import org.apache.http.client.HttpReques import org.apache.http.client.RedirectHandler; import org.apache.http.client.RedirectStrategy; import org.apache.http.client.RequestDirector; -import org.apache.http.client.ResponseHandler; import org.apache.http.client.UserTokenHandler; -import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.params.AuthPolicy; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.CookiePolicy; import org.apache.http.client.protocol.ClientContext; -import org.apache.http.client.utils.URIUtils; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionManagerFactory; import org.apache.http.conn.ConnectionKeepAliveStrategy; @@ -94,7 +89,6 @@ import org.apache.http.protocol.HttpCont import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.protocol.ImmutableHttpProcessor; -import org.apache.http.util.EntityUtils; /** * Base class for {@link HttpClient} implementations. This class acts as @@ -180,9 +174,8 @@ import org.apache.http.util.EntityUtils; * * @since 4.0 */ -@SuppressWarnings("deprecation") @ThreadSafe -public abstract class AbstractHttpClient implements HttpClient { +public abstract class AbstractHttpClient extends AbstractBasicHttpClient { private final Log log = LogFactory.getLog(getClass()); @@ -270,6 +263,7 @@ public abstract class AbstractHttpClient protected AbstractHttpClient( final ClientConnectionManager conman, final HttpParams params) { + super(); defaultParams = params; connManager = conman; } // constructor @@ -778,55 +772,6 @@ public abstract class AbstractHttpClient protocolProcessor = null; } - public final HttpResponse execute(HttpUriRequest request) - throws IOException, ClientProtocolException { - - return execute(request, (HttpContext) null); - } - - /** - * Maps to {@link HttpClient#execute(HttpHost,HttpRequest,HttpContext) - * execute(target, request, context)}. - * The target is determined from the URI of the request. - * - * @param request the request to execute - * @param context the request-specific execution context, - * or null to use a default context - */ - public final HttpResponse execute(HttpUriRequest request, - HttpContext context) - throws IOException, ClientProtocolException { - - if (request == null) { - throw new IllegalArgumentException - ("Request must not be null."); - } - - return execute(determineTarget(request), request, context); - } - - private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException { - // A null target may be acceptable if there is a default target. - // Otherwise, the null target is detected in the director. - HttpHost target = null; - - URI requestURI = request.getURI(); - if (requestURI.isAbsolute()) { - target = URIUtils.extractHost(requestURI); - if (target == null) { - throw new ClientProtocolException( - "URI does not specify a valid host name: " + requestURI); - } - } - return target; - } - - public final HttpResponse execute(HttpHost target, HttpRequest request) - throws IOException, ClientProtocolException { - - return execute(target, request, (HttpContext) null); - } - public final HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException { @@ -1027,69 +972,4 @@ public abstract class AbstractHttpClient (null, getParams(), req.getParams(), null); } - public T execute( - final HttpUriRequest request, - final ResponseHandler responseHandler) - throws IOException, ClientProtocolException { - return execute(request, responseHandler, null); - } - - public T execute( - final HttpUriRequest request, - final ResponseHandler responseHandler, - final HttpContext context) - throws IOException, ClientProtocolException { - HttpHost target = determineTarget(request); - return execute(target, request, responseHandler, context); - } - - public T execute( - final HttpHost target, - final HttpRequest request, - final ResponseHandler responseHandler) - throws IOException, ClientProtocolException { - return execute(target, request, responseHandler, null); - } - - public T execute( - final HttpHost target, - final HttpRequest request, - final ResponseHandler responseHandler, - final HttpContext context) - throws IOException, ClientProtocolException { - if (responseHandler == null) { - throw new IllegalArgumentException - ("Response handler must not be null."); - } - - HttpResponse response = execute(target, request, context); - - T result; - try { - result = responseHandler.handleResponse(response); - } catch (Exception t) { - HttpEntity entity = response.getEntity(); - try { - EntityUtils.consume(entity); - } catch (Exception t2) { - // Log this exception. The original exception is more - // important and will be thrown to the caller. - this.log.warn("Error consuming content after an exception.", t2); - } - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } - if (t instanceof IOException) { - throw (IOException) t; - } - throw new UndeclaredThrowableException(t); - } - - // Handling the response was successful. Ensure that the content has - // been fully consumed. - HttpEntity entity = response.getEntity(); - EntityUtils.consume(entity); - return result; - } - } Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/ContentEncodingHttpClient.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/ContentEncodingHttpClient.java?rev=1352545&r1=1352544&r2=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/ContentEncodingHttpClient.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/ContentEncodingHttpClient.java Thu Jun 21 14:49:19 2012 @@ -47,6 +47,8 @@ import org.apache.http.protocol.BasicHtt * responses in compressed or uncompressed form. * * @since 4.1 + * + * @deprecated (4.2) use {@link HttpClientBuilder} */ @Deprecated @ThreadSafe // since DefaultHttpClient is Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DecompressingHttpClient.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DecompressingHttpClient.java?rev=1352545&r1=1352544&r2=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DecompressingHttpClient.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DecompressingHttpClient.java Thu Jun 21 14:49:19 2012 @@ -70,7 +70,10 @@ import org.apache.http.util.EntityUtils; * in either order and still have cacheable responses be cached.

* * @since 4.2 + * + * @deprecated (4.3) use {@link HttpClientBuilder} */ +@Deprecated public class DecompressingHttpClient implements HttpClient { private HttpClient backend; Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java?rev=1352545&r1=1352544&r2=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultHttpClient.java Thu Jun 21 14:49:19 2012 @@ -34,6 +34,8 @@ import org.apache.http.client.protocol.R import org.apache.http.client.protocol.RequestAuthCache; import org.apache.http.client.protocol.RequestClientConnControl; import org.apache.http.client.protocol.RequestDefaultHeaders; +import org.apache.http.client.protocol.RequestProxyAuthentication; +import org.apache.http.client.protocol.RequestTargetAuthentication; import org.apache.http.client.protocol.ResponseProcessCookies; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.params.CoreConnectionPNames; Added: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java?rev=1352545&view=auto ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java (added) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java Thu Jun 21 14:49:19 2012 @@ -0,0 +1,530 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.ProxySelector; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.BackoffManager; +import org.apache.http.client.ConnectionBackoffStrategy; +import org.apache.http.client.HttpClient; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.RedirectStrategy; +import org.apache.http.client.UserTokenHandler; +import org.apache.http.client.protocol.RequestAcceptEncoding; +import org.apache.http.client.protocol.RequestAddCookies; +import org.apache.http.client.protocol.RequestAuthCache; +import org.apache.http.client.protocol.RequestClientConnControl; +import org.apache.http.client.protocol.RequestDefaultHeaders; +import org.apache.http.client.protocol.ResponseContentEncoding; +import org.apache.http.client.protocol.ResponseProcessCookies; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ConnectionKeepAliveStrategy; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.impl.DefaultConnectionReuseStrategy; +import org.apache.http.impl.NoConnectionReuseStrategy; +import org.apache.http.impl.client.exec.BackoffStrategyExec; +import org.apache.http.impl.client.exec.ClientExecChain; +import org.apache.http.impl.client.exec.MainClientExec; +import org.apache.http.impl.client.exec.ProtocolExec; +import org.apache.http.impl.client.exec.RedirectExec; +import org.apache.http.impl.client.exec.RetryExec; +import org.apache.http.impl.client.exec.InternalHttpClient; +import org.apache.http.impl.conn.DefaultHttpRoutePlanner; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.impl.conn.ProxySelectorRoutePlanner; +import org.apache.http.impl.conn.SchemeRegistryFactory; +import org.apache.http.protocol.HttpProcessor; +import org.apache.http.protocol.HttpRequestExecutor; +import org.apache.http.protocol.ImmutableHttpProcessor; +import org.apache.http.protocol.RequestContent; +import org.apache.http.protocol.RequestExpectContinue; +import org.apache.http.protocol.RequestTargetHost; +import org.apache.http.protocol.RequestUserAgent; + +/** + * {@link HttpClient} builder. + *

+ * The following system properties are taken into account by this class + * if the {@link #useSystemProperties()} method is called. + *

    + *
  • ssl.TrustManagerFactory.algorithm
  • + *
  • javax.net.ssl.trustStoreType
  • + *
  • javax.net.ssl.trustStore
  • + *
  • javax.net.ssl.trustStoreProvider
  • + *
  • javax.net.ssl.trustStorePassword
  • + *
  • java.home
  • + *
  • ssl.KeyManagerFactory.algorithm
  • + *
  • javax.net.ssl.keyStoreType
  • + *
  • javax.net.ssl.keyStore
  • + *
  • javax.net.ssl.keyStoreProvider
  • + *
  • javax.net.ssl.keyStorePassword
  • + *
  • http.proxyHost
  • + *
  • http.proxyPort
  • + *
  • http.nonProxyHosts
  • + *
  • http.keepAlive
  • + *
  • http.maxConnections
  • + *
+ *

+ * @since 4.3 + */ +@NotThreadSafe +public class HttpClientBuilder { + + private HttpRequestExecutor requestExec; + private ClientConnectionManager connManager; + private ConnectionReuseStrategy reuseStrategy; + private ConnectionKeepAliveStrategy keepAliveStrategy; + private AuthenticationStrategy targetAuthStrategy; + private AuthenticationStrategy proxyAuthStrategy; + private UserTokenHandler userTokenHandler; + + private HttpProcessor httpprocessor; + private LinkedList requestFirst; + private LinkedList requestLast; + private LinkedList responseFirst; + private LinkedList responseLast; + + private HttpRequestRetryHandler retryHandler; + + private HttpRoutePlanner routePlanner; + private RedirectStrategy redirectStrategy; + + private ConnectionBackoffStrategy connectionBackoffStrategy; + private BackoffManager backoffManager; + + private boolean systemProperties; + private boolean laxRedirects; + private boolean redirectHandlingDisabled; + private boolean automaticRetriesDisabled; + private boolean contentCompressionDisabled; + private boolean cookieManagementDisabled; + private boolean authCachingDisabled; + + public HttpClientBuilder() { + super(); + } + + public final HttpRequestExecutor getRequestExecutor() { + return requestExec; + } + + public final HttpClientBuilder setRequestExecutor(final HttpRequestExecutor requestExec) { + this.requestExec = requestExec; + return this; + } + + public final ClientConnectionManager getConnectionManager() { + return connManager; + } + + public final HttpClientBuilder setConnectionManager(final ClientConnectionManager connManager) { + this.connManager = connManager; + return this; + } + + public final ConnectionReuseStrategy getConnectionReuseStrategy() { + return reuseStrategy; + } + + public final HttpClientBuilder setConnectionReuseStrategy( + final ConnectionReuseStrategy reuseStrategy) { + this.reuseStrategy = reuseStrategy; + return this; + } + + public final ConnectionKeepAliveStrategy getKeepAliveStrategy() { + return keepAliveStrategy; + } + + public final HttpClientBuilder setKeepAliveStrategy( + final ConnectionKeepAliveStrategy keepAliveStrategy) { + this.keepAliveStrategy = keepAliveStrategy; + return this; + } + + public final UserTokenHandler getUserTokenHandler() { + return userTokenHandler; + } + + public final HttpClientBuilder setUserTokenHandler(final UserTokenHandler userTokenHandler) { + this.userTokenHandler = userTokenHandler; + return this; + } + + public final AuthenticationStrategy getTargetAuthenticationStrategy() { + return targetAuthStrategy; + } + + public final HttpClientBuilder setTargetAuthenticationStrategy( + final AuthenticationStrategy targetAuthStrategy) { + this.targetAuthStrategy = targetAuthStrategy; + return this; + } + + public final AuthenticationStrategy getProxyAuthenticationStrategy() { + return proxyAuthStrategy; + } + + public final HttpClientBuilder setProxyAuthenticationStrategy( + final AuthenticationStrategy proxyAuthStrategy) { + this.proxyAuthStrategy = proxyAuthStrategy; + return this; + } + + public final HttpProcessor getHttpProcessor() { + return httpprocessor; + } + + public final HttpClientBuilder setHttpProcessor(final HttpProcessor httpprocessor) { + this.httpprocessor = httpprocessor; + return this; + } + + public final HttpClientBuilder addResponseInterceptorFirst( + final HttpResponseInterceptor itcp) { + if (itcp == null) { + return this; + } + if (responseFirst == null) { + responseFirst = new LinkedList(); + } + responseFirst.addFirst(itcp); + return this; + } + + public final HttpClientBuilder addResponseInterceptorLast( + final HttpResponseInterceptor itcp) { + if (itcp == null) { + return this; + } + if (responseLast == null) { + responseLast = new LinkedList(); + } + responseLast.addLast(itcp); + return this; + } + + public final HttpClientBuilder addRequestInterceptorFirst( + final HttpRequestInterceptor itcp) { + if (itcp == null) { + return this; + } + if (requestFirst == null) { + requestFirst = new LinkedList(); + } + requestFirst.addFirst(itcp); + return this; + } + + public final HttpClientBuilder addRequestInterceptorLast( + final HttpRequestInterceptor itcp) { + if (itcp == null) { + return this; + } + if (requestLast == null) { + requestLast = new LinkedList(); + } + requestLast.addLast(itcp); + return this; + } + + public final HttpRequestRetryHandler getRetryHandler() { + return retryHandler; + } + + public final HttpClientBuilder setRetryHandler(final HttpRequestRetryHandler retryHandler) { + this.retryHandler = retryHandler; + return this; + } + + public final HttpRoutePlanner getRoutePlanner() { + return routePlanner; + } + + public final HttpClientBuilder setRoutePlanner(final HttpRoutePlanner routePlanner) { + this.routePlanner = routePlanner; + return this; + } + + public final RedirectStrategy getRedirectStrategy() { + return redirectStrategy; + } + + public final HttpClientBuilder setRedirectStrategy(final RedirectStrategy redirectStrategy) { + this.redirectStrategy = redirectStrategy; + return this; + } + + public final ConnectionBackoffStrategy getConnectionBackoffStrategy() { + return connectionBackoffStrategy; + } + + public final HttpClientBuilder setConnectionBackoffStrategy( + final ConnectionBackoffStrategy connectionBackoffStrategy) { + this.connectionBackoffStrategy = connectionBackoffStrategy; + return this; + } + + public final BackoffManager getBackoffManager() { + return backoffManager; + } + + public final HttpClientBuilder setBackoffManager(final BackoffManager backoffManager) { + this.backoffManager = backoffManager; + return this; + } + + public final HttpClientBuilder disableRedirectHandling() { + redirectHandlingDisabled = true; + return this; + } + + public final HttpClientBuilder disableAutomaticRetries() { + automaticRetriesDisabled = true; + return this; + } + + public final HttpClientBuilder useSystemProperties() { + systemProperties = true; + return this; + } + + public final HttpClientBuilder useLaxRedirects() { + laxRedirects = true; + return this; + } + + protected ClientExecChain decorateMainExec(final ClientExecChain mainExec) { + return mainExec; + } + + protected ClientExecChain decorateProtocolExec(final ClientExecChain protocolExec) { + return protocolExec; + } + + public HttpClient build() { + // Create main request executor + HttpRequestExecutor requestExec = getRequestExecutor(); + if (requestExec == null) { + requestExec = new HttpRequestExecutor(); + } + ClientConnectionManager connManager = getConnectionManager(); + if (connManager == null) { + PoolingClientConnectionManager poolingmgr = new PoolingClientConnectionManager( + systemProperties ? SchemeRegistryFactory.createSystemDefault() : + SchemeRegistryFactory.createDefault()); + if (systemProperties) { + String s = System.getProperty("http.keepAlive"); + if ("true".equalsIgnoreCase(s)) { + s = System.getProperty("http.maxConnections", "5"); + int max = Integer.parseInt(s); + poolingmgr.setDefaultMaxPerRoute(max); + poolingmgr.setMaxTotal(2 * max); + } + } + connManager = poolingmgr; + } + ConnectionReuseStrategy reuseStrategy = getConnectionReuseStrategy(); + if (reuseStrategy != null) { + if (systemProperties) { + String s = System.getProperty("http.keepAlive"); + if ("true".equalsIgnoreCase(s)) { + reuseStrategy = new DefaultConnectionReuseStrategy(); + } else { + reuseStrategy = new NoConnectionReuseStrategy(); + } + } else { + reuseStrategy = new DefaultConnectionReuseStrategy(); + } + } + ConnectionKeepAliveStrategy keepAliveStrategy = getKeepAliveStrategy(); + if (keepAliveStrategy == null) { + keepAliveStrategy = new DefaultConnectionKeepAliveStrategy(); + } + AuthenticationStrategy targetAuthStrategy = getTargetAuthenticationStrategy(); + if (targetAuthStrategy == null) { + targetAuthStrategy = new TargetAuthenticationStrategy(); + } + AuthenticationStrategy proxyAuthStrategy = getProxyAuthenticationStrategy(); + if (proxyAuthStrategy == null) { + proxyAuthStrategy = new ProxyAuthenticationStrategy(); + } + UserTokenHandler userTokenHandler = getUserTokenHandler(); + if (userTokenHandler == null) { + userTokenHandler = new DefaultUserTokenHandler(); + } + ClientExecChain execChain = new MainClientExec( + requestExec, + connManager, + reuseStrategy, + keepAliveStrategy, + targetAuthStrategy, + proxyAuthStrategy, + userTokenHandler); + + execChain = decorateMainExec(execChain); + + HttpProcessor httpprocessor = getHttpProcessor(); + if (httpprocessor == null) { + ListBuilder reqlb = new ListBuilder(); + reqlb.addAll(requestFirst); + reqlb.addAll( + new RequestDefaultHeaders(), + new RequestContent(), + new RequestTargetHost(), + new RequestClientConnControl(), + new RequestUserAgent(), + new RequestExpectContinue()); + if (!cookieManagementDisabled) { + reqlb.add(new RequestAddCookies()); + } + if (!contentCompressionDisabled) { + reqlb.add(new RequestAcceptEncoding()); + } + if (!authCachingDisabled) { + reqlb.add(new RequestAuthCache()); + } + reqlb.addAll(requestLast); + + ListBuilder reslb = new ListBuilder(); + reslb.addAll(responseFirst); + if (!cookieManagementDisabled) { + reslb.add(new ResponseProcessCookies()); + } + if (!contentCompressionDisabled) { + reslb.add(new ResponseContentEncoding()); + } + reslb.addAll(responseLast); + List reqincps = reqlb.build(); + List resincps = reslb.build(); + httpprocessor = new ImmutableHttpProcessor( + reqincps.toArray(new HttpRequestInterceptor[reqincps.size()]), + resincps.toArray(new HttpResponseInterceptor[resincps.size()])); + } + execChain = new ProtocolExec(execChain, httpprocessor); + + execChain = decorateProtocolExec(execChain); + + // Add request retry executor, if not disabled + if (!automaticRetriesDisabled) { + HttpRequestRetryHandler retryHandler = getRetryHandler(); + if (retryHandler == null) { + retryHandler = new DefaultHttpRequestRetryHandler(); + } + execChain = new RetryExec(execChain, retryHandler); + } + + // Add redirect executor, if not disabled + HttpRoutePlanner routePlanner = getRoutePlanner(); + if (routePlanner == null) { + if (systemProperties) { + routePlanner = new ProxySelectorRoutePlanner( + getConnectionManager().getSchemeRegistry(), + ProxySelector.getDefault()); + } else { + routePlanner = new DefaultHttpRoutePlanner(connManager.getSchemeRegistry()); + } + } + if (!redirectHandlingDisabled) { + RedirectStrategy redirectStrategy = getRedirectStrategy(); + if (redirectStrategy == null) { + if (laxRedirects) { + redirectStrategy = new LaxRedirectStrategy(); + } else { + redirectStrategy = new DefaultRedirectStrategy(); + } + } + execChain = new RedirectExec(execChain, routePlanner, redirectStrategy); + } + + // Optionally, add connection back-off executor + BackoffManager backoffManager = getBackoffManager(); + ConnectionBackoffStrategy connectionBackoffStrategy = getConnectionBackoffStrategy(); + if (backoffManager != null && connectionBackoffStrategy != null) { + execChain = new BackoffStrategyExec(execChain, connectionBackoffStrategy, backoffManager); + } + + return new InternalHttpClient(execChain, connManager, routePlanner, null); + } + + static class ListBuilder { + + private final LinkedList list; + private final Set> uniqueClasses; + + ListBuilder() { + this.list = new LinkedList(); + this.uniqueClasses = new HashSet>(); + } + + public void add(final E e) { + if (e == null) { + return; + } + if (!this.uniqueClasses.contains(e.getClass())) { + this.list.addFirst(e); + this.uniqueClasses.add(e.getClass()); + } + } + + public void addAll(final Collection c) { + if (c == null) { + return; + } + for (E e: c) { + add(e); + } + } + + public void addAll(E... c) { + if (c == null) { + return; + } + for (E e: c) { + add(e); + } + } + + public List build() { + return new ArrayList(this.list); + } + + } + +} Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java?rev=1352545&r1=1352544&r2=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java Thu Jun 21 14:49:19 2012 @@ -82,8 +82,8 @@ class RequestDirectorAdaptor implements this.routePlanner = rouplan; this.params = params; MainClientExec mainExecutor = new MainClientExec( - requestExecutor, connman, reustrat, kastrat, targetAuthStrategy, - proxyAuthStrategy, userTokenHandler, params); + requestExecutor, connman, reustrat, kastrat, + targetAuthStrategy, proxyAuthStrategy, userTokenHandler); ProtocolExec protocolFacade = new ProtocolExec(mainExecutor, httpProcessor); RetryExec retryFacade = new RetryExec(protocolFacade, retryHandler); RedirectExec redirectFacade = new RedirectExec(retryFacade, rouplan, redirectStrategy); Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/SystemDefaultHttpClient.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/SystemDefaultHttpClient.java?rev=1352545&r1=1352544&r2=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/SystemDefaultHttpClient.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/SystemDefaultHttpClient.java Thu Jun 21 14:49:19 2012 @@ -101,8 +101,11 @@ import org.apache.http.params.HttpParams *

* * @since 4.2 + * + * @deprecated (4.3) use {@link HttpClientBuilder} */ @ThreadSafe +@Deprecated public class SystemDefaultHttpClient extends DefaultHttpClient { public SystemDefaultHttpClient(final HttpParams params) { Copied: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java (from r1351453, httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java) URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java?p2=httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java&p1=httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java&r1=1351453&r2=1352545&rev=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/BasicHttpClient.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java Thu Jun 21 14:49:19 2012 @@ -28,12 +28,7 @@ package org.apache.http.impl.client.exec; import java.io.IOException; -import java.lang.reflect.UndeclaredThrowableException; -import java.net.URI; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpEntity; import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; @@ -41,70 +36,50 @@ import org.apache.http.HttpResponse; import org.apache.http.annotation.ThreadSafe; import org.apache.http.auth.AuthState; import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpExecutionAware; -import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.protocol.ClientContext; -import org.apache.http.client.utils.URIUtils; +import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.impl.client.AbstractBasicHttpClient; import org.apache.http.impl.client.ClientParamsStack; import org.apache.http.impl.client.RequestAbortedException; import org.apache.http.params.HttpParams; +import org.apache.http.params.SyncBasicHttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; -import org.apache.http.util.EntityUtils; /** * @since 4.3 */ @ThreadSafe -public abstract class BasicHttpClient implements HttpClient { +public class InternalHttpClient extends AbstractBasicHttpClient { - private final Log log = LogFactory.getLog(getClass()); - - private final ClientExecChain requestExecutor; + private final ClientExecChain execChain; + private final ClientConnectionManager connManager; private final HttpRoutePlanner routePlanner; + private final HttpParams params; - public BasicHttpClient( - final ClientExecChain requestExecutor, - final HttpRoutePlanner routePlanner) { + public InternalHttpClient( + final ClientExecChain execChain, + final ClientConnectionManager connManager, + final HttpRoutePlanner routePlanner, + final HttpParams params) { super(); - if (requestExecutor == null) { - throw new IllegalArgumentException("HTTP client request executor may not be null"); + if (execChain == null) { + throw new IllegalArgumentException("HTTP client exec chain may not be null"); + } + if (connManager == null) { + throw new IllegalArgumentException("HTTP connection manager may not be null"); } if (routePlanner == null) { throw new IllegalArgumentException("HTTP route planner may not be null"); } - this.requestExecutor = requestExecutor; + this.execChain = execChain; + this.connManager = connManager; this.routePlanner = routePlanner; - } - - public final HttpResponse execute( - final HttpUriRequest request, - final HttpContext context) throws IOException, ClientProtocolException { - if (request == null) { - throw new IllegalArgumentException("Request must not be null."); - } - return execute(determineTarget(request), request, context); - } - - private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException { - // A null target may be acceptable if there is a default target. - // Otherwise, the null target is detected in the director. - HttpHost target = null; - - URI requestURI = request.getURI(); - if (requestURI.isAbsolute()) { - target = URIUtils.extractHost(requestURI); - if (target == null) { - throw new ClientProtocolException("URI does not specify a valid host name: " - + requestURI); - } - } - return target; + this.params = params != null ? params : new SyncBasicHttpParams(); } private HttpRoute determineRoute( @@ -130,13 +105,7 @@ public abstract class BasicHttpClient im } } - public final HttpResponse execute( - final HttpHost target, - final HttpRequest request) throws IOException, ClientProtocolException { - return execute(target, request, (HttpContext) null); - } - - public final HttpResponse execute( + public HttpResponse execute( final HttpHost target, final HttpRequest request, final HttpContext context) throws IOException, ClientProtocolException { @@ -160,66 +129,18 @@ public abstract class BasicHttpClient im } } HttpRoute route = determineRoute(target, request, context); - return this.requestExecutor.execute(route, wrapper, execContext, execListner); + return this.execChain.execute(route, wrapper, execContext, execListner); } catch (HttpException httpException) { throw new ClientProtocolException(httpException); } } - public T execute(final HttpUriRequest request, - final ResponseHandler responseHandler) throws IOException, - ClientProtocolException { - return execute(request, responseHandler, null); - } - - public T execute(final HttpUriRequest request, - final ResponseHandler responseHandler, final HttpContext context) - throws IOException, ClientProtocolException { - HttpHost target = determineTarget(request); - return execute(target, request, responseHandler, context); + public HttpParams getParams() { + return this.params; } - public T execute(final HttpHost target, final HttpRequest request, - final ResponseHandler responseHandler) throws IOException, - ClientProtocolException { - return execute(target, request, responseHandler, null); - } - - public T execute(final HttpHost target, final HttpRequest request, - final ResponseHandler responseHandler, final HttpContext context) - throws IOException, ClientProtocolException { - if (responseHandler == null) { - throw new IllegalArgumentException("Response handler must not be null."); - } - - HttpResponse response = execute(target, request, context); - - T result; - try { - result = responseHandler.handleResponse(response); - } catch (Exception t) { - HttpEntity entity = response.getEntity(); - try { - EntityUtils.consume(entity); - } catch (Exception t2) { - // Log this exception. The original exception is more - // important and will be thrown to the caller. - this.log.warn("Error consuming content after an exception.", t2); - } - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } - if (t instanceof IOException) { - throw (IOException) t; - } - throw new UndeclaredThrowableException(t); - } - - // Handling the response was successful. Ensure that the content has - // been fully consumed. - HttpEntity entity = response.getEntity(); - EntityUtils.consume(entity); - return result; + public ClientConnectionManager getConnectionManager() { + return this.connManager; } } Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/InternalHttpClient.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainClientExec.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainClientExec.java?rev=1352545&r1=1352544&r2=1352545&view=diff ============================================================================== --- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainClientExec.java (original) +++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainClientExec.java Thu Jun 21 14:49:19 2012 @@ -118,7 +118,8 @@ public class MainClientExec implements C private final AuthenticationStrategy proxyAuthStrategy; private final HttpAuthenticator authenticator; private final UserTokenHandler userTokenHandler; - private final HttpParams params; + private final HttpRouteDirector routeDirector; + public MainClientExec( final HttpRequestExecutor requestExecutor, @@ -127,8 +128,7 @@ public class MainClientExec implements C final ConnectionKeepAliveStrategy keepAliveStrategy, final AuthenticationStrategy targetAuthStrategy, final AuthenticationStrategy proxyAuthStrategy, - final UserTokenHandler userTokenHandler, - final HttpParams params) { + final UserTokenHandler userTokenHandler) { if (requestExecutor == null) { throw new IllegalArgumentException("HTTP request executor may not be null"); } @@ -150,14 +150,12 @@ public class MainClientExec implements C if (userTokenHandler == null) { throw new IllegalArgumentException("User token handler may not be null"); } - if (params == null) { - throw new IllegalArgumentException("HTTP parameters may not be null"); - } this.authenticator = new HttpAuthenticator(); this.proxyHttpProcessor = new ImmutableHttpProcessor(new HttpRequestInterceptor[] { new RequestClientConnControl(), new RequestUserAgent() } ); + this.routeDirector = new BasicRouteDirector(); this.requestExecutor = requestExecutor; this.connManager = connManager; this.reuseStrategy = reuseStrategy; @@ -165,7 +163,6 @@ public class MainClientExec implements C this.targetAuthStrategy = targetAuthStrategy; this.proxyAuthStrategy = proxyAuthStrategy; this.userTokenHandler = userTokenHandler; - this.params = params; } public HttpResponseWrapper execute( @@ -192,6 +189,8 @@ public class MainClientExec implements C proxyAuthState = new AuthState(); } + HttpParams params = request.getParams(); + Object userToken = context.getAttribute(ClientContext.USER_TOKEN); ClientConnectionRequest connRequest = connManager.requestConnection(route, userToken); @@ -251,7 +250,7 @@ public class MainClientExec implements C } try { - establishRoute(proxyAuthState, managedConn, route, context); + establishRoute(proxyAuthState, managedConn, route, request, context); } catch (TunnelRefusedException ex) { if (this.log.isDebugEnabled()) { this.log.debug(ex.getMessage()); @@ -379,25 +378,25 @@ public class MainClientExec implements C final AuthState proxyAuthState, final ManagedClientConnection managedConn, final HttpRoute route, + final HttpRequest request, final HttpContext context) throws HttpException, IOException { - - HttpRouteDirector rowdy = new BasicRouteDirector(); + HttpParams params = request.getParams(); int step; do { HttpRoute fact = managedConn.getRoute(); - step = rowdy.nextStep(route, fact); + step = this.routeDirector.nextStep(route, fact); switch (step) { case HttpRouteDirector.CONNECT_TARGET: case HttpRouteDirector.CONNECT_PROXY: - managedConn.open(route, context, this.params); + managedConn.open(route, context, params); break; case HttpRouteDirector.TUNNEL_TARGET: { - boolean secure = createTunnelToTarget(proxyAuthState, managedConn, route, context); + boolean secure = createTunnelToTarget(proxyAuthState, managedConn, route, request, context); this.log.debug("Tunnel to target created."); - managedConn.tunnelTarget(secure, this.params); + managedConn.tunnelTarget(secure, params); } break; case HttpRouteDirector.TUNNEL_PROXY: { @@ -408,13 +407,11 @@ public class MainClientExec implements C final int hop = fact.getHopCount()-1; // the hop to establish boolean secure = createTunnelToProxy(route, hop, context); this.log.debug("Tunnel to proxy created."); - managedConn.tunnelProxy(route.getHopTarget(hop), - secure, this.params); + managedConn.tunnelProxy(route.getHopTarget(hop), secure, params); } break; - case HttpRouteDirector.LAYER_PROTOCOL: - managedConn.layerProtocol(context, this.params); + managedConn.layerProtocol(context, params); break; case HttpRouteDirector.UNREACHABLE: @@ -443,26 +440,43 @@ public class MainClientExec implements C final AuthState proxyAuthState, final ManagedClientConnection managedConn, final HttpRoute route, + final HttpRequest request, final HttpContext context) throws HttpException, IOException { + HttpParams params = request.getParams(); + HttpHost target = route.getTargetHost(); HttpHost proxy = route.getProxyHost(); HttpResponse response = null; - HttpRequest connect = createConnectRequest(route, context); - connect.setParams(this.params); + String host = target.getHostName(); + int port = target.getPort(); + if (port < 0) { + Scheme scheme = connManager.getSchemeRegistry(). + getScheme(target.getSchemeName()); + port = scheme.getDefaultPort(); + } + + StringBuilder buffer = new StringBuilder(host.length() + 6); + buffer.append(host); + buffer.append(':'); + buffer.append(Integer.toString(port)); + + String authority = buffer.toString(); + ProtocolVersion ver = HttpProtocolParams.getVersion(params); + HttpRequest connect = new BasicHttpRequest("CONNECT", authority, ver); + connect.setParams(params); this.requestExecutor.preProcess(connect, this.proxyHttpProcessor, context); for (;;) { if (!managedConn.isOpen()) { - managedConn.open(route, context, this.params); + managedConn.open(route, context, params); } connect.removeHeaders(AUTH.PROXY_AUTH_RESP); this.authenticator.generateAuthResponse(connect, proxyAuthState, context); response = this.requestExecutor.execute(connect, managedConn, context); - response.setParams(this.params); int status = response.getStatusLine().getStatusCode(); if (status < 200) { @@ -470,7 +484,7 @@ public class MainClientExec implements C response.getStatusLine()); } - if (HttpClientParams.isAuthenticating(this.params)) { + if (HttpClientParams.isAuthenticating(params)) { if (this.authenticator.isAuthenticationRequested(proxy, response, this.proxyAuthStrategy, proxyAuthState, context)) { if (this.authenticator.handleAuthChallenge(proxy, response, @@ -539,38 +553,6 @@ public class MainClientExec implements C throw new HttpException("Proxy chains are not supported."); } - /** - * Creates the CONNECT request for tunnelling. - * Called by {@link #createTunnelToTarget createTunnelToTarget}. - */ - private HttpRequest createConnectRequest( - final HttpRoute route, - final HttpContext context) { - // see RFC 2817, section 5.2 and - // INTERNET-DRAFT: Tunneling TCP based protocols through - // Web proxy servers - - HttpHost target = route.getTargetHost(); - - String host = target.getHostName(); - int port = target.getPort(); - if (port < 0) { - Scheme scheme = connManager.getSchemeRegistry(). - getScheme(target.getSchemeName()); - port = scheme.getDefaultPort(); - } - - StringBuilder buffer = new StringBuilder(host.length() + 6); - buffer.append(host); - buffer.append(':'); - buffer.append(Integer.toString(port)); - - String authority = buffer.toString(); - ProtocolVersion ver = HttpProtocolParams.getVersion(params); - HttpRequest req = new BasicHttpRequest("CONNECT", authority, ver); - return req; - } - private boolean needAuthentication( final AuthState targetAuthState, final AuthState proxyAuthState,