示例#1
0
        /// <summary>
        /// Returns the response body as a String if the response was successful (a
        /// 2xx status code).
        /// </summary>
        /// <remarks>
        /// Returns the response body as a String if the response was successful (a
        /// 2xx status code). If no response body exists, this returns null. If the
        /// response was unsuccessful (&gt;= 300 status code), throws an
        /// <see cref="Apache.Http.Client.HttpResponseException">Apache.Http.Client.HttpResponseException
        ///     </see>
        /// .
        /// </remarks>
        /// <exception cref="Apache.Http.Client.HttpResponseException"></exception>
        /// <exception cref="System.IO.IOException"></exception>
        public virtual string HandleResponse(HttpResponse response)
        {
            StatusLine statusLine = response.GetStatusLine();
            HttpEntity entity     = response.GetEntity();

            if (statusLine.GetStatusCode() >= 300)
            {
                EntityUtils.Consume(entity);
                throw new HttpResponseException(statusLine.GetStatusCode(), statusLine.GetReasonPhrase
                                                    ());
            }
            return(entity == null ? null : EntityUtils.ToString(entity));
        }
示例#2
0
 /// <summary>Unconditionally close a response.</summary>
 /// <remarks>
 /// Unconditionally close a response.
 /// <p>
 /// Example Code:
 /// <pre>
 /// HttpResponse httpResponse = null;
 /// try {
 /// httpResponse = httpClient.execute(httpGet);
 /// } catch (Exception e) {
 /// // error handling
 /// } finally {
 /// HttpClientUtils.closeQuietly(httpResponse);
 /// }
 /// </pre>
 /// </remarks>
 /// <param name="response">
 /// the HttpResponse to release resources, may be null or already
 /// closed.
 /// </param>
 /// <since>4.2</since>
 public static void CloseQuietly(HttpResponse response)
 {
     if (response != null)
     {
         HttpEntity entity = response.GetEntity();
         if (entity != null)
         {
             try
             {
                 EntityUtils.Consume(entity);
             }
             catch (IOException)
             {
             }
         }
     }
 }
示例#3
0
 /// <summary>Unconditionally close a response.</summary>
 /// <remarks>
 /// Unconditionally close a response.
 /// <p>
 /// Example Code:
 /// <pre>
 /// HttpResponse httpResponse = null;
 /// try {
 /// httpResponse = httpClient.execute(httpGet);
 /// } catch (Exception e) {
 /// // error handling
 /// } finally {
 /// HttpClientUtils.closeQuietly(httpResponse);
 /// }
 /// </pre>
 /// </remarks>
 /// <param name="response">
 /// the HttpResponse to release resources, may be null or already
 /// closed.
 /// </param>
 /// <since>4.3</since>
 public static void CloseQuietly(CloseableHttpResponse response)
 {
     if (response != null)
     {
         try
         {
             try
             {
                 EntityUtils.Consume(response.GetEntity());
             }
             finally
             {
                 response.Close();
             }
         }
         catch (IOException)
         {
         }
     }
 }
        /// <summary>
        /// Executes a request using the default context and processes the
        /// response using the given response handler.
        /// </summary>
        /// <remarks>
        /// Executes a request using the default context and processes the
        /// response using the given response handler. The content entity associated
        /// with the response is fully consumed and the underlying connection is
        /// released back to the connection manager automatically in all cases
        /// relieving individual
        /// <see cref="Apache.Http.Client.ResponseHandler{T}">Apache.Http.Client.ResponseHandler&lt;T&gt;
        ///     </see>
        /// s from having to manage
        /// resource deallocation internally.
        /// </remarks>
        /// <param name="target">
        /// the target host for the request.
        /// Implementations may accept <code>null</code>
        /// if they can still determine a route, for example
        /// to a default target or by inspecting the request.
        /// </param>
        /// <param name="request">the request to execute</param>
        /// <param name="responseHandler">the response handler</param>
        /// <param name="context">
        /// the context to use for the execution, or
        /// <code>null</code> to use the default context
        /// </param>
        /// <returns>the response object as generated by the response handler.</returns>
        /// <exception cref="System.IO.IOException">in case of a problem or the connection was aborted
        ///     </exception>
        /// <exception cref="Apache.Http.Client.ClientProtocolException">in case of an http protocol error
        ///     </exception>
        public virtual T Execute <T, _T1>(HttpHost target, IHttpRequest request, ResponseHandler
                                          <_T1> responseHandler, HttpContext context) where _T1 : T
        {
            Args.NotNull(responseHandler, "Response handler");
            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 is RuntimeException)
                {
                    throw (RuntimeException)t;
                }
                if (t is IOException)
                {
                    throw (IOException)t;
                }
                throw new UndeclaredThrowableException(t);
            }
            // Handling the response was successful. Ensure that the content has
            // been fully consumed.
            HttpEntity entity_1 = response.GetEntity();

            EntityUtils.Consume(entity_1);
            return(result);
        }
