Example usage for org.apache.http.protocol ExecutionContext HTTP_PROXY_HOST

List of usage examples for org.apache.http.protocol ExecutionContext HTTP_PROXY_HOST

Introduction

In this page you can find the example usage for org.apache.http.protocol ExecutionContext HTTP_PROXY_HOST.

Prototype

String HTTP_PROXY_HOST

To view the source code for org.apache.http.protocol ExecutionContext HTTP_PROXY_HOST.

Click Source Link

Usage

From source file:com.grendelscan.commons.http.apache_overrides.client.CustomClientRequestDirector.java

/**
 * 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.
 * //from ww w .  ja v  a  2s  .  c om
 * @param route
 *            the route to establish
 * @param context
 *            the context for request execution
 * 
 * @return <code>true</code> if the tunnelled route is secure,
 *         <code>false</code> otherwise.
 *         The implementation here always returns <code>false</code>,
 *         but derived classes may override.
 * 
 * @throws HttpException
 *             in case of a problem
 * @throws IOException
 *             in case of an IO problem
 */
private boolean createTunnelToTarget(HttpRoute route, HttpContext context) throws HttpException, IOException {

    HttpHost proxy = route.getProxyHost();
    HttpHost target = route.getTargetHost();
    HttpResponse response = null;

    boolean done = false;
    while (!done) {

        done = true;

        if (!managedConn.isOpen()) {
            managedConn.open(route, context, params);
        }

        HttpRequest connect = createConnectRequest(route);
        connect.setParams(params);

        // 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);
        context.setAttribute(ExecutionContext.HTTP_REQUEST, connect);

        requestExec.preProcess(connect, httpProcessor, context);

        response = requestExec.execute(connect, managedConn, context);

        response.setParams(params);
        requestExec.postProcess(response, httpProcessor, context);

        int status = response.getStatusLine().getStatusCode();
        if (status < 200) {
            throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine());
        }

        CredentialsProvider credsProvider = (CredentialsProvider) context
                .getAttribute(ClientContext.CREDS_PROVIDER);

        if ((credsProvider != null) && HttpClientParams.isAuthenticating(params)) {
            if (proxyAuthHandler.isAuthenticationRequested(response, context)) {

                LOGGER.debug("Proxy requested authentication");
                Map<String, Header> challenges = proxyAuthHandler.getChallenges(response, context);
                try {
                    processChallenges(challenges, proxyAuthState, proxyAuthHandler, response, context);
                } catch (AuthenticationException ex) {
                    LOGGER.warn("Authentication error: " + ex.getMessage());
                }
                updateAuthState(proxyAuthState, proxy, credsProvider);

                if (proxyAuthState.getCredentials() != null) {
                    done = false;

                    // Retry request
                    if (reuseStrategy.keepAlive(response, context)) {
                        LOGGER.debug("Connection kept alive");
                        // Consume response content
                        HttpEntity entity = response.getEntity();
                        if (entity != null) {
                            entity.consumeContent();
                        }
                    } else {
                        managedConn.close();
                    }

                }

            } else {
                // Reset proxy auth scope
                proxyAuthState.setAuthScope(null);
            }
        }
    }

    int status = response.getStatusLine().getStatusCode(); // can't be null

    if (status > 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);
    }

    managedConn.markReusable();

    // 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;

}

From source file:org.robolectric.shadows.httpclient.DefaultRequestDirector.java

/**
 * 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.
 *
 * @param route     the route to establish
 * @param context   the context for request execution
 *
 * @return  <code>true</code> if the tunnelled route is secure,
 *          <code>false</code> otherwise.
 *          The implementation here always returns <code>false</code>,
 *          but derived classes may override.
 *
 * @throws HttpException    in case of a problem
 * @throws IOException      in case of an IO problem
 *//*from w w  w .  ja  v  a 2  s.  co  m*/
