/// <exception cref="System.IO.IOException"></exception>
 public virtual void Upgrade(HttpClientConnection conn, HttpRoute route, HttpContext
                             context)
 {
     Args.NotNull(conn, "Connection");
     Args.NotNull(route, "HTTP route");
     Asserts.Check(conn == this.conn, "Connection not obtained from this manager");
     this.connectionOperator.Upgrade(this.conn, route.GetTargetHost(), context);
 }
        private bool NeedAuthentication(AuthState targetAuthState, AuthState proxyAuthState
                                        , HttpRoute route, HttpResponse response, HttpClientContext context)
        {
            RequestConfig config = context.GetRequestConfig();

            if (config.IsAuthenticationEnabled())
            {
                HttpHost target = context.GetTargetHost();
                if (target == null)
                {
                    target = route.GetTargetHost();
                }
                if (target.GetPort() < 0)
                {
                    target = new HttpHost(target.GetHostName(), route.GetTargetHost().GetPort(), target
                                          .GetSchemeName());
                }
                if (this.authenticator.IsAuthenticationRequested(target, response, this.targetAuthStrategy
                                                                 , targetAuthState, context))
                {
                    return(this.authenticator.HandleAuthChallenge(target, response, this.targetAuthStrategy
                                                                  , targetAuthState, context));
                }
                HttpHost proxy = route.GetProxyHost();
                if (this.authenticator.IsAuthenticationRequested(proxy, response, this.proxyAuthStrategy
                                                                 , proxyAuthState, context))
                {
                    // if proxy is not set use target host instead
                    if (proxy == null)
                    {
                        proxy = route.GetTargetHost();
                    }
                    return(this.authenticator.HandleAuthChallenge(proxy, response, this.proxyAuthStrategy
                                                                  , proxyAuthState, context));
                }
            }
            return(false);
        }
Example #3
0
 /// <exception cref="Apache.Http.ProtocolException"></exception>
 internal virtual void RewriteRequestURI(HttpRequestWrapper request, HttpRoute route
                                         )
 {
     try
     {
         URI uri = request.GetURI();
         if (uri != null)
         {
             if (route.GetProxyHost() != null && !route.IsTunnelled())
             {
                 // Make sure the request URI is absolute
                 if (!uri.IsAbsolute())
                 {
                     HttpHost target = route.GetTargetHost();
                     uri = URIUtils.RewriteURI(uri, target, true);
                 }
                 else
                 {
                     uri = URIUtils.RewriteURI(uri);
                 }
             }
             else
             {
                 // Make sure the request URI is relative
                 if (uri.IsAbsolute())
                 {
                     uri = URIUtils.RewriteURI(uri, null, true);
                 }
                 else
                 {
                     uri = URIUtils.RewriteURI(uri);
                 }
             }
             request.SetURI(uri);
         }
     }
     catch (URISyntaxException ex)
     {
         throw new ProtocolException("Invalid URI: " + request.GetRequestLine().GetUri(),
                                     ex);
     }
 }
        /// <exception cref="System.IO.IOException"></exception>
        public virtual void Connect(HttpClientConnection conn, HttpRoute route, int connectTimeout
                                    , HttpContext context)
        {
            Args.NotNull(conn, "Connection");
            Args.NotNull(route, "HTTP route");
            Asserts.Check(conn == this.conn, "Connection not obtained from this manager");
            HttpHost host;

            if (route.GetProxyHost() != null)
            {
                host = route.GetProxyHost();
            }
            else
            {
                host = route.GetTargetHost();
            }
            IPEndPoint localAddress = route.GetLocalSocketAddress();

            this.connectionOperator.Connect(this.conn, host, localAddress, connectTimeout, this
                                            .socketConfig, context);
        }