示例#5
0
        /// <summary>
        /// Handles receives one HTTP request over the given connection within the
        /// given execution context and sends a response back to the client.
        /// </summary>
        /// <remarks>
        /// Handles receives one HTTP request over the given connection within the
        /// given execution context and sends a response back to the client.
        /// </remarks>
        /// <param name="conn">the active connection to the client</param>
        /// <param name="context">the actual execution context.</param>
        /// <exception cref="System.IO.IOException">in case of an I/O error.</exception>
        /// <exception cref="Org.Apache.Http.HttpException">
        /// in case of HTTP protocol violation or a processing
        /// problem.
        /// </exception>
        public virtual void HandleRequest(HttpServerConnection conn, HttpContext context)
        {
            context.SetAttribute(HttpCoreContext.HttpConnection, conn);
            HttpResponse response = null;

            try
            {
                IHttpRequest request = conn.ReceiveRequestHeader();
                if (request is HttpEntityEnclosingRequest)
                {
                    if (((HttpEntityEnclosingRequest)request).ExpectContinue())
                    {
                        response = this.responseFactory.NewHttpResponse(HttpVersion.Http11, HttpStatus.ScContinue
                                                                        , context);
                        if (this.expectationVerifier != null)
                        {
                            try
                            {
                                this.expectationVerifier.Verify(request, response, context);
                            }
                            catch (HttpException ex)
                            {
                                response = this.responseFactory.NewHttpResponse(HttpVersion.Http10, HttpStatus.ScInternalServerError
                                                                                , context);
                                HandleException(ex, response);
                            }
                        }
                        if (response.GetStatusLine().GetStatusCode() < 200)
                        {
                            // Send 1xx response indicating the server expections
                            // have been met
                            conn.SendResponseHeader(response);
                            conn.Flush();
                            response = null;
                            conn.ReceiveRequestEntity((HttpEntityEnclosingRequest)request);
                        }
                    }
                    else
                    {
                        conn.ReceiveRequestEntity((HttpEntityEnclosingRequest)request);
                    }
                }
                context.SetAttribute(HttpCoreContext.HttpRequest, request);
                if (response == null)
                {
                    response = this.responseFactory.NewHttpResponse(HttpVersion.Http11, HttpStatus.ScOk
                                                                    , context);
                    this.processor.Process(request, context);
                    DoService(request, response, context);
                }
                // Make sure the request content is fully consumed
                if (request is HttpEntityEnclosingRequest)
                {
                    HttpEntity entity = ((HttpEntityEnclosingRequest)request).GetEntity();
                    EntityUtils.Consume(entity);
                }
            }
            catch (HttpException ex)
            {
                response = this.responseFactory.NewHttpResponse(HttpVersion.Http10, HttpStatus.ScInternalServerError
                                                                , context);
                HandleException(ex, response);
            }
            context.SetAttribute(HttpCoreContext.HttpResponse, response);
            this.processor.Process(response, context);
            conn.SendResponseHeader(response);
            conn.SendResponseEntity(response);
            conn.Flush();
            if (!this.connStrategy.KeepAlive(response, context))
            {
                conn.Close();
            }
        }
示例#6
0
        /// <exception cref="System.IO.IOException"></exception>
        public virtual void Close()
        {
            HttpEntity entity = this.original.GetEntity();

            EntityUtils.Consume(entity);
        }