protected boolean createTunnelToTarget(HttpRoute route, HttpContext context) throws HttpException, IOException {

    HttpHost proxy = route.getProxyHost();
    HttpHost target = route.getTargetHost();
    HttpResponse response = null;

    boolean done = false;
    while (!done) {

        done = true;

        if (!this.managedConn.isOpen()) {
            this.managedConn.open(route, context, this.params);
        }

        HttpRequest connect = createConnectRequest(route, context);
        connect.setParams(this.params);

        // 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);
        context.setAttribute(ExecutionContext.HTTP_REQUEST, connect);

        this.requestExec.preProcess(connect, this.httpProcessor, context);

        response = this.requestExec.execute(connect, this.managedConn, context);

        response.setParams(this.params);
        this.requestExec.postProcess(response, this.httpProcessor, context);

        int status = response.getStatusLine().getStatusCode();
        if (status < 200) {
            throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine());
        }

        CredentialsProvider credsProvider = (CredentialsProvider) context
                .getAttribute(ClientContext.CREDS_PROVIDER);

        if (credsProvider != null && HttpClientParams.isAuthenticating(params)) {
            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());
                        break;
                    }
                }
                updateAuthState(this.proxyAuthState, proxy, credsProvider);

                if (this.proxyAuthState.getCredentials() != null) {
                    done = false;

                    // Retry request
                    if (this.reuseStrategy.keepAlive(response, context)) {
                        this.log.debug("Connection kept alive");
                        // Consume response content
                        HttpEntity entity = response.getEntity();
                        if (entity != null) {
                            entity.consumeContent();
                        }
                    } else {
                        this.managedConn.close();
                    }

                }

            } else {
                // Reset proxy auth scope
                this.proxyAuthState.setAuthScope(null);
            }
        }
    }

    int status = response.getStatusLine().getStatusCode(); // can't be null

    if (status > 299) {

        // Buffer response content
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            response.setEntity(new BufferedHttpEntity(entity));
        }

        this.managedConn.close();
        throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response);
    }

    this.managedConn.markReusable();

    // 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;

}

From source file:org.vietspider.net.apache.DefaultRequestDirector.java

/**
 * 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.
 *
 * @param route     the route to establish
 * @param context   the context for request execution
 *
 * @return  <code>true</code> if the tunnelled route is secure,
 *          <code>false</code> otherwise.
 *          The implementation here always returns <code>false</code>,
 *          but derived classes may override.
 *
 * @throws HttpException    in case of a problem
 * @throws IOException      in case of an IO problem
 *//*  w w w .  j a v  a 2  s. c o  m*/
protected boolean createTunnelToTarget(HttpRoute route, HttpContext context) throws HttpException, IOException {

    HttpHost proxy = route.getProxyHost();
    HttpHost target = route.getTargetHost();
    HttpResponse response = null;

    boolean done = false;
    while (!done) {

        done = true;

        if (!this.managedConn.isOpen()) {
            this.managedConn.open(route, context, this.params);
        }

        HttpRequest connect = createConnectRequest(route, context);
        connect.setParams(this.params);

        // 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);
        context.setAttribute(ExecutionContext.HTTP_REQUEST, connect);

        this.requestExec.preProcess(connect, this.httpProcessor, context);

        response = this.requestExec.execute(connect, this.managedConn, context);

        response.setParams(this.params);
        this.requestExec.postProcess(response, this.httpProcessor, context);

        int status = response.getStatusLine().getStatusCode();
        if (status < 200) {
            throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine());
        }

        CredentialsProvider credsProvider = (CredentialsProvider) context
                .getAttribute(ClientContext.CREDS_PROVIDER);

        if (credsProvider != null && HttpClientParams.isAuthenticating(params)) {
            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());
                        break;
                    }
                }
                updateAuthState(this.proxyAuthState, proxy, credsProvider);

                if (this.proxyAuthState.getCredentials() != null) {
                    done = false;

                    // 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 {
                        this.managedConn.close();
                    }

                }

            } else {
                // Reset proxy auth scope
                this.proxyAuthState.setAuthScope(null);
            }
        }
    }

    int status = response.getStatusLine().getStatusCode(); // can't be null

    if (status > 299) {

        // Buffer response content
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            response.setEntity(new BufferedHttpEntity(entity));
        }

        this.managedConn.close();
        throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response);
    }

    this.managedConn.markReusable();

    // 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;

}