Example #5
0
        /// <exception cref="Apache.Http.Auth.AuthenticationException"></exception>
        public override Header Authenticate(Credentials credentials, IHttpRequest request
                                            , HttpContext context)
        {
            Args.NotNull(request, "HTTP request");
            switch (state)
            {
            case GGSSchemeBase.State.Uninitiated:
            {
                throw new AuthenticationException(GetSchemeName() + " authentication has not been initiated"
                                                  );
            }

            case GGSSchemeBase.State.Failed:
            {
                throw new AuthenticationException(GetSchemeName() + " authentication has failed");
            }

            case GGSSchemeBase.State.ChallengeReceived:
            {
                try
                {
                    HttpRoute route = (HttpRoute)context.GetAttribute(HttpClientContext.HttpRoute);
                    if (route == null)
                    {
                        throw new AuthenticationException("Connection route is not available");
                    }
                    HttpHost host;
                    if (IsProxy())
                    {
                        host = route.GetProxyHost();
                        if (host == null)
                        {
                            host = route.GetTargetHost();
                        }
                    }
                    else
                    {
                        host = route.GetTargetHost();
                    }
                    string authServer;
                    if (!this.stripPort && host.GetPort() > 0)
                    {
                        authServer = host.ToHostString();
                    }
                    else
                    {
                        authServer = host.GetHostName();
                    }
                    if (log.IsDebugEnabled())
                    {
                        log.Debug("init " + authServer);
                    }
                    token = GenerateToken(token, authServer);
                    state = GGSSchemeBase.State.TokenGenerated;
                }
                catch (GSSException gsse)
                {
                    state = GGSSchemeBase.State.Failed;
                    if (gsse.GetMajor() == GSSException.DefectiveCredential || gsse.GetMajor() == GSSException
                        .CredentialsExpired)
                    {
                        throw new InvalidCredentialsException(gsse.Message, gsse);
                    }
                    if (gsse.GetMajor() == GSSException.NoCred)
                    {
                        throw new InvalidCredentialsException(gsse.Message, gsse);
                    }
                    if (gsse.GetMajor() == GSSException.DefectiveToken || gsse.GetMajor() == GSSException
                        .DuplicateToken || gsse.GetMajor() == GSSException.OldToken)
                    {
                        throw new AuthenticationException(gsse.Message, gsse);
                    }
                    // other error
                    throw new AuthenticationException(gsse.Message);
                }
                goto case GGSSchemeBase.State.TokenGenerated;
            }

            case GGSSchemeBase.State.TokenGenerated:
            {
                string tokenstr = Sharpen.Runtime.GetStringForBytes(base64codec.Encode(token));
                if (log.IsDebugEnabled())
                {
                    log.Debug("Sending response '" + tokenstr + "' back to the auth server");
                }
                CharArrayBuffer buffer = new CharArrayBuffer(32);
                if (IsProxy())
                {
                    buffer.Append(AUTH.ProxyAuthResp);
                }
                else
                {
                    buffer.Append(AUTH.WwwAuthResp);
                }
                buffer.Append(": Negotiate ");
                buffer.Append(tokenstr);
                return(new BufferedHeader(buffer));
            }

            default:
            {
                throw new InvalidOperationException("Illegal state: " + state);
            }
            }
        }
Example #6
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");
            IHttpRequest original = request.GetOriginal();
            URI          uri      = null;

            if (original is IHttpUriRequest)
            {
                uri = ((IHttpUriRequest)original).GetURI();
            }
            else
            {
                string uriString = original.GetRequestLine().GetUri();
                try
                {
                    uri = URI.Create(uriString);
                }
                catch (ArgumentException ex)
                {
                    if (this.log.IsDebugEnabled())
                    {
                        this.log.Debug("Unable to parse '" + uriString + "' as a valid URI; " + "request URI and Host header may be inconsistent"
                                       , ex);
                    }
                }
            }
            request.SetURI(uri);
            // Re-write request URI if needed
            RewriteRequestURI(request, route);
            HttpParams @params     = request.GetParams();
            HttpHost   virtualHost = (HttpHost)@params.GetParameter(ClientPNames.VirtualHost);

            // HTTPCLIENT-1092 - add the port if necessary
            if (virtualHost != null && virtualHost.GetPort() == -1)
            {
                int port = route.GetTargetHost().GetPort();
                if (port != -1)
                {
                    virtualHost = new HttpHost(virtualHost.GetHostName(), port, virtualHost.GetSchemeName
                                                   ());
                }
                if (this.log.IsDebugEnabled())
                {
                    this.log.Debug("Using virtual host" + virtualHost);
                }
            }
            HttpHost target = null;

            if (virtualHost != null)
            {
                target = virtualHost;
            }
            else
            {
                if (uri != null && uri.IsAbsolute() && uri.GetHost() != null)
                {
                    target = new HttpHost(uri.GetHost(), uri.GetPort(), uri.GetScheme());
                }
            }
            if (target == null)
            {
                target = route.GetTargetHost();
            }
            // Get user info from the URI
            if (uri != null)
            {
                string userinfo = uri.GetUserInfo();
                if (userinfo != null)
                {
                    CredentialsProvider credsProvider = context.GetCredentialsProvider();
                    if (credsProvider == null)
                    {
                        credsProvider = new BasicCredentialsProvider();
                        context.SetCredentialsProvider(credsProvider);
                    }
                    credsProvider.SetCredentials(new AuthScope(target), new UsernamePasswordCredentials
                                                     (userinfo));
                }
            }
            // Run request protocol interceptors
            context.SetAttribute(HttpClientContext.HttpTargetHost, target);
            context.SetAttribute(HttpClientContext.HttpRoute, route);
            context.SetAttribute(HttpClientContext.HttpRequest, request);
            this.httpProcessor.Process(request, context);
            CloseableHttpResponse response = this.requestExecutor.Execute(route, request, context
                                                                          , execAware);

            try
            {
                // Run response protocol interceptors
                context.SetAttribute(HttpClientContext.HttpResponse, response);
                this.httpProcessor.Process(response, context);
                return(response);
            }
            catch (RuntimeException ex)
            {
                response.Close();
                throw;
            }
            catch (IOException ex)
            {
                response.Close();
                throw;
            }
            catch (HttpException ex)
            {
                response.Close();
                throw;
            }
        }
