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;

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

      
      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;

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

          }

        } else {
          
          this.proxyAuthState.setAuthScope(null);
        }
      }
    }

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

    if (status > 299) {

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

    
    
    
    
    return false;

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