From source file:org.apache.http.client.protocol.ResponseAuthCache.java

public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException {
    Args.notNull(response, "HTTP request");
    Args.notNull(context, "HTTP context");
    AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE);

    HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
    final AuthState targetState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
    if (target != null && targetState != null) {
        if (this.log.isDebugEnabled()) {
            this.log.debug("Target auth state: " + targetState.getState());
        }/*from w  ww.ja va 2  s  . c om*/
        if (isCachable(targetState)) {
            final SchemeRegistry schemeRegistry = (SchemeRegistry) context
                    .getAttribute(ClientContext.SCHEME_REGISTRY);
            if (target.getPort() < 0) {
                final Scheme scheme = schemeRegistry.getScheme(target);
                target = new HttpHost(target.getHostName(), scheme.resolvePort(target.getPort()),
                        target.getSchemeName());
            }
            if (authCache == null) {
                authCache = new BasicAuthCache();
                context.setAttribute(ClientContext.AUTH_CACHE, authCache);
            }
            switch (targetState.getState()) {
            case CHALLENGED:
                cache(authCache, target, targetState.getAuthScheme());
                break;
            case FAILURE:
                uncache(authCache, target, targetState.getAuthScheme());
            }
        }
    }

    final HttpHost proxy = (HttpHost) context.getAttribute(ExecutionContext.HTTP_PROXY_HOST);
    final AuthState proxyState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE);
    if (proxy != null && proxyState != null) {
        if (this.log.isDebugEnabled()) {
            this.log.debug("Proxy auth state: " + proxyState.getState());
        }
        if (isCachable(proxyState)) {
            if (authCache == null) {
                authCache = new BasicAuthCache();
                context.setAttribute(ClientContext.AUTH_CACHE, authCache);
            }
            switch (proxyState.getState()) {
            case CHALLENGED:
                cache(authCache, proxy, proxyState.getAuthScheme());
                break;
            case FAILURE:
                uncache(authCache, proxy, proxyState.getAuthScheme());
            }
        }
    }
}

From source file:org.apache.http.impl.client.DefaultRequestDirector.java

/**
 * 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.
 *
 * @param route     the route to establish
 * @param context   the context for request execution
 *
 * @return  <code>true</code> if the tunnelled route is secure,
 *          <code>false</code> otherwise.
 *          The implementation here always returns <code>false</code>,
 *          but derived classes may override.
 *
 * @throws HttpException    in case of a problem
 * @throws IOException      in case of an IO problem
 *//*from   w  ww  .  j  a va 2 s. c om*/
protected boolean createTunnelToTarget(final HttpRoute route, final HttpContext context)
        throws HttpException, IOException {

    final HttpHost proxy = route.getProxyHost();
    final HttpHost target = route.getTargetHost();
    HttpResponse response = null;

    for (;;) {
        if (!this.managedConn.isOpen()) {
            this.managedConn.open(route, context, this.params);
        }

        final HttpRequest connect = createConnectRequest(route, context);
        connect.setParams(this.params);

        // 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(ExecutionContext.HTTP_REQUEST, connect);

        this.requestExec.preProcess(connect, this.httpProcessor, context);

        response = this.requestExec.execute(connect, this.managedConn, context);

        response.setParams(this.params);
        this.requestExec.postProcess(response, this.httpProcessor, context);

        final int status = response.getStatusLine().getStatusCode();
        if (status < 200) {
            throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine());
        }

        if (HttpClientParams.isAuthenticating(this.params)) {
            if (this.authenticator.isAuthenticationRequested(proxy, response, this.proxyAuthStrategy,
                    this.proxyAuthState, context)) {
                if (this.authenticator.authenticate(proxy, response, this.proxyAuthStrategy,
                        this.proxyAuthState, context)) {
                    // Retry request
                    if (this.reuseStrategy.keepAlive(response, context)) {
                        this.log.debug("Connection kept alive");
                        // Consume response content
                        final HttpEntity entity = response.getEntity();
                        EntityUtils.consume(entity);
                    } else {
                        this.managedConn.close();
                    }
                } else {
                    break;
                }
            } else {
                break;
            }
        }
    }

    final int status = response.getStatusLine().getStatusCode();

    if (status > 299) {

        // Buffer response content
        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            response.setEntity(new BufferedHttpEntity(entity));
        }

        this.managedConn.close();
        throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response);
    }

    this.managedConn.markReusable();

    // 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;

}