示例#7
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="Apache.Http.HttpException"></exception>
        public virtual CloseableHttpResponse Execute(HttpRoute route, HttpRequestWrapper
                                                     request, HttpClientContext context, HttpExecutionAware execAware)
        {
            Args.NotNull(route, "HTTP route");
            Args.NotNull(request, "HTTP request");
            Args.NotNull(context, "HTTP context");
            IList <URI> redirectLocations = context.GetRedirectLocations();

            if (redirectLocations != null)
            {
                redirectLocations.Clear();
            }
            RequestConfig      config         = context.GetRequestConfig();
            int                maxRedirects   = config.GetMaxRedirects() > 0 ? config.GetMaxRedirects() : 50;
            HttpRoute          currentRoute   = route;
            HttpRequestWrapper currentRequest = request;

            for (int redirectCount = 0; ;)
            {
                CloseableHttpResponse response = requestExecutor.Execute(currentRoute, currentRequest
                                                                         , context, execAware);
                try
                {
                    if (config.IsRedirectsEnabled() && this.redirectStrategy.IsRedirected(currentRequest
                                                                                          , response, context))
                    {
                        if (redirectCount >= maxRedirects)
                        {
                            throw new RedirectException("Maximum redirects (" + maxRedirects + ") exceeded");
                        }
                        redirectCount++;
                        IHttpRequest redirect = this.redirectStrategy.GetRedirect(currentRequest, response
                                                                                  , context);
                        if (!redirect.HeaderIterator().HasNext())
                        {
                            IHttpRequest original = request.GetOriginal();
                            redirect.SetHeaders(original.GetAllHeaders());
                        }
                        currentRequest = HttpRequestWrapper.Wrap(redirect);
                        if (currentRequest is HttpEntityEnclosingRequest)
                        {
                            Proxies.EnhanceEntity((HttpEntityEnclosingRequest)currentRequest);
                        }
                        URI      uri       = currentRequest.GetURI();
                        HttpHost newTarget = URIUtils.ExtractHost(uri);
                        if (newTarget == null)
                        {
                            throw new ProtocolException("Redirect URI does not specify a valid host name: " +
                                                        uri);
                        }
                        // Reset virtual host and auth states if redirecting to another host
                        if (!currentRoute.GetTargetHost().Equals(newTarget))
                        {
                            AuthState targetAuthState = context.GetTargetAuthState();
                            if (targetAuthState != null)
                            {
                                this.log.Debug("Resetting target auth state");
                                targetAuthState.Reset();
                            }
                            AuthState proxyAuthState = context.GetProxyAuthState();
                            if (proxyAuthState != null)
                            {
                                AuthScheme authScheme = proxyAuthState.GetAuthScheme();
                                if (authScheme != null && authScheme.IsConnectionBased())
                                {
                                    this.log.Debug("Resetting proxy auth state");
                                    proxyAuthState.Reset();
                                }
                            }
                        }
                        currentRoute = this.routePlanner.DetermineRoute(newTarget, currentRequest, context
                                                                        );
                        if (this.log.IsDebugEnabled())
                        {
                            this.log.Debug("Redirecting to '" + uri + "' via " + currentRoute);
                        }
                        EntityUtils.Consume(response.GetEntity());
                        response.Close();
                    }
                    else
                    {
                        return(response);
                    }
                }
                catch (RuntimeException ex)
                {
                    response.Close();
                    throw;
                }
                catch (IOException ex)
                {
                    response.Close();
                    throw;
                }
                catch (HttpException ex)
                {
                    // Protocol exception related to a direct.
                    // The underlying connection may still be salvaged.
                    try
                    {
                        EntityUtils.Consume(response.GetEntity());
                    }
                    catch (IOException ioex)
                    {
                        this.log.Debug("I/O error while releasing connection", ioex);
                    }
                    finally
                    {
                        response.Close();
                    }
                    throw;
                }
            }
        }