Example #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");
            ConnectionRequest connRequest = connManager.RequestConnection(route, null);

            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);
            }
            ConnectionHolder releaseTrigger = new ConnectionHolder(log, connManager, managedConn
                                                                   );

            try
            {
                if (execAware != null)
                {
                    if (execAware.IsAborted())
                    {
                        releaseTrigger.Close();
                        throw new RequestAbortedException("Request aborted");
                    }
                    else
                    {
                        execAware.SetCancellable(releaseTrigger);
                    }
                }
                if (!managedConn.IsOpen())
                {
                    int timeout = config.GetConnectTimeout();
                    this.connManager.Connect(managedConn, route, timeout > 0 ? timeout : 0, context);
                    this.connManager.RouteComplete(managedConn, route, context);
                }
                int timeout_1 = config.GetSocketTimeout();
                if (timeout_1 >= 0)
                {
                    managedConn.SetSocketTimeout(timeout_1);
                }
                HttpHost     target   = null;
                IHttpRequest original = request.GetOriginal();
                if (original is IHttpUriRequest)
                {
                    URI uri = ((IHttpUriRequest)original).GetURI();
                    if (uri.IsAbsolute())
                    {
                        target = new HttpHost(uri.GetHost(), uri.GetPort(), uri.GetScheme());
                    }
                }
                if (target == null)
                {
                    target = route.GetTargetHost();
                }
                context.SetAttribute(HttpClientContext.HttpTargetHost, target);
                context.SetAttribute(HttpClientContext.HttpRequest, request);
                context.SetAttribute(HttpClientContext.HttpConnection, managedConn);
                context.SetAttribute(HttpClientContext.HttpRoute, route);
                httpProcessor.Process(request, context);
                HttpResponse response = requestExecutor.Execute(request, managedConn, context);
                httpProcessor.Process(response, 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);
                    releaseTrigger.SetValidFor(duration, TimeUnit.Milliseconds);
                    releaseTrigger.MarkReusable();
                }
                else
                {
                    releaseTrigger.MarkNonReusable();
                }
                // check for entity, release connection if possible
                HttpEntity entity = response.GetEntity();
                if (entity == null || !entity.IsStreaming())
                {
                    // connection not needed and (assumed to be) in re-usable state
                    releaseTrigger.ReleaseConnection();
                    return(Proxies.EnhanceResponse(response, null));
                }
                else
                {
                    return(Proxies.EnhanceResponse(response, releaseTrigger));
                }
            }
            catch (ConnectionShutdownException ex)
            {
                ThreadInterruptedException ioex = new ThreadInterruptedException("Connection has been shut down"
                                                                                 );
                Sharpen.Extensions.InitCause(ioex, ex);
                throw ioex;
            }
            catch (HttpException ex)
            {
                releaseTrigger.AbortConnection();
                throw;
            }
            catch (IOException ex)
            {
                releaseTrigger.AbortConnection();
                throw;
            }
            catch (RuntimeException ex)
            {
                releaseTrigger.AbortConnection();
                throw;
            }
        }
Example #8
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;
                }
            }
        }
        /// <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);
        }