Search in sources :

Example 6 with HttpRoute

use of org.apache.http.conn.routing.HttpRoute in project robovm by robovm.

the class DefaultRequestDirector method handleResponse.

/**
     * Analyzes a response to check need for a followup.
     *
     * @param roureq    the request and route. 
     * @param response  the response to analayze
     * @param context   the context used for the current request execution
     *
     * @return  the followup request and route if there is a followup, or
     *          <code>null</code> if the response should be returned as is
     *
     * @throws HttpException    in case of a problem
     * @throws IOException      in case of an IO problem
     */
protected RoutedRequest handleResponse(RoutedRequest roureq, HttpResponse response, HttpContext context) throws HttpException, IOException {
    HttpRoute route = roureq.getRoute();
    HttpHost proxy = route.getProxyHost();
    RequestWrapper request = roureq.getRequest();
    HttpParams params = request.getParams();
    if (HttpClientParams.isRedirecting(params) && this.redirectHandler.isRedirectRequested(response, context)) {
        if (redirectCount >= maxRedirects) {
            throw new RedirectException("Maximum redirects (" + maxRedirects + ") exceeded");
        }
        redirectCount++;
        URI uri = this.redirectHandler.getLocationURI(response, context);
        HttpHost newTarget = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
        HttpGet redirect = new HttpGet(uri);
        HttpRequest orig = request.getOriginal();
        redirect.setHeaders(orig.getAllHeaders());
        RequestWrapper wrapper = new RequestWrapper(redirect);
        wrapper.setParams(params);
        HttpRoute newRoute = determineRoute(newTarget, wrapper, context);
        RoutedRequest newRequest = new RoutedRequest(wrapper, newRoute);
        if (this.log.isDebugEnabled()) {
            this.log.debug("Redirecting to '" + uri + "' via " + newRoute);
        }
        return newRequest;
    }
    CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
    if (credsProvider != null && HttpClientParams.isAuthenticating(params)) {
        if (this.targetAuthHandler.isAuthenticationRequested(response, context)) {
            HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
            if (target == null) {
                target = route.getTargetHost();
            }
            this.log.debug("Target requested authentication");
            Map<String, Header> challenges = this.targetAuthHandler.getChallenges(response, context);
            try {
                processChallenges(challenges, this.targetAuthState, this.targetAuthHandler, response, context);
            } catch (AuthenticationException ex) {
                if (this.log.isWarnEnabled()) {
                    this.log.warn("Authentication error: " + ex.getMessage());
                    return null;
                }
            }
            updateAuthState(this.targetAuthState, target, credsProvider);
            if (this.targetAuthState.getCredentials() != null) {
                // Re-try the same request via the same route
                return roureq;
            } else {
                return null;
            }
        } else {
            // Reset target auth scope
            this.targetAuthState.setAuthScope(null);
        }
        if (this.proxyAuthHandler.isAuthenticationRequested(response, context)) {
            this.log.debug("Proxy requested authentication");
            Map<String, Header> challenges = this.proxyAuthHandler.getChallenges(response, context);
            try {
                processChallenges(challenges, this.proxyAuthState, this.proxyAuthHandler, response, context);
            } catch (AuthenticationException ex) {
                if (this.log.isWarnEnabled()) {
                    this.log.warn("Authentication error: " + ex.getMessage());
                    return null;
                }
            }
            updateAuthState(this.proxyAuthState, proxy, credsProvider);
            if (this.proxyAuthState.getCredentials() != null) {
                // Re-try the same request via the same route
                return roureq;
            } else {
                return null;
            }
        } else {
            // Reset proxy auth scope
            this.proxyAuthState.setAuthScope(null);
        }
    }
    return null;
}
Also used : HttpRequest(org.apache.http.HttpRequest) BasicHttpRequest(org.apache.http.message.BasicHttpRequest) AbortableHttpRequest(org.apache.http.client.methods.AbortableHttpRequest) AuthenticationException(org.apache.http.auth.AuthenticationException) HttpGet(org.apache.http.client.methods.HttpGet) CredentialsProvider(org.apache.http.client.CredentialsProvider) URI(java.net.URI) HttpRoute(org.apache.http.conn.routing.HttpRoute) HttpParams(org.apache.http.params.HttpParams) Header(org.apache.http.Header) HttpHost(org.apache.http.HttpHost) RedirectException(org.apache.http.client.RedirectException)

