/**
   * Aggressively tries to get the final HTTP response, potentially making many HTTP requests in the
   * process in order to cope with redirects and authentication.
   */
  private HttpEngine getResponse() throws IOException {
    initHttpEngine();

    if (httpEngine.hasResponse()) {
      return httpEngine;
    }

    while (true) {
      if (!execute(true)) {
        continue;
      }

      Retry retry = processResponseHeaders();
      if (retry == Retry.NONE) {
        httpEngine.automaticallyReleaseConnectionToPool();
        return httpEngine;
      }

      // The first request was insufficient. Prepare for another...
      String retryMethod = method;
      OutputStream requestBody = httpEngine.getRequestBody();

      // Although RFC 2616 10.3.2 specifies that a HTTP_MOVED_PERM
      // redirect should keep the same method, Chrome, Firefox and the
      // RI all issue GETs when following any redirect.
      int responseCode = getResponseCode();
      if (responseCode == HTTP_MULT_CHOICE
          || responseCode == HTTP_MOVED_PERM
          || responseCode == HTTP_MOVED_TEMP
          || responseCode == HTTP_SEE_OTHER) {
        retryMethod = "GET";
        requestBody = null;
      }

      if (requestBody != null && !(requestBody instanceof RetryableOutputStream)) {
        throw new HttpRetryException(
            "Cannot retry streamed HTTP body", httpEngine.getResponseCode());
      }

      if (retry == Retry.DIFFERENT_CONNECTION) {
        httpEngine.automaticallyReleaseConnectionToPool();
      }

      httpEngine.release(false);

      httpEngine =
          newHttpEngine(
              retryMethod,
              rawRequestHeaders,
              httpEngine.getConnection(),
              (RetryableOutputStream) requestBody);
    }
  }
 /**
  * Returns an input stream from the server in the case of error such as the requested file (txt,
  * htm, html) is not found on the remote server.
  */
 @Override
 public final InputStream getErrorStream() {
   try {
     HttpEngine response = getResponse();
     if (response.hasResponseBody() && response.getResponseCode() >= HTTP_BAD_REQUEST) {
       return response.getResponseBody();
     }
     return null;
   } catch (IOException e) {
     return null;
   }
 }