You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2012/06/15 17:15:12 UTC

svn commit: r1350650 - in /httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src: main/java/org/apache/http/client/protocol/ main/java/org/apache/http/impl/client/ main/java/org/apache/http/impl/client/exec/ test/java/org/apache/http/...

Author: olegk
Date: Fri Jun 15 15:15:11 2012
New Revision: 1350650

URL: http://svn.apache.org/viewvc?rev=1350650&view=rev
Log:
Replaced DefaultRequestDirector with a new implementation based on chain of request handlers

Added:
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java   (with props)
Modified:
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java
    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/DefaultHttpClient.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ProtocolFacade.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RedirectFacade.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RetryFacade.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java
    httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestWrapper.java

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/client/protocol/ResponseContentEncoding.java Fri Jun 15 15:15:11 2012
@@ -83,9 +83,11 @@ public class ResponseContentEncoding imp
                     String codecname = codec.getName().toLowerCase(Locale.US);
                     if ("gzip".equals(codecname) || "x-gzip".equals(codecname)) {
                         response.setEntity(new GzipDecompressingEntity(response.getEntity()));
+                        uncompressed = true;
                         break;
                     } else if ("deflate".equals(codecname)) {
                         response.setEntity(new DeflateDecompressingEntity(response.getEntity()));
+                        uncompressed = true;
                         break;
                     } else if ("identity".equals(codecname)) {
 

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=1350650&r1=1350649&r2=1350650&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 Fri Jun 15 15:15:11 2012
@@ -992,8 +992,7 @@ public abstract class AbstractHttpClient
             final AuthenticationStrategy proxyAuthStrategy,
             final UserTokenHandler userTokenHandler,
             final HttpParams params) {
-        return new DefaultRequestDirector(
-                log,
+        return new RequestDirectorAdaptor(
                 requestExec,
                 conman,
                 reustrat,

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=1350650&r1=1350649&r2=1350650&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 Fri Jun 15 15:15:11 2012
@@ -34,8 +34,6 @@ 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;
@@ -219,8 +217,6 @@ public class DefaultHttpClient extends A
         httpproc.addInterceptor(new ResponseProcessCookies());
         // HTTP authentication interceptors
         httpproc.addInterceptor(new RequestAuthCache());
-        httpproc.addInterceptor(new RequestTargetAuthentication());
-        httpproc.addInterceptor(new RequestProxyAuthentication());
         return httpproc;
     }
 

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java Fri Jun 15 15:15:11 2012
@@ -126,8 +126,10 @@ import org.apache.http.util.EntityUtils;
  * </ul>
  *
  * @since 4.0
+ * 
+ * @deprecated (4.3)
  */
-@SuppressWarnings("deprecation")
+@Deprecated
 @NotThreadSafe // e.g. managedConn
 public class DefaultRequestDirector implements RequestDirector {
 

Added: 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=1350650&view=auto
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java (added)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java Fri Jun 15 15:15:11 2012
@@ -0,0 +1,126 @@
+/*
+ * ====================================================================
+ * 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
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl.client;
+
+import java.io.IOException;
+
+import org.apache.http.ConnectionReuseStrategy;
+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.AuthenticationStrategy;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.client.RedirectStrategy;
+import org.apache.http.client.RequestDirector;
+import org.apache.http.client.UserTokenHandler;
+import org.apache.http.client.methods.HttpExecutionAware;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.conn.routing.HttpRoutePlanner;
+import org.apache.http.impl.client.exec.HttpClientRequestExecutor;
+import org.apache.http.impl.client.exec.HttpRequestWrapper;
+import org.apache.http.impl.client.exec.MainRequestExecutor;
+import org.apache.http.impl.client.exec.ProtocolFacade;
+import org.apache.http.impl.client.exec.RedirectFacade;
+import org.apache.http.impl.client.exec.RetryFacade;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestExecutor;
+
+@ThreadSafe
+class RequestDirectorAdaptor implements RequestDirector {
+
+    private final HttpRoutePlanner routePlanner;
+    private final HttpParams params;
+    private final HttpClientRequestExecutor execChain;
+
+    public RequestDirectorAdaptor(
+            final HttpRequestExecutor requestExecutor,
+            final ClientConnectionManager connman,
+            final ConnectionReuseStrategy reustrat,
+            final ConnectionKeepAliveStrategy kastrat,
+            final HttpRoutePlanner rouplan,
+            final HttpProcessor httpProcessor,
+            final HttpRequestRetryHandler retryHandler,
+            final RedirectStrategy redirectStrategy,
+            final AuthenticationStrategy targetAuthStrategy,
+            final AuthenticationStrategy proxyAuthStrategy,
+            final UserTokenHandler userTokenHandler,
+            final HttpParams params) {
+        this.routePlanner = rouplan;
+        this.params = params;
+        MainRequestExecutor mainExecutor = new MainRequestExecutor(
+                requestExecutor, connman, reustrat, kastrat, targetAuthStrategy,
+                proxyAuthStrategy, userTokenHandler, params);
+        ProtocolFacade protocolFacade = new ProtocolFacade(mainExecutor, httpProcessor);
+        RetryFacade retryFacade = new RetryFacade(protocolFacade, retryHandler);
+        RedirectFacade redirectFacade = new RedirectFacade(retryFacade, rouplan, redirectStrategy);
+        this.execChain = redirectFacade;
+    }
+
+    public HttpResponse execute(
+            HttpHost target,
+            final HttpRequest request,
+            final HttpContext context) throws HttpException, IOException {
+        if (target == null) {
+            target = (HttpHost) this.params.getParameter(ClientPNames.DEFAULT_HOST);
+        }
+        if (target == null) {
+            throw new IllegalStateException("Target host must not be null, or set in parameters");
+        }
+        HttpRequestWrapper wrapper = HttpRequestWrapper.wrap(request);
+        wrapper.setParams(this.params);
+        HttpHost virtualHost = (HttpHost) this.params.getParameter(ClientPNames.VIRTUAL_HOST);
+        wrapper.setVirtualHost(virtualHost);
+        HttpExecutionAware execListner = null;
+        if (request instanceof HttpExecutionAware) {
+            execListner = (HttpExecutionAware) request;
+            if (execListner.isAborted()) {
+                throw new RequestAbortedException("Request aborted");
+            }
+        }
+        HttpRoute route = this.routePlanner.determineRoute(target, request, 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());
+        }
+
+        return this.execChain.execute(route, wrapper, context, execListner);
+    }
+
+}

Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/RequestDirectorAdaptor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/MainRequestExecutor.java Fri Jun 15 15:15:11 2012
@@ -45,7 +45,6 @@ import org.apache.http.annotation.Thread
 import org.apache.http.auth.AUTH;
 import org.apache.http.auth.AuthProtocolState;
 import org.apache.http.auth.AuthState;
-import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.AuthenticationStrategy;
 import org.apache.http.client.NonRepeatableRequestException;
 import org.apache.http.client.UserTokenHandler;
@@ -62,7 +61,6 @@ import org.apache.http.conn.routing.Http
 import org.apache.http.conn.routing.HttpRouteDirector;
 import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.entity.BufferedHttpEntity;
-import org.apache.http.impl.auth.BasicScheme;
 import org.apache.http.impl.client.HttpAuthenticator;
 import org.apache.http.impl.client.RequestAbortedException;
 import org.apache.http.impl.client.TunnelRefusedException;
@@ -111,10 +109,10 @@ public class MainRequestExecutor impleme
 
     private final Log log = LogFactory.getLog(getClass());
 
+    private final HttpRequestExecutor requestExecutor;
     private final ClientConnectionManager connManager;
     private final ConnectionReuseStrategy reuseStrategy;
     private final ConnectionKeepAliveStrategy keepAliveStrategy;
-    private final HttpRequestExecutor requestExec;
     private final HttpProcessor proxyHttpProcessor;
     private final AuthenticationStrategy targetAuthStrategy;
     private final AuthenticationStrategy proxyAuthStrategy;
@@ -123,6 +121,7 @@ public class MainRequestExecutor impleme
     private final HttpParams params;
 
     public MainRequestExecutor(
+            final HttpRequestExecutor requestExecutor,
             final ClientConnectionManager connManager,
             final ConnectionReuseStrategy reuseStrategy,
             final ConnectionKeepAliveStrategy keepAliveStrategy,
@@ -130,6 +129,9 @@ public class MainRequestExecutor impleme
             final AuthenticationStrategy proxyAuthStrategy,
             final UserTokenHandler userTokenHandler,
             final HttpParams params) {
+        if (requestExecutor == null) {
+            throw new IllegalArgumentException("HTTP request executor may not be null");
+        }
         if (connManager == null) {
             throw new IllegalArgumentException("Client connection manager may not be null");
         }
@@ -152,11 +154,11 @@ public class MainRequestExecutor impleme
             throw new IllegalArgumentException("HTTP parameters may not be null");
         }
         this.authenticator      = new HttpAuthenticator();
-        this.requestExec        = new HttpRequestExecutor();
         this.proxyHttpProcessor = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                 new RequestClientConnControl(),
                 new RequestUserAgent()
         } );
+        this.requestExecutor    = requestExecutor;
         this.connManager        = connManager;
         this.reuseStrategy      = reuseStrategy;
         this.keepAliveStrategy  = keepAliveStrategy;
@@ -190,12 +192,6 @@ public class MainRequestExecutor impleme
             proxyAuthState = new AuthState();
         }
 
-        String userinfo = request.getURI().getUserInfo();
-        if (userinfo != null) {
-            targetAuthState.update(
-                    new BasicScheme(), new UsernamePasswordCredentials(userinfo));
-        }
-
         Object userToken = context.getAttribute(ClientContext.USER_TOKEN);
 
         ClientConnectionRequest connRequest = connManager.requestConnection(route, userToken);
@@ -285,7 +281,7 @@ public class MainRequestExecutor impleme
                     this.authenticator.generateAuthResponse(request, proxyAuthState, context);
                 }
 
-                response = requestExec.execute(request, managedConn, context);
+                response = requestExecutor.execute(request, managedConn, context);
                 response.setParams(params);
 
                 // The connection is in or can be brought to a re-usable state.
@@ -459,7 +455,7 @@ public class MainRequestExecutor impleme
         HttpRequest connect = createConnectRequest(route, context);
         connect.setParams(this.params);
 
-        this.requestExec.preProcess(connect, this.proxyHttpProcessor, context);
+        this.requestExecutor.preProcess(connect, this.proxyHttpProcessor, context);
 
         for (;;) {
             if (!managedConn.isOpen()) {
@@ -469,7 +465,7 @@ public class MainRequestExecutor impleme
             connect.removeHeaders(AUTH.PROXY_AUTH_RESP);
             this.authenticator.generateAuthResponse(connect, proxyAuthState, context);
 
-            response = this.requestExec.execute(connect, managedConn, context);
+            response = this.requestExecutor.execute(connect, managedConn, context);
             response.setParams(this.params);
 
             int status = response.getStatusLine().getStatusCode();

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ProtocolFacade.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ProtocolFacade.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ProtocolFacade.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/ProtocolFacade.java Fri Jun 15 15:15:11 2012
@@ -38,9 +38,13 @@ import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
 import org.apache.http.ProtocolException;
 import org.apache.http.annotation.ThreadSafe;
+import org.apache.http.auth.AuthState;
+import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.methods.HttpExecutionAware;
+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.impl.auth.BasicScheme;
 import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
@@ -112,7 +116,16 @@ public class ProtocolFacade implements H
             throw new IllegalArgumentException("HTTP context may not be null");
         }
         HttpHost target = route.getTargetHost();
-        HttpHost proxy = route.getProxyHost();
+
+        // Get user info from the URI
+        AuthState targetAuthState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
+        if (targetAuthState != null) {
+            String userinfo = request.getURI().getUserInfo();
+            if (userinfo != null) {
+                targetAuthState.update(
+                        new BasicScheme(), new UsernamePasswordCredentials(userinfo));
+            }
+        }
 
         // Re-write request URI if needed
         rewriteRequestURI(request, route);
@@ -128,20 +141,20 @@ public class ProtocolFacade implements H
                 this.log.debug("Using virtual host" + virtualHost);
             }
         }
-        
+
         // Run request protocol interceptors
         context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, virtualHost != null ? virtualHost : target);
-        context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy);
+        context.setAttribute(ClientContext.ROUTE, route);
         context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
 
         this.httpProcessor.process(request, context);
-        
+
         HttpResponse response = this.requestExecutor.execute(route, request, context, execAware);
-        
+
         // Run response protocol interceptors
         context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
         this.httpProcessor.process(response, context);
-        
+
         return response;
     }
 

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RedirectFacade.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RedirectFacade.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RedirectFacade.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RedirectFacade.java Fri Jun 15 15:15:11 2012
@@ -32,6 +32,7 @@ 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;
@@ -50,6 +51,7 @@ import org.apache.http.conn.routing.Http
 import org.apache.http.conn.routing.HttpRoutePlanner;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
 
 /**
  * The following parameters can be used to customize the behavior of this
@@ -105,60 +107,72 @@ public class RedirectFacade implements H
             throw new IllegalArgumentException("HTTP context may not be null");
         }
         HttpParams params = request.getParams();
-        int redirectCount = 0;
         int maxRedirects = params.getIntParameter(ClientPNames.MAX_REDIRECTS, 100);
         HttpRoute currentRoute = route;
         HttpRequestWrapper currentRequest = request;
-        for (;;) {
+        for (int redirectCount = 0;;) {
             HttpResponse response = requestExecutor.execute(
                     currentRoute, currentRequest, context, execAware);
-            if (HttpClientParams.isRedirecting(params) &&
-                    this.redirectStrategy.isRedirected(currentRequest, response, context)) {
+            try {
+                if (HttpClientParams.isRedirecting(params) &&
+                        this.redirectStrategy.isRedirected(currentRequest, response, context)) {
 
-                if (redirectCount >= maxRedirects) {
-                    throw new RedirectException("Maximum redirects ("+ maxRedirects + ") exceeded");
-                }
-                redirectCount++;
+                    if (redirectCount >= maxRedirects) {
+                        throw new RedirectException("Maximum redirects ("+ maxRedirects + ") exceeded");
+                    }
+                    redirectCount++;
 
-                HttpRequest redirect = this.redirectStrategy.getRedirect(currentRequest, response, context);
-                currentRequest = HttpRequestWrapper.wrap(redirect);
-                currentRequest.setHeaders(request.getAllHeaders());
-                currentRequest.setParams(params);
-
-                URI uri = currentRequest.getURI();
-                if (uri.getHost() == null) {
-                    throw new ProtocolException("Redirect URI does not specify a valid host name: " +
-                            uri);
-                }
+                    HttpRequest redirect = this.redirectStrategy.getRedirect(currentRequest, response, context);
+                    HttpRequest original = currentRequest.getOriginal();
+                    currentRequest = HttpRequestWrapper.wrap(redirect);
+                    currentRequest.setHeaders(original.getAllHeaders());
+                    currentRequest.setParams(params);
+
+                    URI uri = currentRequest.getURI();
+                    if (uri.getHost() == null) {
+                        throw new ProtocolException("Redirect URI does not specify a valid host name: " +
+                                uri);
+                    }
 
-                HttpHost newTarget = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
+                    HttpHost newTarget = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
 
-                // Reset virtual host and auth states if redirecting to another host
-                if (!currentRoute.getTargetHost().equals(newTarget)) {
-                    AuthState targetAuthState = (AuthState) context.getAttribute(
-                            ClientContext.TARGET_AUTH_STATE);
-                    if (targetAuthState != null) {
-                        this.log.debug("Resetting target auth state");
-                        targetAuthState.reset();
-                    }
-                    AuthState proxyAuthState = (AuthState) context.getAttribute(
-                            ClientContext.PROXY_AUTH_STATE);
-                    if (proxyAuthState != null) {
-                        AuthScheme authScheme = proxyAuthState.getAuthScheme();
-                        if (authScheme != null && authScheme.isConnectionBased()) {
-                            this.log.debug("Resetting proxy auth state");
-                            proxyAuthState.reset();
+                    // Reset virtual host and auth states if redirecting to another host
+                    if (!currentRoute.getTargetHost().equals(newTarget)) {
+                        AuthState targetAuthState = (AuthState) context.getAttribute(
+                                ClientContext.TARGET_AUTH_STATE);
+                        if (targetAuthState != null) {
+                            this.log.debug("Resetting target auth state");
+                            targetAuthState.reset();
                         }
+                        AuthState proxyAuthState = (AuthState) context.getAttribute(
+                                ClientContext.PROXY_AUTH_STATE);
+                        if (proxyAuthState != null) {
+                            AuthScheme authScheme = proxyAuthState.getAuthScheme();
+                            if (authScheme != null && authScheme.isConnectionBased()) {
+                                this.log.debug("Resetting proxy auth state");
+                                proxyAuthState.reset();
+                            }
+                        }
+                        request.setVirtualHost(null);
                     }
-                    request.setVirtualHost(null);
-                }
 
-                currentRoute = this.routePlanner.determineRoute(newTarget, currentRequest, context);
-                if (this.log.isDebugEnabled()) {
-                    this.log.debug("Redirecting to '" + uri + "' via " + currentRoute);
+                    currentRoute = this.routePlanner.determineRoute(newTarget, currentRequest, context);
+                    if (this.log.isDebugEnabled()) {
+                        this.log.debug("Redirecting to '" + uri + "' via " + currentRoute);
+                    }
+                    HttpEntity entity = response.getEntity();
+                    if (entity != null) {
+                        EntityUtils.consume(entity);
+                    }
+                } else {
+                    return response;
+                }
+            } catch (HttpException ex) {
+                HttpEntity entity = response.getEntity();
+                if (entity != null) {
+                    EntityUtils.consume(entity);
                 }
-            } else {
-                return response;
+                throw ex;
             }
         }
     }

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RetryFacade.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RetryFacade.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RetryFacade.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/main/java/org/apache/http/impl/client/exec/RetryFacade.java Fri Jun 15 15:15:11 2012
@@ -48,7 +48,7 @@ import org.apache.http.protocol.HttpCont
  */
 @NotThreadSafe // e.g. managedConn
 public class RetryFacade implements HttpClientRequestExecutor {
-    
+
     private final Log log = LogFactory.getLog(getClass());
 
     private final HttpClientRequestExecutor requestExecutor;
@@ -82,9 +82,9 @@ public class RetryFacade implements Http
             throw new IllegalArgumentException("HTTP context may not be null");
         }
         Header[] origheaders = request.getAllHeaders();
-        for (int execCount = 0;; execCount++) {
+        for (int execCount = 1;; execCount++) {
             try {
-                this.requestExecutor.execute(route, request, context, execAware);
+                return this.requestExecutor.execute(route, request, context, execAware);
             } catch (IOException ex) {
                 HttpRequest original = request.getOriginal();
                 if (original instanceof HttpUriRequest && ((HttpUriRequest) original).isAborted()) {
@@ -114,4 +114,4 @@ public class RetryFacade implements Http
         }
     }
 
-}
\ No newline at end of file
+}

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultClientRequestDirector.java Fri Jun 15 15:15:11 2012
@@ -316,7 +316,6 @@ public class TestDefaultClientRequestDir
 
         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
 
-        Assert.assertTrue(reqWrapper instanceof RequestWrapper);
         Header[] myheaders = reqWrapper.getHeaders("my-header");
         Assert.assertNotNull(myheaders);
         Assert.assertEquals(1, myheaders.length);

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestRetryHandler.java Fri Jun 15 15:15:11 2012
@@ -32,7 +32,7 @@ import java.net.UnknownHostException;
 
 import org.apache.http.client.HttpRequestRetryHandler;
 import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.conn.ClientConnectionManager;
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.scheme.Scheme;
@@ -63,7 +63,7 @@ public class TestRequestRetryHandler {
         TestHttpRequestRetryHandler testRetryHandler = new TestHttpRequestRetryHandler();
         client.setHttpRequestRetryHandler(testRetryHandler);
 
-        HttpRequestBase request = new HttpGet("http://www.example.com/");
+        HttpUriRequest request = new HttpGet("http://www.example.com/");
 
         HttpConnectionParams.setConnectionTimeout(request.getParams(), 1);
         try {

Modified: httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestWrapper.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestWrapper.java?rev=1350650&r1=1350649&r2=1350650&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestWrapper.java (original)
+++ httpcomponents/httpclient/branches/decorator-refactoring/httpclient/src/test/java/org/apache/http/impl/client/TestRequestWrapper.java Fri Jun 15 15:15:11 2012
@@ -93,7 +93,6 @@ public class TestRequestWrapper extends 
 
         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
 
-        Assert.assertTrue(reqWrapper instanceof RequestWrapper);
         Assert.assertEquals("/path", reqWrapper.getRequestLine().getUri());
     }
 
@@ -115,7 +114,6 @@ public class TestRequestWrapper extends 
 
         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
 
-        Assert.assertTrue(reqWrapper instanceof RequestWrapper);
         Assert.assertEquals("/", reqWrapper.getRequestLine().getUri());
     }