Example 7 with HttpRoute

use of org.apache.http.conn.routing.HttpRoute in project robolectric by robolectric.

the class DefaultRequestDirector method execute.

// non-javadoc, see interface ClientRequestDirector
public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException, IOException {
    HttpRequest orig = request;
    RequestWrapper origWrapper = wrapRequest(orig);
    origWrapper.setParams(params);
    HttpRoute origRoute = determineRoute(target, origWrapper, context);
    virtualHost = (HttpHost) orig.getParams().getParameter(ClientPNames.VIRTUAL_HOST);
    RoutedRequest roureq = new RoutedRequest(origWrapper, origRoute);
    long timeout = ConnManagerParams.getTimeout(params);
    int execCount = 0;
    boolean reuse = false;
    boolean done = false;
    try {
        HttpResponse response = null;
        while (!done) {
            // In this loop, the RoutedRequest may be replaced by a
            // followup request and route. The request and route passed
            // in the method arguments will be replaced. The original
            // request is still available in 'orig'.
            RequestWrapper wrapper = roureq.getRequest();
            HttpRoute route = roureq.getRoute();
            response = null;
            // See if we have a user token bound to the execution context
            Object userToken = context.getAttribute(ClientContext.USER_TOKEN);
            // Allocate connection if needed
            if (managedConn == null) {
                ClientConnectionRequest connRequest = connManager.requestConnection(route, userToken);
                if (orig instanceof AbortableHttpRequest) {
                    ((AbortableHttpRequest) orig).setConnectionRequest(connRequest);
                }
                try {
                    managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS);
                } catch (InterruptedException interrupted) {
                    InterruptedIOException iox = new InterruptedIOException();
                    iox.initCause(interrupted);
                    throw iox;
                }
                if (HttpConnectionParams.isStaleCheckingEnabled(params)) {
                    // validate connection
                    if (managedConn.isOpen()) {
                        this.log.debug("Stale connection check");
                        if (managedConn.isStale()) {
                            this.log.debug("Stale connection detected");
                            managedConn.close();
                        }
                    }
                }
            }
            if (orig instanceof AbortableHttpRequest) {
                ((AbortableHttpRequest) orig).setReleaseTrigger(managedConn);
            }
            // Reopen connection if needed
            if (!managedConn.isOpen()) {
                managedConn.open(route, context, params);
            } else {
                managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params));
            }
            try {
                establishRoute(route, context);
            } catch (TunnelRefusedException ex) {
                if (this.log.isDebugEnabled()) {
                    this.log.debug(ex.getMessage());
                }
                response = ex.getResponse();
                break;
            }
            // Reset headers on the request wrapper
            wrapper.resetHeaders();
            // Re-write request URI if needed
            rewriteRequestURI(wrapper, route);
            // Use virtual host if set
            target = virtualHost;
            if (target == null) {
                target = route.getTargetHost();
            }
            HttpHost proxy = route.getProxyHost();
            // Populate the execution context
            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
            context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy);
            context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn);
            context.setAttribute(ClientContext.TARGET_AUTH_STATE, targetAuthState);
            context.setAttribute(ClientContext.PROXY_AUTH_STATE, proxyAuthState);
            // Run request protocol interceptors
            requestExec.preProcess(wrapper, httpProcessor, context);
            boolean retrying = true;
            Exception retryReason = null;
            while (retrying) {
                // Increment total exec count (with redirects)
                execCount++;
                // Increment exec count for this particular request
                wrapper.incrementExecCount();
                if (!wrapper.isRepeatable()) {
                    this.log.debug("Cannot retry non-repeatable request");
                    if (retryReason != null) {
                        throw new NonRepeatableRequestException("Cannot retry request " + "with a non-repeatable request entity.  The cause lists the " + "reason the original request failed: " + retryReason);
                    } else {
                        throw new NonRepeatableRequestException("Cannot retry request " + "with a non-repeatable request entity.");
                    }
                }
                try {
                    if (this.log.isDebugEnabled()) {
                        this.log.debug("Attempt " + execCount + " to execute request");
                    }
                    response = requestExec.execute(wrapper, managedConn, context);
                    retrying = false;
                } catch (IOException ex) {
                    this.log.debug("Closing the connection.");
                    managedConn.close();
                    if (retryHandler.retryRequest(ex, wrapper.getExecCount(), context)) {
                        if (this.log.isInfoEnabled()) {
                            this.log.info("I/O exception (" + ex.getClass().getName() + ") caught when processing request: " + ex.getMessage());
                        }
                        if (this.log.isDebugEnabled()) {
                            this.log.debug(ex.getMessage(), ex);
                        }
                        this.log.info("Retrying request");
                        retryReason = ex;
                    } else {
                        throw ex;
                    }
                    // just re-open connection and re-try the request
                    if (!route.isTunnelled()) {
                        this.log.debug("Reopening the direct connection.");
                        managedConn.open(route, context, params);
                    } else {
                        // otherwise give up
                        this.log.debug("Proxied connection. Need to start over.");
                        retrying = false;
                    }
                }
            }
            if (response == null) {
                // Need to start over
                continue;
            }
            // Run response protocol interceptors
            response.setParams(params);
            requestExec.postProcess(response, httpProcessor, context);
            // The connection is in or can be brought to a re-usable state.
            reuse = reuseStrategy.keepAlive(response, context);
            if (reuse) {
                // Set the idle duration of this connection
                long duration = keepAliveStrategy.getKeepAliveDuration(response, context);
                managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS);
                if (this.log.isDebugEnabled()) {
                    if (duration >= 0) {
                        this.log.debug("Connection can be kept alive for " + duration + " ms");
                    } else {
                        this.log.debug("Connection can be kept alive indefinitely");
                    }
                }
            }
            RoutedRequest followup = handleResponse(roureq, response, context);
            if (followup == null) {
                done = true;
            } else {
                if (reuse) {
                    // Make sure the response body is fully consumed, if present
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        entity.consumeContent();
                    }
                    // entity consumed above is not an auto-release entity,
                    // need to mark the connection re-usable explicitly
                    managedConn.markReusable();
                } else {
                    managedConn.close();
                }
                // check if we can use the same connection for the followup
                if (!followup.getRoute().equals(roureq.getRoute())) {
                    releaseConnection();
                }
                roureq = followup;
            }
            if (managedConn != null && userToken == null) {
                userToken = userTokenHandler.getUserToken(context);
                context.setAttribute(ClientContext.USER_TOKEN, userToken);
                if (userToken != null) {
                    managedConn.setState(userToken);
                }
            }
        }
        // check for entity, release connection if possible
        if ((response == null) || (response.getEntity() == null) || !response.getEntity().isStreaming()) {
            // connection not needed and (assumed to be) in re-usable state
            if (reuse)
                managedConn.markReusable();
            releaseConnection();
        } else {
            // install an auto-release entity
            HttpEntity entity = response.getEntity();
            entity = new BasicManagedEntity(entity, managedConn, reuse);
            response.setEntity(entity);
        }
        return response;
    } catch (HttpException | RuntimeException | IOException ex) {
        abortConnection();
        throw ex;
    }
}
Also used : HttpRequest(org.apache.http.HttpRequest) BasicHttpRequest(org.apache.http.message.BasicHttpRequest) AbortableHttpRequest(org.apache.http.client.methods.AbortableHttpRequest) AbortableHttpRequest(org.apache.http.client.methods.AbortableHttpRequest) InterruptedIOException(java.io.InterruptedIOException) TunnelRefusedException(org.apache.http.impl.client.TunnelRefusedException) HttpEntity(org.apache.http.HttpEntity) BufferedHttpEntity(org.apache.http.entity.BufferedHttpEntity) HttpResponse(org.apache.http.HttpResponse) ClientConnectionRequest(org.apache.http.conn.ClientConnectionRequest) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) ProtocolException(org.apache.http.ProtocolException) URISyntaxException(java.net.URISyntaxException) HttpException(org.apache.http.HttpException) AuthenticationException(org.apache.http.auth.AuthenticationException) RedirectException(org.apache.http.client.RedirectException) InterruptedIOException(java.io.InterruptedIOException) MalformedChallengeException(org.apache.http.auth.MalformedChallengeException) TunnelRefusedException(org.apache.http.impl.client.TunnelRefusedException) IOException(java.io.IOException) NonRepeatableRequestException(org.apache.http.client.NonRepeatableRequestException) HttpRoute(org.apache.http.conn.routing.HttpRoute) BasicManagedEntity(org.apache.http.conn.BasicManagedEntity) HttpHost(org.apache.http.HttpHost) RequestWrapper(org.apache.http.impl.client.RequestWrapper) EntityEnclosingRequestWrapper(org.apache.http.impl.client.EntityEnclosingRequestWrapper) HttpException(org.apache.http.HttpException) RoutedRequest(org.apache.http.impl.client.RoutedRequest) NonRepeatableRequestException(org.apache.http.client.NonRepeatableRequestException)

