shadows/httpclient/src/main/java/org/robolectric/shadows/httpclient/DefaultRequestDirector.java
protected RoutedRequest handleResponse(RoutedRequest roureq,
                       HttpResponse response,
                       HttpContext context)
    throws HttpException, IOException {

    HttpRoute route = roureq.getRoute();
    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++;

      // Virtual host cannot be used any longer
      virtualHost = null;

      URI uri = this.redirectHandler.getLocationURI(response, context);

      HttpHost newTarget = new HttpHost(
          uri.getHost(),
          uri.getPort(),
          uri.getScheme());

      // Unset auth scope
      targetAuthState.setAuthScope(null);
      proxyAuthState.setAuthScope(null);

      // Invalidate auth states if redirecting to another host
      if (!route.getTargetHost().equals(newTarget)) {
        targetAuthState.invalidate();
        AuthScheme authScheme = proxyAuthState.getAuthScheme();
        if (authScheme != null && authScheme.isConnectionBased()) {
          proxyAuthState.invalidate();
        }
      }

      HttpRedirect redirect = new HttpRedirect(request.getMethod(), 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)) {

        HttpHost proxy = route.getProxyHost();

        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;
  }
protected RoutedRequest handleResponse(RoutedRequest roureq,
                       HttpResponse response,
                       HttpContext context)
    throws HttpException, IOException {

    HttpRoute route = roureq.getRoute();
    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++;

      // Virtual host cannot be used any longer
      virtualHost = null;

      URI uri = this.redirectHandler.getLocationURI(response, context);

      HttpHost newTarget = new HttpHost(
          uri.getHost(),
          uri.getPort(),
          uri.getScheme());

      // Unset auth scope
      targetAuthState.setAuthScope(null);
      proxyAuthState.setAuthScope(null);

      // Invalidate auth states if redirecting to another host
      if (!route.getTargetHost().equals(newTarget)) {
        targetAuthState.invalidate();
        AuthScheme authScheme = proxyAuthState.getAuthScheme();
        if (authScheme != null && authScheme.isConnectionBased()) {
          proxyAuthState.invalidate();
        }
      }

      HttpRedirect redirect = new HttpRedirect(request.getMethod(), 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)) {

        HttpHost proxy = route.getProxyHost();

        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;
  }
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} if the response should be returned as is

@throws HttpException    in case of a problem
@throws IOException      in case of an IO problem