@Test
 public void testHandledTransformerException() throws Exception {
   HttpMethodBase request = createRequest(getBaseUri() + "/handledTransformerException");
   int status = httpClient.executeMethod(request);
   assertEquals(HttpConstants.SC_OK, status);
   assertTrue(request.getResponseBodyAsString().contains("Success"));
 }
 @Test
 public void testRouterException() throws Exception {
   HttpMethodBase request = createRequest(getBaseUri() + "/routerException");
   int status = httpClient.executeMethod(request);
   assertEquals(HttpConstants.SC_INTERNAL_SERVER_ERROR, status);
   assertTrue(request.getResponseBodyAsString().contains("Failure"));
 }
 @Test
 public void testNoException() throws Exception {
   HttpMethodBase request = createRequest(getBaseUri() + "/noException");
   int status = httpClient.executeMethod(request);
   assertEquals(HttpConstants.SC_OK, status);
   assertEquals("Here you go", request.getResponseBodyAsString());
 }
 @Test
 public void testComponentException() throws Exception {
   HttpMethodBase request = createRequest(getBaseUri() + "/componentException");
   int status = httpClient.executeMethod(request);
   // Component exception occurs after the SEDA queue for an asynchronous request, but since
   // this request is synchronous, the failure propagates back to the client.
   assertEquals(HttpConstants.SC_INTERNAL_SERVER_ERROR, status);
   assertTrue(request.getResponseBodyAsString().contains("exception"));
 }
Пример #5
0
  public void testCallServlet() {
    boolean result = true;
    try {
      // run tests by calling a servlet
      Header runParam = new Header("run", "run");
      HttpMethodBase request =
          HttpUtils.accessURL(
              new URL(serverUrl),
              null,
              HttpURLConnection.HTTP_OK,
              new Header[] {runParam},
              HttpUtils.POST);

      String response = null;
      int index = 0;
      do {
        System.err.println("_____________ " + (index++) + "th round");
        // we have to give some time to the tests to finish
        Thread.sleep(10000); // 10 secs

        // tries to get results
        request =
            HttpUtils.accessURL(new URL(serverUrl), null, HttpURLConnection.HTTP_OK, HttpUtils.GET);

        response = request.getResponseBodyAsString();
      } while (response != null && response.indexOf("finished") == -1 && index < LOOP_RETRY_MAX);

      if (response != null && response.indexOf("finished") == -1) {
        System.err.println("======================================================");
        System.err.println("====================  TIMED OUT  =====================");
        System.err.println("======================================================");
        result = false;
      } else {
        System.err.println("======================================================");
        System.err.println("====================   RESULT    =====================");
        System.err.println("======================================================");
        System.err.println(response);
        // writes response to the outfile
        BufferedWriter writer = new BufferedWriter(new FileWriter(outfile));
        writer.write(response);
        writer.close();
      }
    } catch (Exception e) {
      System.err.println("======================================================");
      System.err.println("====================  EXCEPTION  =====================");
      System.err.println("======================================================");
      e.printStackTrace();
      result = false;
    }

    assertTrue(result);
  }
Пример #6
0
 public void executeMethod(final HttpMethodBase method) throws CloudstackRESTException {
   try {
     validation.executeMethod(method, client, protocol);
   } catch (final HttpException e) {
     s_logger.error("HttpException caught while trying to connect to the REST Service", e);
     method.releaseConnection();
     throw new CloudstackRESTException("API call to REST Service Failed", e);
   } catch (final IOException e) {
     s_logger.error("IOException caught while trying to connect to the REST Service", e);
     method.releaseConnection();
     throw new CloudstackRESTException("API call to Nicira REST Service Failed", e);
   }
 }