Example 8 with HttpRoute

use of org.apache.http.conn.routing.HttpRoute in project robolectric by robolectric.

the class DefaultRequestDirector method establishRoute.

/**
   * Establishes the target route.
   *
   * @param route     the route to establish
   * @param context   the context for the request execution
   *
   * @throws HttpException    in case of a problem
   * @throws IOException      in case of an IO problem
   */
protected void establishRoute(HttpRoute route, HttpContext context) throws HttpException, IOException {
    HttpRouteDirector rowdy = new BasicRouteDirector();
    int step;
    do {
        HttpRoute fact = managedConn.getRoute();
        step = rowdy.nextStep(route, fact);
        switch(step) {
            case HttpRouteDirector.CONNECT_TARGET:
            case HttpRouteDirector.CONNECT_PROXY:
                managedConn.open(route, context, this.params);
                break;
            case HttpRouteDirector.TUNNEL_TARGET:
                {
                    boolean secure = createTunnelToTarget(route, context);
                    this.log.debug("Tunnel to target created.");
                    managedConn.tunnelTarget(secure, this.params);
                }
                break;
            case HttpRouteDirector.TUNNEL_PROXY:
                {
                    // The most simple example for this case is a proxy chain
                    // of two proxies, where P1 must be tunnelled to P2.
                    // route: Source -> P1 -> P2 -> Target (3 hops)
                    // fact:  Source -> P1 -> Target       (2 hops)
                    // the hop to establish
                    final int hop = fact.getHopCount() - 1;
                    boolean secure = createTunnelToProxy(route, hop, context);
                    this.log.debug("Tunnel to proxy created.");
                    managedConn.tunnelProxy(route.getHopTarget(hop), secure, this.params);
                }
                break;
            case HttpRouteDirector.LAYER_PROTOCOL:
                managedConn.layerProtocol(context, this.params);
                break;
            case HttpRouteDirector.UNREACHABLE:
                throw new IllegalStateException("Unable to establish route." + "\nplanned = " + route + "\ncurrent = " + fact);
            case HttpRouteDirector.COMPLETE:
                // do nothing
                break;
            default:
                throw new IllegalStateException("Unknown step indicator " + step + " from RouteDirector.");
        }
    // switch
    } while (step > HttpRouteDirector.COMPLETE);
}
Also used : HttpRoute(org.apache.http.conn.routing.HttpRoute) BasicRouteDirector(org.apache.http.conn.routing.BasicRouteDirector) HttpRouteDirector(org.apache.http.conn.routing.HttpRouteDirector)