From source file:org.apache.http.impl.client.StatiscicsLoggingRequestDirector.java

public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context)
        throws HttpException, IOException {

    HttpRequest orig = request;// w ww  . j  a  v  a 2 s .c om
    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 = HttpConnectionParams.getConnectionTimeout(params);

    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);
            }

            try {
                tryConnect(roureq, 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);

            synchronized (connectionStats) {
                ConnectionStatistics stats = new ConnectionStatistics();
                stats.setConnectionState(State.OPEN);
                stats.setLastUsed(System.currentTimeMillis());
                stats.setLastRequest(request.getRequestLine().getUri());
                connectionStats.put(java.lang.System.identityHashCode(managedConn), stats);
            }

            // Run request protocol interceptors
            requestExec.preProcess(wrapper, httpProcessor, context);

            response = tryExecute(roureq, context);
            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);
                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);
                }
                managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS);
            }

            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();
                    EntityUtils.consume(entity);
                    // 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);
                }
            }

        } // while not done

        // 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 StatisticsAwareManagedEntity(entity, managedConn, reuse, this.connectionStats);
            response.setEntity(entity);
        }

        return response;

    } catch (ConnectionShutdownException ex) {
        InterruptedIOException ioex = new InterruptedIOException("Connection has been shut down");
        ioex.initCause(ex);
        throw ioex;
    } catch (HttpException ex) {
        abortConnection();
        throw ex;
    } catch (IOException ex) {
        abortConnection();
        throw ex;
    } catch (RuntimeException ex) {
        abortConnection();
        throw ex;
    }
}

From source file:org.apache.http.impl.client.DefaultRequestDirector.java

/**
 * 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.
 *
 * @param route     the route to establish
 * @param context   the context for request execution
 *
 * @return  {@code true} if the tunnelled route is secure,
 *          {@code false} otherwise.//from   w  w  w .ja  v  a 2s . c  o m
 *          The implementation here always returns {@code false},
 *          but derived classes may override.
 *
 * @throws HttpException    in case of a problem
 * @throws IOException      in case of an IO problem
 */
protected boolean createTunnelToTarget(final HttpRoute route, final HttpContext context)
        throws HttpException, IOException {

    final HttpHost proxy = route.getProxyHost();
    final HttpHost target = route.getTargetHost();
    HttpResponse response = null;

    for (;;) {
        if (!this.managedConn.isOpen()) {
            this.managedConn.open(route, context, this.params);
        }

        final HttpRequest connect = createConnectRequest(route, context);
        connect.setParams(this.params);

        // Populate the execution context
        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
        context.setAttribute(ClientContext.ROUTE, route);
        context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy);
        context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn);
        context.setAttribute(ExecutionContext.HTTP_REQUEST, connect);

        this.requestExec.preProcess(connect, this.httpProcessor, context);

        response = this.requestExec.execute(connect, this.managedConn, context);

        response.setParams(this.params);
        this.requestExec.postProcess(response, this.httpProcessor, context);

        final int status = response.getStatusLine().getStatusCode();
        if (status < 200) {
            throw new HttpException("Unexpected response to CONNECT request: " + response.getStatusLine());
        }

        if (HttpClientParams.isAuthenticating(this.params)) {
            if (this.authenticator.isAuthenticationRequested(proxy, response, this.proxyAuthStrategy,
                    this.proxyAuthState, context)) {
                if (this.authenticator.authenticate(proxy, response, this.proxyAuthStrategy,
                        this.proxyAuthState, context)) {
                    // Retry request
                    if (this.reuseStrategy.keepAlive(response, context)) {
                        this.log.debug("Connection kept alive");
                        // Consume response content
                        final HttpEntity entity = response.getEntity();
                        EntityUtils.consume(entity);
                    } else {
                        this.managedConn.close();
                    }
                } else {
                    break;
                }
            } else {
                break;
            }
        }
    }

    final int status = response.getStatusLine().getStatusCode();

    if (status > 299) {

        // Buffer response content
        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            response.setEntity(new BufferedHttpEntity(entity));
        }

        this.managedConn.close();
        throw new TunnelRefusedException("CONNECT refused by proxy: " + response.getStatusLine(), response);
    }

    this.managedConn.markReusable();

    // 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;

}

