예제 #1
0
  /**
   * Process the redirect response.
   *
   * @return <code>true</code> if the redirect was successful
   */
  private boolean processRedirectResponse(final HttpMethod method) throws RedirectException {
    // get the location header to find out where to redirect to
    Header locationHeader = method.getResponseHeader("location");
    if (locationHeader == null) {
      // got a redirect response, but no location header
      LOG.error("Received redirect response " + method.getStatusCode() + " but no location header");
      return false;
    }
    String location = locationHeader.getValue();
    if (LOG.isDebugEnabled()) {
      LOG.debug("Redirect requested to location '" + location + "'");
    }

    // rfc2616 demands the location value be a complete URI
    // Location       = "Location" ":" absoluteURI
    URI redirectUri = null;
    URI currentUri = null;

    try {
      currentUri =
          new URI(
              this.conn.getProtocol().getScheme(),
              null,
              this.conn.getHost(),
              this.conn.getPort(),
              method.getPath());

      String charset = method.getParams().getUriCharset();
      redirectUri = new URI(location, true, charset);

      if (redirectUri.isRelativeURI()) {
        if (this.params.isParameterTrue(HttpClientParams.REJECT_RELATIVE_REDIRECT)) {
          LOG.warn("Relative redirect location '" + location + "' not allowed");
          return false;
        } else {
          // location is incomplete, use current values for defaults
          LOG.debug("Redirect URI is not absolute - parsing as relative");
          redirectUri = new URI(currentUri, redirectUri);
        }
      } else {
        // Reset the default params
        method.getParams().setDefaults(this.params);
      }
      method.setURI(redirectUri);
      hostConfiguration.setHost(redirectUri);
    } catch (URIException ex) {
      throw new InvalidRedirectLocationException(
          "Invalid redirect location: " + location, location, ex);
    }

    if (this.params.isParameterFalse(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS)) {
      if (this.redirectLocations == null) {
        this.redirectLocations = new HashSet();
      }
      this.redirectLocations.add(currentUri);
      try {
        if (redirectUri.hasQuery()) {
          redirectUri.setQuery(null);
        }
      } catch (URIException e) {
        // Should never happen
        return false;
      }

      if (this.redirectLocations.contains(redirectUri)) {
        throw new CircularRedirectException("Circular redirect to '" + redirectUri + "'");
      }
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "Redirecting from '"
              + currentUri.getEscapedURI()
              + "' to '"
              + redirectUri.getEscapedURI());
    }
    // And finally invalidate the actual authentication scheme
    method.getHostAuthState().invalidate();
    return true;
  }