Example 9 with HttpRoute

use of org.apache.http.conn.routing.HttpRoute in project XobotOS by xamarin.

the class ProxySelectorRoutePlanner method determineRoute.

// non-javadoc, see interface HttpRoutePlanner
public HttpRoute determineRoute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException {
    if (request == null) {
        throw new IllegalStateException("Request must not be null.");
    }
    // If we have a forced route, we can do without a target.
    HttpRoute route = ConnRouteParams.getForcedRoute(request.getParams());
    if (route != null)
        return route;
    if (target == null) {
        throw new IllegalStateException("Target host must not be null.");
    }
    final InetAddress local = ConnRouteParams.getLocalAddress(request.getParams());
    // BEGIN android-changed
    //     If the client or request explicitly specifies a proxy (or no
    //     proxy), prefer that over the ProxySelector's VM-wide default.
    HttpHost proxy = (HttpHost) request.getParams().getParameter(ConnRoutePNames.DEFAULT_PROXY);
    if (proxy == null) {
        proxy = determineProxy(target, request, context);
    } else if (ConnRouteParams.NO_HOST.equals(proxy)) {
        // value is explicitly unset
        proxy = null;
    }
    // END android-changed
    final Scheme schm = this.schemeRegistry.getScheme(target.getSchemeName());
    // as it is typically used for TLS/SSL, we assume that
    // a layered scheme implies a secure connection
    final boolean secure = schm.isLayered();
    if (proxy == null) {
        route = new HttpRoute(target, local, secure);
    } else {
        route = new HttpRoute(target, local, proxy, secure);
    }
    return route;
}
Also used : HttpRoute(org.apache.http.conn.routing.HttpRoute) Scheme(org.apache.http.conn.scheme.Scheme) HttpHost(org.apache.http.HttpHost) InetAddress(java.net.InetAddress)

