Example #1
0
  /**
   * Handle the call and follow redirection for safe methods.
   *
   * @param request The request to send.
   * @param response The response to update.
   * @param references The references that caused a redirection to prevent infinite loops.
   * @param retryAttempt The number of remaining attempts.
   * @param next The next handler handling the call.
   */
  private void handle(
      Request request,
      Response response,
      List<Reference> references,
      int retryAttempt,
      Uniform next) {
    if (next != null) {
      // Actually handle the call
      next.handle(request, response);

      // Check for redirections
      if (isFollowingRedirects()
          && response.getStatus().isRedirection()
          && (response.getLocationRef() != null)) {
        boolean doRedirection = false;

        if (request.getMethod().isSafe()) {
          doRedirection = true;
        } else {
          if (Status.REDIRECTION_SEE_OTHER.equals(response.getStatus())) {
            // The user agent is redirected using the GET method
            request.setMethod(Method.GET);
            request.setEntity(null);
            doRedirection = true;
          } else if (Status.REDIRECTION_USE_PROXY.equals(response.getStatus())) {
            doRedirection = true;
          }
        }

        if (doRedirection) {
          Reference newTargetRef = response.getLocationRef();

          if ((references != null) && references.contains(newTargetRef)) {
            getLogger().warning("Infinite redirection loop detected with URI: " + newTargetRef);
          } else if (request.getEntity() != null && !request.isEntityAvailable()) {
            getLogger()
                .warning(
                    "Unable to follow the redirection because the request entity isn't available anymore.");
          } else {
            if (references == null) {
              references = new ArrayList<Reference>();
            }

            // Add to the list of redirection reference
            // to prevent infinite loops
            references.add(request.getResourceRef());
            request.setResourceRef(newTargetRef);
            handle(request, response, references, 0, next);
          }
        }
      } else if (isRetryOnError()
          && response.getStatus().isRecoverableError()
          && request.getMethod().isIdempotent()
          && (retryAttempt < getRetryAttempts())
          && ((request.getEntity() == null) || request.getEntity().isAvailable())) {
        getLogger()
            .log(
                Level.INFO,
                "A recoverable error was detected ("
                    + response.getStatus().getCode()
                    + "), attempting again in "
                    + getRetryDelay()
                    + " ms.");

        // Wait before attempting again
        if (getRetryDelay() > 0) {
          try {
            Thread.sleep(getRetryDelay());
          } catch (InterruptedException e) {
            getLogger().log(Level.FINE, "Retry delay sleep was interrupted", e);
          }
        }

        // Retry the call
        handle(request, response, references, ++retryAttempt, next);
      }
    }
  }