From source file:org.apache.http.impl.nio.client.DefaultAsyncRequestDirector.java

@Override
public synchronized HttpRequest generateRequest() throws IOException, HttpException {
    final HttpRoute route = this.mainRequest.getRoute();
    if (!this.routeEstablished) {
        int step;
        do {/*from w ww. java  2  s.c  o m*/
            final HttpRoute fact = this.managedConn.getRoute();
            step = this.routeDirector.nextStep(route, fact);
            switch (step) {
            case HttpRouteDirector.CONNECT_TARGET:
            case HttpRouteDirector.CONNECT_PROXY:
                break;
            case HttpRouteDirector.TUNNEL_TARGET:
                if (this.log.isDebugEnabled()) {
                    this.log.debug("[exchange: " + this.id + "] Tunnel required");
                }
                final HttpRequest connect = createConnectRequest(route);
                this.currentRequest = wrapRequest(connect);
                this.currentRequest.setParams(this.params);
                break;
            case HttpRouteDirector.TUNNEL_PROXY:
                throw new HttpException("Proxy chains are not supported");
            case HttpRouteDirector.LAYER_PROTOCOL:
                managedConn.layerProtocol(this.localContext, this.params);
                break;
            case HttpRouteDirector.UNREACHABLE:
                throw new HttpException(
                        "Unable to establish route: " + "planned = " + route + "; current = " + fact);
            case HttpRouteDirector.COMPLETE:
                this.routeEstablished = true;
                break;
            default:
                throw new IllegalStateException("Unknown step indicator " + step + " from RouteDirector.");
            }
        } while (step > HttpRouteDirector.COMPLETE && this.currentRequest == null);
    }

    HttpHost target = (HttpHost) this.params.getParameter(ClientPNames.VIRTUAL_HOST);
    if (target == null) {
        target = route.getTargetHost();
    }
    final HttpHost proxy = route.getProxyHost();
    this.localContext.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
    this.localContext.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy);
    this.localContext.setAttribute(ExecutionContext.HTTP_CONNECTION, this.managedConn);
    this.localContext.setAttribute(ClientContext.ROUTE, route);

    if (this.currentRequest == null) {
        this.currentRequest = this.mainRequest.getRequest();

        final String userinfo = this.currentRequest.getURI().getUserInfo();
        if (userinfo != null) {
            this.targetAuthState.update(new BasicScheme(), new UsernamePasswordCredentials(userinfo));
        }

        // Re-write request URI if needed
        rewriteRequestURI(this.currentRequest, route);
    }
    // Reset headers on the request wrapper
    this.currentRequest.resetHeaders();

    this.currentRequest.incrementExecCount();
    if (this.currentRequest.getExecCount() > 1 && !this.requestProducer.isRepeatable()
            && this.requestContentProduced) {
        throw new NonRepeatableRequestException(
                "Cannot retry request " + "with a non-repeatable request entity.");
    }
    this.execCount++;
    if (this.log.isDebugEnabled()) {
        this.log.debug("[exchange: " + this.id + "] Attempt " + this.execCount + " to execute request");
    }
    return this.currentRequest;
}