Example 10 with HttpRoute

use of org.apache.http.conn.routing.HttpRoute in project XobotOS by xamarin.

the class AbstractConnPool method handleReference.

// non-javadoc, see interface RefQueueHandler
// BEGIN android-changed
public void handleReference(Reference ref) {
    // END android-changed
    poolLock.lock();
    try {
        if (ref instanceof BasicPoolEntryRef) {
            // check if the GCed pool entry was still in use
            //@@@ find a way to detect this without lookup
            //@@@ flag in the BasicPoolEntryRef, to be reset when freed?
            final boolean lost = issuedConnections.remove(ref);
            if (lost) {
                final HttpRoute route = ((BasicPoolEntryRef) ref).getRoute();
                if (log.isDebugEnabled()) {
                    log.debug("Connection garbage collected. " + route);
                }
                handleLostEntry(route);
            }
        }
    } finally {
        poolLock.unlock();
    }
}
Also used : HttpRoute(org.apache.http.conn.routing.HttpRoute)

Aggregations

HttpRoute (org.apache.http.conn.routing.HttpRoute)33 HttpHost (org.apache.http.HttpHost)17 HttpRequest (org.apache.http.HttpRequest)9 AbortableHttpRequest (org.apache.http.client.methods.AbortableHttpRequest)8 BasicHttpRequest (org.apache.http.message.BasicHttpRequest)8 InetAddress (java.net.InetAddress)7 IOException (java.io.IOException)6 HttpException (org.apache.http.HttpException)6 Scheme (org.apache.http.conn.scheme.Scheme)6 HttpResponse (org.apache.http.HttpResponse)5 AuthenticationException (org.apache.http.auth.AuthenticationException)5 RedirectException (org.apache.http.client.RedirectException)5 ClientConnectionRequest (org.apache.http.conn.ClientConnectionRequest)5 HttpParams (org.apache.http.params.HttpParams)5 InterruptedIOException (java.io.InterruptedIOException)4 URI (java.net.URI)4 Header (org.apache.http.Header)4 HttpEntity (org.apache.http.HttpEntity)4 CredentialsProvider (org.apache.http.client.CredentialsProvider)4 NonRepeatableRequestException (org.apache.http.client.NonRepeatableRequestException)4