Пример #7
0
  /**
   * Run the first test.
   *
   * @param string a part of URL to connect to.
   * @return ManagerClient object
   * @throws IOException for any failures.
   */
  public ManagerClient(String string) throws Exception {
    URL = "http://" + string + "/mod_cluster_manager/";
    GetMethod gm = null;
    HttpMethodBase bm = null;
    if (httpClient == null) {
      httpClient = new HttpClient();
      gm = new GetMethod(URL);
      bm = gm;
    }

    System.out.println("Connecting to " + URL);

    Integer connectionTimeout = 40000;
    bm.getParams().setParameter("http.socket.timeout", connectionTimeout);
    bm.getParams().setParameter("http.connection.timeout", connectionTimeout);
    httpClient.getParams().setParameter("http.socket.timeout", connectionTimeout);
    httpClient.getParams().setParameter("http.connection.timeout", connectionTimeout);

    try {
      httpResponseCode = httpClient.executeMethod(gm);

      if (httpResponseCode == 200) {
        // Read the nonce.
        String result = gm.getResponseBodyAsString();
        String[] records = result.split("\n");
        for (int i = 0; i < records.length; i++) {
          int j = records[i].indexOf("?nonce=");
          if (j < 0) continue;
          j = j + 7;
          String nnonce = records[i].substring(j);
          int k = nnonce.indexOf('&');
          if (k > 0) {
            nonce = nnonce.substring(0, k);
            break;
          }
        }
      } else {
        System.out.println("response: " + httpResponseCode);
        System.out.println("response: " + bm.getStatusLine());
        throw (new Exception("Reponse notok"));
      }
      // System.out.println("response:\n" + bm.getResponseBodyAsString(len));
    } catch (HttpException e) {
      System.out.println("error: " + e);
      throw (e);
    }
    bm.releaseConnection();
  }
Пример #8
0
 @Override
 public void addAuthentication(final HttpClient httpClient, final HttpMethodBase method)
     throws ProponoException {
   httpClient.getParams().setAuthenticationPreemptive(true);
   final String header = "Basic " + credentials;
   method.setRequestHeader("Authorization", header);
 }
Пример #9
0
  private String responseToErrorMessage(final HttpMethodBase method) {
    assert method.isRequestSent() : "no use getting an error message unless the request is sent";

    if (TEXT_HTML_CONTENT_TYPE.equals(method.getResponseHeader(CONTENT_TYPE).getValue())) {
      // The error message is the response content
      // Safety margin of 1024 characters, anything longer is probably useless
      // and will clutter the logs
      try {
        return method.getResponseBodyAsString(BODY_RESP_MAX_LEN);
      } catch (final IOException e) {
        s_logger.debug("Error while loading response body", e);
      }
    }

    // The default
    return method.getStatusText();
  }
  public boolean populate(CrawlURI curi, HttpClient http, HttpMethod method, String payload) {
    // http is not used.
    // payload is not used.
    boolean result = false;
    Map formItems = null;
    try {
      formItems = getFormItems(curi);
    } catch (AttributeNotFoundException e1) {
      logger.severe("Failed get of form items for " + curi);
    }
    if (formItems == null || formItems.size() <= 0) {
      try {
        logger.severe("No form items for " + method.getURI());
      } catch (URIException e) {
        logger.severe("No form items and exception getting uri: " + e.getMessage());
      }
      return result;
    }

    NameValuePair[] data = new NameValuePair[formItems.size()];
    int index = 0;
    String key = null;
    for (Iterator i = formItems.keySet().iterator(); i.hasNext(); ) {
      key = (String) i.next();
      data[index++] = new NameValuePair(key, (String) formItems.get(key));
    }
    if (method instanceof PostMethod) {
      ((PostMethod) method).setRequestBody(data);
      result = true;
    } else if (method instanceof GetMethod) {
      // Append these values to the query string.
      // Get current query string, then add data, then get it again
      // only this time its our data only... then append.
      HttpMethodBase hmb = (HttpMethodBase) method;
      String currentQuery = hmb.getQueryString();
      hmb.setQueryString(data);
      String newQuery = hmb.getQueryString();
      hmb.setQueryString(((currentQuery != null) ? currentQuery : "") + "&" + newQuery);
      result = true;
    } else {
      logger.severe("Unknown method type: " + method);
    }
    return result;
  }
  private int executeAndRelease(HttpClient httpClient, HttpMethodBase method) throws IOException {
    int status = 0;
    try {
      status = httpClient.executeMethod(method);
    } finally {
      method.releaseConnection();
    }

    return status;
  }
  private FluentCaseInsensitiveStringsMap computerHeaders() {
    FluentCaseInsensitiveStringsMap h = new FluentCaseInsensitiveStringsMap();

    Header[] uh = method.getResponseHeaders();

    for (Header e : uh) {
      if (e.getName() != null) {
        h.add(e.getName(), e.getValue());
      }
    }

    uh = method.getResponseFooters();
    for (Header e : uh) {
      if (e.getName() != null) {
        h.add(e.getName(), e.getValue());
      }
    }

    return h;
  }