示例#8
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="Apache.Http.HttpException"></exception>
        public virtual Socket Tunnel(HttpHost proxy, HttpHost target, Credentials credentials
                                     )
        {
            Args.NotNull(proxy, "Proxy host");
            Args.NotNull(target, "Target host");
            Args.NotNull(credentials, "Credentials");
            HttpHost host = target;

            if (host.GetPort() <= 0)
            {
                host = new HttpHost(host.GetHostName(), 80, host.GetSchemeName());
            }
            HttpRoute route = new HttpRoute(host, this.requestConfig.GetLocalAddress(), proxy
                                            , false, RouteInfo.TunnelType.Tunnelled, RouteInfo.LayerType.Plain);
            ManagedHttpClientConnection conn = this.connFactory.Create(route, this.connectionConfig
                                                                       );
            HttpContext  context = new BasicHttpContext();
            HttpResponse response;
            IHttpRequest connect = new BasicHttpRequest("CONNECT", host.ToHostString(), HttpVersion
                                                        .Http11);
            BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();

            credsProvider.SetCredentials(new AuthScope(proxy), credentials);
            // Populate the execution context
            context.SetAttribute(HttpCoreContext.HttpTargetHost, target);
            context.SetAttribute(HttpCoreContext.HttpConnection, conn);
            context.SetAttribute(HttpCoreContext.HttpRequest, connect);
            context.SetAttribute(HttpClientContext.HttpRoute, route);
            context.SetAttribute(HttpClientContext.ProxyAuthState, this.proxyAuthState);
            context.SetAttribute(HttpClientContext.CredsProvider, credsProvider);
            context.SetAttribute(HttpClientContext.AuthschemeRegistry, this.authSchemeRegistry
                                 );
            context.SetAttribute(HttpClientContext.RequestConfig, this.requestConfig);
            this.requestExec.PreProcess(connect, this.httpProcessor, context);
            for (; ;)
            {
                if (!conn.IsOpen())
                {
                    Socket socket = Sharpen.Extensions.CreateSocket(proxy.GetHostName(), proxy.GetPort
                                                                        ());
                    conn.Bind(socket);
                }
                this.authenticator.GenerateAuthResponse(connect, this.proxyAuthState, context);
                response = this.requestExec.Execute(connect, conn, context);
                int status = response.GetStatusLine().GetStatusCode();
                if (status < 200)
                {
                    throw new HttpException("Unexpected response to CONNECT request: " + response.GetStatusLine
                                                ());
                }
                if (this.authenticator.IsAuthenticationRequested(proxy, response, this.proxyAuthStrategy
                                                                 , this.proxyAuthState, context))
                {
                    if (this.authenticator.HandleAuthChallenge(proxy, response, this.proxyAuthStrategy
                                                               , this.proxyAuthState, context))
                    {
                        // Retry request
                        if (this.reuseStrategy.KeepAlive(response, context))
                        {
                            // Consume response content
                            HttpEntity entity = response.GetEntity();
                            EntityUtils.Consume(entity);
                        }
                        else
                        {
                            conn.Close();
                        }
                        // discard previous auth header
                        connect.RemoveHeaders(AUTH.ProxyAuthResp);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            int status_1 = response.GetStatusLine().GetStatusCode();

            if (status_1 > 299)
            {
                // Buffer response content
                HttpEntity entity = response.GetEntity();
                if (entity != null)
                {
                    response.SetEntity(new BufferedHttpEntity(entity));
                }
                conn.Close();
                throw new TunnelRefusedException("CONNECT refused by proxy: " + response.GetStatusLine
                                                     (), response);
            }
            return(conn.GetSocket());
        }
        /// <summary>Creates a tunnel to the target server.</summary>
        /// <remarks>
        /// Creates a tunnel to the target server.
        /// The connection must be established to the (last) proxy.
        /// A CONNECT request for tunnelling through the proxy will
        /// be created and sent, the response received and checked.
        /// This method does <i>not</i> update the connection with
        /// information about the tunnel, that is left to the caller.
        /// </remarks>
        /// <exception cref="Apache.Http.HttpException"></exception>
        /// <exception cref="System.IO.IOException"></exception>
        private bool CreateTunnelToTarget(AuthState proxyAuthState, HttpClientConnection
                                          managedConn, HttpRoute route, IHttpRequest request, HttpClientContext context)
        {
            RequestConfig config  = context.GetRequestConfig();
            int           timeout = config.GetConnectTimeout();
            HttpHost      target  = route.GetTargetHost();
            HttpHost      proxy   = route.GetProxyHost();
            HttpResponse  response;
            string        authority = target.ToHostString();
            IHttpRequest  connect   = new BasicHttpRequest("CONNECT", authority, request.GetProtocolVersion
                                                               ());

            this.requestExecutor.PreProcess(connect, this.proxyHttpProcessor, context);
            for (; ;)
            {
                if (!managedConn.IsOpen())
                {
                    this.connManager.Connect(managedConn, route, timeout > 0 ? timeout : 0, context);
                }
                connect.RemoveHeaders(AUTH.ProxyAuthResp);
                this.authenticator.GenerateAuthResponse(connect, proxyAuthState, context);
                response = this.requestExecutor.Execute(connect, managedConn, context);
                int status = response.GetStatusLine().GetStatusCode();
                if (status < 200)
                {
                    throw new HttpException("Unexpected response to CONNECT request: " + response.GetStatusLine
                                                ());
                }
                if (config.IsAuthenticationEnabled())
                {
                    if (this.authenticator.IsAuthenticationRequested(proxy, response, this.proxyAuthStrategy
                                                                     , proxyAuthState, context))
                    {
                        if (this.authenticator.HandleAuthChallenge(proxy, response, this.proxyAuthStrategy
                                                                   , proxyAuthState, context))
                        {
                            // Retry request
                            if (this.reuseStrategy.KeepAlive(response, context))
                            {
                                this.log.Debug("Connection kept alive");
                                // Consume response content
                                HttpEntity entity = response.GetEntity();
                                EntityUtils.Consume(entity);
                            }
                            else
                            {
                                managedConn.Close();
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            int status_1 = response.GetStatusLine().GetStatusCode();

            if (status_1 > 299)
            {
                // Buffer response content
                HttpEntity entity = response.GetEntity();
                if (entity != null)
                {
                    response.SetEntity(new BufferedHttpEntity(entity));
                }
                managedConn.Close();
                throw new TunnelRefusedException("CONNECT refused by proxy: " + response.GetStatusLine
                                                     (), response);
            }
            // How to decide on security of the tunnelled connection?
            // The socket factory knows only about the segment to the proxy.
            // Even if that is secure, the hop to the target may be insecure.
            // Leave it to derived classes, consider insecure by default here.
            return(false);
        }
示例#10
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="Apache.Http.HttpException"></exception>
        public virtual CloseableHttpResponse Execute(HttpRoute route, HttpRequestWrapper
                                                     request, HttpClientContext context, HttpExecutionAware execAware)
        {
            Args.NotNull(route, "HTTP route");
            Args.NotNull(request, "HTTP request");
            Args.NotNull(context, "HTTP context");
            AuthState targetAuthState = context.GetTargetAuthState();

            if (targetAuthState == null)
            {
                targetAuthState = new AuthState();
                context.SetAttribute(HttpClientContext.TargetAuthState, targetAuthState);
            }
            AuthState proxyAuthState = context.GetProxyAuthState();

            if (proxyAuthState == null)
            {
                proxyAuthState = new AuthState();
                context.SetAttribute(HttpClientContext.ProxyAuthState, proxyAuthState);
            }
            if (request is HttpEntityEnclosingRequest)
            {
                Proxies.EnhanceEntity((HttpEntityEnclosingRequest)request);
            }
            object            userToken   = context.GetUserToken();
            ConnectionRequest connRequest = connManager.RequestConnection(route, userToken);

            if (execAware != null)
            {
                if (execAware.IsAborted())
                {
                    connRequest.Cancel();
                    throw new RequestAbortedException("Request aborted");
                }
                else
                {
                    execAware.SetCancellable(connRequest);
                }
            }
            RequestConfig        config = context.GetRequestConfig();
            HttpClientConnection managedConn;

            try
            {
                int timeout = config.GetConnectionRequestTimeout();
                managedConn = connRequest.Get(timeout > 0 ? timeout : 0, TimeUnit.Milliseconds);
            }
            catch (Exception interrupted)
            {
                Sharpen.Thread.CurrentThread().Interrupt();
                throw new RequestAbortedException("Request aborted", interrupted);
            }
            catch (ExecutionException ex)
            {
                Exception cause = ex.InnerException;
                if (cause == null)
                {
                    cause = ex;
                }
                throw new RequestAbortedException("Request execution failed", cause);
            }
            context.SetAttribute(HttpClientContext.HttpConnection, managedConn);
            if (config.IsStaleConnectionCheckEnabled())
            {
                // validate connection
                if (managedConn.IsOpen())
                {
                    this.log.Debug("Stale connection check");
                    if (managedConn.IsStale())
                    {
                        this.log.Debug("Stale connection detected");
                        managedConn.Close();
                    }
                }
            }
            ConnectionHolder connHolder = new ConnectionHolder(this.log, this.connManager, managedConn
                                                               );

            try
            {
                if (execAware != null)
                {
                    execAware.SetCancellable(connHolder);
                }
                HttpResponse response;
                for (int execCount = 1; ; execCount++)
                {
                    if (execCount > 1 && !Proxies.IsRepeatable(request))
                    {
                        throw new NonRepeatableRequestException("Cannot retry request " + "with a non-repeatable request entity."
                                                                );
                    }
                    if (execAware != null && execAware.IsAborted())
                    {
                        throw new RequestAbortedException("Request aborted");
                    }
                    if (!managedConn.IsOpen())
                    {
                        this.log.Debug("Opening connection " + route);
                        try
                        {
                            EstablishRoute(proxyAuthState, managedConn, route, request, context);
                        }
                        catch (TunnelRefusedException ex)
                        {
                            if (this.log.IsDebugEnabled())
                            {
                                this.log.Debug(ex.Message);
                            }
                            response = ex.GetResponse();
                            break;
                        }
                    }
                    int timeout = config.GetSocketTimeout();
                    if (timeout >= 0)
                    {
                        managedConn.SetSocketTimeout(timeout);
                    }
                    if (execAware != null && execAware.IsAborted())
                    {
                        throw new RequestAbortedException("Request aborted");
                    }
                    if (this.log.IsDebugEnabled())
                    {
                        this.log.Debug("Executing request " + request.GetRequestLine());
                    }
                    if (!request.ContainsHeader(AUTH.WwwAuthResp))
                    {
                        if (this.log.IsDebugEnabled())
                        {
                            this.log.Debug("Target auth state: " + targetAuthState.GetState());
                        }
                        this.authenticator.GenerateAuthResponse(request, targetAuthState, context);
                    }
                    if (!request.ContainsHeader(AUTH.ProxyAuthResp) && !route.IsTunnelled())
                    {
                        if (this.log.IsDebugEnabled())
                        {
                            this.log.Debug("Proxy auth state: " + proxyAuthState.GetState());
                        }
                        this.authenticator.GenerateAuthResponse(request, proxyAuthState, context);
                    }
                    response = requestExecutor.Execute(request, managedConn, context);
                    // The connection is in or can be brought to a re-usable state.
                    if (reuseStrategy.KeepAlive(response, context))
                    {
                        // Set the idle duration of this connection
                        long duration = keepAliveStrategy.GetKeepAliveDuration(response, context);
                        if (this.log.IsDebugEnabled())
                        {
                            string s;
                            if (duration > 0)
                            {
                                s = "for " + duration + " " + TimeUnit.Milliseconds;
                            }
                            else
                            {
                                s = "indefinitely";
                            }
                            this.log.Debug("Connection can be kept alive " + s);
                        }
                        connHolder.SetValidFor(duration, TimeUnit.Milliseconds);
                        connHolder.MarkReusable();
                    }
                    else
                    {
                        connHolder.MarkNonReusable();
                    }
                    if (NeedAuthentication(targetAuthState, proxyAuthState, route, response, context))
                    {
                        // Make sure the response body is fully consumed, if present
                        HttpEntity entity = response.GetEntity();
                        if (connHolder.IsReusable())
                        {
                            EntityUtils.Consume(entity);
                        }
                        else
                        {
                            managedConn.Close();
                            if (proxyAuthState.GetState() == AuthProtocolState.Success && proxyAuthState.GetAuthScheme
                                    () != null && proxyAuthState.GetAuthScheme().IsConnectionBased())
                            {
                                this.log.Debug("Resetting proxy auth state");
                                proxyAuthState.Reset();
                            }
                            if (targetAuthState.GetState() == AuthProtocolState.Success && targetAuthState.GetAuthScheme
                                    () != null && targetAuthState.GetAuthScheme().IsConnectionBased())
                            {
                                this.log.Debug("Resetting target auth state");
                                targetAuthState.Reset();
                            }
                        }
                        // discard previous auth headers
                        IHttpRequest original = request.GetOriginal();
                        if (!original.ContainsHeader(AUTH.WwwAuthResp))
                        {
                            request.RemoveHeaders(AUTH.WwwAuthResp);
                        }
                        if (!original.ContainsHeader(AUTH.ProxyAuthResp))
                        {
                            request.RemoveHeaders(AUTH.ProxyAuthResp);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                if (userToken == null)
                {
                    userToken = userTokenHandler.GetUserToken(context);
                    context.SetAttribute(HttpClientContext.UserToken, userToken);
                }
                if (userToken != null)
                {
                    connHolder.SetState(userToken);
                }
                // check for entity, release connection if possible
                HttpEntity entity_1 = response.GetEntity();
                if (entity_1 == null || !entity_1.IsStreaming())
                {
                    // connection not needed and (assumed to be) in re-usable state
                    connHolder.ReleaseConnection();
                    return(Proxies.EnhanceResponse(response, null));
                }
                else
                {
                    return(Proxies.EnhanceResponse(response, connHolder));
                }
            }
            catch (ConnectionShutdownException ex)
            {
                ThreadInterruptedException ioex = new ThreadInterruptedException("Connection has been shut down"
                                                                                 );
                Sharpen.Extensions.InitCause(ioex, ex);
                throw ioex;
            }
            catch (HttpException ex)
            {
                connHolder.AbortConnection();
                throw;
            }
            catch (IOException ex)
            {
                connHolder.AbortConnection();
                throw;
            }
            catch (RuntimeException ex)
            {
                connHolder.AbortConnection();
                throw;
            }
        }