Пример #13
0
  protected String processResponseHeaderValue(
      HttpMethodBase method, String headerName, String expectedValue) {
    Header header = method.getResponseHeader(headerName);
    if (header == null) {
      throwVdsErrorException(
          "response was missing the following header: " + headerName, EngineError.GeneralException);
    }

    if (expectedValue != null && !expectedValue.equals(header.getValue())) {
      throwVdsErrorException(
          "response header value unexpected for header: " + headerName,
          EngineError.GeneralException);
    }

    return header.getValue();
  }
 /**
  * Requests the received method with the received timeout (milliseconds).
  *
  * <p>Executes the method through the inherited HttpClient.executedMethod(method).
  *
  * <p>Sets the socket and connection timeouts only for the method received.
  *
  * <p>The timeouts are both in milliseconds; 0 means 'infinite'; < 0 means 'do not change the
  * default'
  *
  * @param method HTTP method request.
  * @param readTimeout Timeout to set for data reception
  * @param conntionTimout Timeout to set for connection establishment
  */
 public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout)
     throws HttpException, IOException {
   int oldSoTimeout = getParams().getSoTimeout();
   int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
   try {
     if (readTimeout >= 0) {
       method.getParams().setSoTimeout(readTimeout); // this should be enough...
       getParams().setSoTimeout(readTimeout); // ... but HTTPS needs this
     }
     if (connectionTimeout >= 0) {
       getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
     }
     return executeMethod(method);
   } finally {
     getParams().setSoTimeout(oldSoTimeout);
     getHttpConnectionManager().getParams().setConnectionTimeout(oldConnectionTimeout);
   }
 }
 public boolean cancel(boolean mayInterruptIfRunning) {
   if (!cancelled.get() && innerFuture != null) {
     method.abort();
     try {
       asyncHandler.onThrowable(new CancellationException());
     } catch (Throwable t) {
       logger.debug("asyncHandler.onThrowable", t);
     }
     cancelled.set(true);
     if (reaperFuture != null) {
       reaperFuture.cancel(true);
     }
     super.done();
     return innerFuture.cancel(mayInterruptIfRunning);
   } else {
     super.done();
     return false;
   }
 }
  public void abort(Throwable t) {
    if (innerFuture != null) {
      innerFuture.cancel(true);
    }

    if (method != null) {
      method.abort();
    }

    if (reaperFuture != null) {
      reaperFuture.cancel(true);
    }

    exception.set(t);
    if (!timedOut.get() && !cancelled.get()) {
      try {
        asyncHandler.onThrowable(t);
      } catch (Throwable t2) {
        logger.debug("asyncHandler.onThrowable", t2);
      }
    }
    super.done();
  }
Пример #17
0
 public void recycle() {
   super.recycle();
   setFollowRedirects(false);
 }
 protected void applyProxy(HttpMethodBase method, String host) {
   HostConfiguration hc = new HostConfiguration();
   hc.setHost(host);
   hc.setProxy(proxyHost, proxyPort);
   method.setHostConfiguration(hc);
 }
Пример #19
0
 public void abortRequest(SubmitContext submitContext) {
   HttpMethodBase postMethod = (HttpMethodBase) submitContext.getProperty(HTTP_METHOD);
   if (postMethod != null) postMethod.abort();
 }
Пример #20
0
  /**
   * Make a http request and process the response. This method also performs automatic retries.
   *
   * @param method The HTTP method to use (GET, POST, DELETE, etc)
   * @param action the name of the action for this query request
   * @param params map of request params
   * @param respType the class that represents the desired/expected return type
   */
  protected <T> T makeRequest(
      HttpMethodBase method, String action, Map<String, String> params, Class<T> respType)
      throws HttpException, IOException, JAXBException, AWSException {

    // add auth params, and protocol specific headers
    Map<String, String> qParams = new HashMap<String, String>(params);
    qParams.put("Action", action);
    qParams.put("AWSAccessKeyId", getAwsAccessKeyId());
    qParams.put("SignatureVersion", "" + getSignatureVersion());
    qParams.put("Timestamp", httpDate());
    if (getSignatureVersion() == 2) {
      qParams.put("SignatureMethod", getAlgorithm());
    }
    if (headers != null) {
      for (Iterator<String> i = headers.keySet().iterator(); i.hasNext(); ) {
        String key = i.next();
        for (Iterator<String> j = headers.get(key).iterator(); j.hasNext(); ) {
          qParams.put(key, j.next());
        }
      }
    }
    // sort params by key
    ArrayList<String> keys = new ArrayList<String>(qParams.keySet());
    if (getSignatureVersion() == 2) {
      Collections.sort(keys);
    } else {
      Collator stringCollator = Collator.getInstance();
      stringCollator.setStrength(Collator.PRIMARY);
      Collections.sort(keys, stringCollator);
    }

    // build param string
    StringBuilder resource = new StringBuilder();
    if (getSignatureVersion() == 0) { // ensure Action, Timestamp come first!
      resource.append(qParams.get("Action"));
      resource.append(qParams.get("Timestamp"));
    } else if (getSignatureVersion() == 2) {
      resource.append(method.getName());
      resource.append("\n");
      resource.append(getServer().toLowerCase());
      resource.append("\n/");
      String reqURL = makeURL("").toString();
      // see if there is something after the host:port/ in the URL
      if (reqURL.lastIndexOf('/') < (reqURL.length() - 1)) {
        // if so, put that here in the string to sign
        resource.append(reqURL.substring(reqURL.lastIndexOf('/') + 1));
      }
      resource.append("\n");
      boolean first = true;
      for (String key : keys) {
        if (!first) {
          resource.append("&");
        } else {
          first = false;
        }
        resource.append(key);
        resource.append("=");
        resource.append(SignerEncoder.encode(qParams.get(key)));
        //				System.err.println("encoded params "+key+" :"+(urlencode(qParams.get(key))));
      }
    } else {
      for (String key : keys) {
        resource.append(key);
        resource.append(qParams.get(key));
      }
    }
    //		System.err.println("String to sign :"+resource.toString());

    // calculate signature
    String encoded = encode(getSecretAccessKey(), resource.toString(), true);

    // build param string, encoding values and adding request signature
    resource = new StringBuilder();
    for (String key : keys) {
      resource.append("&");
      resource.append(key);
      resource.append("=");
      resource.append(urlencode(qParams.get(key)));
    }
    resource.setCharAt(0, '?'); // set first param delimeter
    resource.append("&Signature=");
    resource.append(encoded);

    // finally, build request object
    URL url = makeURL(resource.toString());
    method.setURI(new URI(url.toString(), true));
    method.setRequestHeader(new Header("User-Agent", userAgent));
    if (getSignatureVersion() == 0) {
      method.setRequestHeader(
          new Header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"));
    }
    Object response = null;
    boolean done = false;
    int retries = 0;
    boolean doRetry = false;
    AWSException error = null;
    do {
      int responseCode = 600; // default to high value, so we don't think it is valid
      try {
        responseCode = getHttpClient().executeMethod(method);
      } catch (SocketException ex) {
        // these can generally be retried. Treat it like a 500 error
        doRetry = true;
        error = new AWSException(ex.getMessage(), ex);
      }
      // 100's are these are handled by httpclient
      if (responseCode < 300) {
        // 200's : parse normal response into requested object
        if (respType != null) {
          InputStream iStr = method.getResponseBodyAsStream();
          response = JAXBuddy.deserializeXMLStream(respType, iStr);
        }
        done = true;
      } else if (responseCode < 400) {
        // 300's : what to do?
        throw new HttpException("redirect error : " + responseCode);
      } else if (responseCode < 500) {
        // 400's : parse client error message
        String body = getStringFromStream(method.getResponseBodyAsStream());
        throw createException(body, "Client error : ");
      } else if (responseCode < 600) {
        // 500's : retry...
        doRetry = true;
        String body = getStringFromStream(method.getResponseBodyAsStream());
        error = createException(body, "");
      }
      if (doRetry) {
        retries++;
        if (retries > maxRetries) {
          throw new HttpException("Number of retries exceeded : " + action, error);
        }
        doRetry = false;
        try {
          Thread.sleep((int) Math.pow(2.0, retries) * 1000);
        } catch (InterruptedException ex) {
        }
      }
    } while (!done);
    return (T) response;
  }
Пример #21
0
  /**
   * @param since last modified time to use
   * @param req
   * @param url if null, ignored
   * @param redirCount number of redirs we've done
   */
  public static HttpData getDataOnce(
      HttpServletRequest req,
      HttpServletResponse res,
      long since,
      String surl,
      int redirCount,
      int timeout)
      throws IOException, HttpException, DataSourceException, MalformedURLException {

    HttpMethodBase request = null;
    HostConfiguration hcfg = new HostConfiguration();

    /*
      [todo hqm 2006-02-01] Anyone know why this code was here? It is setting
      the mime type to something which just confuses the DHTML parser.

      if (res != null) {
        res.setContentType("application/x-www-form-urlencoded;charset=UTF-8");
        }
    */

    try {

      // TODO: [2002-01-09 bloch] cope with cache-control
      // response headers (no-store, no-cache, must-revalidate,
      // proxy-revalidate).

      if (surl == null) {
        surl = getURL(req);
      }
      if (surl == null || surl.equals("")) {
        throw new MalformedURLException(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="url is empty or null"
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-312"));
      }

      String reqType = "";
      String headers = "";

      if (req != null) {
        reqType = req.getParameter("reqtype");
        headers = req.getParameter("headers");
      }

      boolean isPost = false;
      mLogger.debug("reqtype = " + reqType);

      if (reqType != null && reqType.equals("POST")) {
        request = new LZPostMethod();
        request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        isPost = true;
        mLogger.debug("setting POST req method");
      } else if (reqType != null && reqType.equals("PUT")) {
        request = new LZPutMethod();
        // todo [hqm 2007] treat PUT like POST?
        isPost = true;
        mLogger.debug("setting PUT req method");
      } else if (reqType != null && reqType.equals("DELETE")) {
        request = new LZDeleteMethod();
        mLogger.debug("setting DELETE req method");
      } else {
        mLogger.debug("setting GET (default) req method");
        request = new LZGetMethod();
      }

      request.setHttp11(mUseHttp11);

      // Proxy the request headers
      if (req != null) {
        LZHttpUtils.proxyRequestHeaders(req, request);
      }

      // Set headers from query string
      if (headers != null && headers.length() > 0) {
        StringTokenizer st = new StringTokenizer(headers, "\n");
        while (st.hasMoreTokens()) {
          String h = st.nextToken();
          int i = h.indexOf(":");
          if (i > -1) {
            String n = h.substring(0, i);
            String v = h.substring(i + 2, h.length());
            request.setRequestHeader(n, v);
            mLogger.debug(
                /* (non-Javadoc)
                 * @i18n.test
                 * @org-mes="setting header " + p[0] + "=" + p[1]
                 */
                org.openlaszlo.i18n.LaszloMessages.getMessage(
                    HTTPDataSource.class.getName(), "051018-359", new Object[] {n, v}));
          }
        }
      }

      mLogger.debug("Parsing url");
      URI uri = LZHttpUtils.newURI(surl);
      try {
        hcfg.setHost(uri);
      } catch (Exception e) {
        throw new MalformedURLException(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="can't form uri from " + p[0]
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-376", new Object[] {surl}));
      }

      // This gets us the url-encoded (escaped) path and query string
      String path = uri.getEscapedPath();
      String query = uri.getEscapedQuery();
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="encoded path:  " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-389", new Object[] {path}));
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="encoded query: " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-397", new Object[] {query}));

      // This call takes a decoded (unescaped) path
      request.setPath(path);

      boolean hasQuery = (query != null && query.length() > 0);

      String rawcontent = null;
      // Newer rawpost protocol puts lzpostbody as a separate
      // top level query arg in the request.
      rawcontent = req.getParameter("lzpostbody");

      if (isPost) {
        // Older rawpost protocol put the "lzpostbody" arg
        // embedded in the "url" args's query args
        if (rawcontent == null && hasQuery) {
          rawcontent = findQueryArg("lzpostbody", query);
        }
        if (rawcontent != null) {
          // Get the unescaped query string
          ((EntityEnclosingMethod) request).setRequestBody(rawcontent);
        } else if (hasQuery) {
          StringTokenizer st = new StringTokenizer(query, "&");
          while (st.hasMoreTokens()) {
            String it = st.nextToken();
            int i = it.indexOf("=");
            if (i > 0) {
              String n = it.substring(0, i);
              String v = it.substring(i + 1, it.length());
              // POST encodes values during request
              ((PostMethod) request).addParameter(n, URLDecoder.decode(v, "UTF-8"));
            } else {
              mLogger.warn(
                  /* (non-Javadoc)
                   * @i18n.test
                   * @org-mes="ignoring bad token (missing '=' char) in query string: " + p[0]
                   */
                  org.openlaszlo.i18n.LaszloMessages.getMessage(
                      HTTPDataSource.class.getName(), "051018-429", new Object[] {it}));
            }
          }
        }
      } else {
        // This call takes an encoded (escaped) query string
        request.setQueryString(query);
      }

      // Put in the If-Modified-Since headers
      if (since != -1) {
        String lms = LZHttpUtils.getDateString(since);
        request.setRequestHeader(LZHttpUtils.IF_MODIFIED_SINCE, lms);
        mLogger.debug(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="proxying lms: " + p[0]
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-450", new Object[] {lms}));
      }

      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="setting up http client"
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-460"));
      HttpClient htc = null;
      if (mConnectionMgr != null) {
        htc = new HttpClient(mConnectionMgr);
      } else {
        htc = new HttpClient();
      }

      htc.setHostConfiguration(hcfg);

      // This is the data timeout
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="timeout set to " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-478", new Object[] {new Integer(timeout)}));
      htc.setTimeout(timeout);

      // Set connection timeout the same
      htc.setConnectionTimeout(mConnectionTimeout);

      // Set timeout for getting a connection
      htc.setHttpConnectionFactoryTimeout(mConnectionPoolTimeout);

      // TODO: [2003-03-05 bloch] this should be more configurable (per app?)
      if (!isPost) {
        request.setFollowRedirects(mFollowRedirects > 0);
      }

      long t1 = System.currentTimeMillis();
      mLogger.debug("starting remote request");
      int rc = htc.executeMethod(hcfg, request);
      String status = HttpStatus.getStatusText(rc);
      if (status == null) {
        status = "" + rc;
      }
      mLogger.debug(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="remote response status: " + p[0]
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(), "051018-504", new Object[] {status}));

      HttpData data = null;
      if (isRedirect(rc) && mFollowRedirects > redirCount) {
        String loc = request.getResponseHeader("Location").toString();
        String hostURI = loc.substring(loc.indexOf(": ") + 2, loc.length());
        mLogger.info(
            /* (non-Javadoc)
             * @i18n.test
             * @org-mes="Following URL from redirect: " + p[0]
             */
            org.openlaszlo.i18n.LaszloMessages.getMessage(
                HTTPDataSource.class.getName(), "051018-517", new Object[] {hostURI}));
        long t2 = System.currentTimeMillis();
        if (timeout > 0) {
          timeout -= (t2 - t1);
          if (timeout < 0) {
            throw new InterruptedIOException(
                /* (non-Javadoc)
                 * @i18n.test
                 * @org-mes=p[0] + " timed out after redirecting to " + p[1]
                 */
                org.openlaszlo.i18n.LaszloMessages.getMessage(
                    HTTPDataSource.class.getName(), "051018-529", new Object[] {surl, loc}));
          }
        }

        data = getDataOnce(req, res, since, hostURI, redirCount++, timeout);
      } else {
        data = new HttpData(request, rc);
      }

      if (req != null && res != null) {
        // proxy response headers
        LZHttpUtils.proxyResponseHeaders(request, res, req.isSecure());
      }

      return data;

    } catch (ConnectTimeoutException ce) {
      // Transduce to an InterrupedIOException, since lps takes these to be timeouts.
      if (request != null) {
        request.releaseConnection();
      }
      throw new InterruptedIOException(
          /* (non-Javadoc)
           * @i18n.test
           * @org-mes="connecting to " + p[0] + ":" + p[1] + " timed out beyond " + p[2] + " msecs."
           */
          org.openlaszlo.i18n.LaszloMessages.getMessage(
              HTTPDataSource.class.getName(),
              "051018-557",
              new Object[] {
                hcfg.getHost(), new Integer(hcfg.getPort()), new Integer(mConnectionTimeout)
              }));
    } catch (HttpRecoverableException hre) {
      if (request != null) {
        request.releaseConnection();
      }
      throw hre;
    } catch (HttpException e) {
      if (request != null) {
        request.releaseConnection();
      }
      throw e;
    } catch (IOException ie) {
      if (request != null) {
        request.releaseConnection();
      }
      throw ie;
    } catch (RuntimeException e) {
      if (request != null) {
        request.releaseConnection();
      }
      throw e;
    }
  }