/** {@inheritDoc} */
 public HttpResponse fetch(HttpRequest request) {
   if (!whitelist.allows(request.getUri().toJavaUri())) {
     log.warn(
         "A request to "
             + request.getUri()
             + " has been denied.  To allow requests to this URL add the application URL to your whitelist (http://confluence.atlassian.com/x/KQfCDQ ).");
     return new HttpResponseBuilder()
         .setHttpStatusCode(HttpResponse.SC_FORBIDDEN)
         .setHeader("Content-Type", "text/plain")
         .setResponseString(
             "Requests to "
                 + request.getUri()
                 + " are not allowed.  See your administrator about configuring a whitelist entry for this destination (http://confluence.atlassian.com/x/KQfCDQ ).")
         .create();
   }
   HttpCacheKey cacheKey = new HttpCacheKey(request);
   HttpResponse response = cache.getResponse(cacheKey, request);
   if (response != null) {
     return response;
   }
   try {
     HttpUriRequest hcRequest = newHcRequest(request);
     if (request.getPostBodyLength() > 0) {
       ((HttpEntityEnclosingRequest) hcRequest)
           .setEntity(new InputStreamEntity(request.getPostBody(), request.getPostBodyLength()));
     }
     org.apache.http.HttpResponse hcResponse;
     try {
       // first try with TLS, the most common SSL protocol
       hcResponse = newHttpClient("TLSv1", request).execute(hcRequest);
     } catch (SSLException e) {
       log.debug(
           "SSL Exception establishing connection with TLSv1 protocol. Falling back to SSLv3.", e);
       // if TLS failed, try with SSLv3
       hcResponse = newHttpClient("SSLv3", request).execute(hcRequest);
     }
     response = makeResponse(hcResponse);
     return cache.addResponse(cacheKey, request, response);
   } catch (IOException e) {
     if (e instanceof java.net.SocketTimeoutException || e instanceof java.net.SocketException) {
       return HttpResponse.timeout();
     } else {
       log.error("Unable to retrieve response", e);
     }
     return HttpResponse.error();
   }
 }
예제 #2
0
  public HttpResponse fetch(org.apache.shindig.gadgets.http.HttpRequest request)
      throws GadgetException {
    HttpUriRequest httpMethod = null;
    Preconditions.checkNotNull(request);
    final String methodType = request.getMethod();

    final org.apache.http.HttpResponse response;
    final long started = System.currentTimeMillis();

    // Break the request Uri to its components:
    Uri uri = request.getUri();
    if (StringUtils.isEmpty(uri.getAuthority())) {
      throw new GadgetException(
          GadgetException.Code.INVALID_USER_DATA,
          "Missing domain name for request: " + uri,
          HttpServletResponse.SC_BAD_REQUEST);
    }
    if (StringUtils.isEmpty(uri.getScheme())) {
      throw new GadgetException(
          GadgetException.Code.INVALID_USER_DATA,
          "Missing schema for request: " + uri,
          HttpServletResponse.SC_BAD_REQUEST);
    }
    String[] hostparts = StringUtils.splitPreserveAllTokens(uri.getAuthority(), ':');
    int port = -1; // default port
    if (hostparts.length > 2) {
      throw new GadgetException(
          GadgetException.Code.INVALID_USER_DATA,
          "Bad host name in request: " + uri.getAuthority(),
          HttpServletResponse.SC_BAD_REQUEST);
    }
    if (hostparts.length == 2) {
      try {
        port = Integer.parseInt(hostparts[1]);
      } catch (NumberFormatException e) {
        throw new GadgetException(
            GadgetException.Code.INVALID_USER_DATA,
            "Bad port number in request: " + uri.getAuthority(),
            HttpServletResponse.SC_BAD_REQUEST);
      }
    }

    String requestUri = uri.getPath();
    // Treat path as / if set as null.
    if (uri.getPath() == null) {
      requestUri = "/";
    }
    if (uri.getQuery() != null) {
      requestUri += '?' + uri.getQuery();
    }

    // Get the http host to connect to.
    HttpHost host = new HttpHost(hostparts[0], port, uri.getScheme());

    try {
      if ("POST".equals(methodType) || "PUT".equals(methodType)) {
        HttpEntityEnclosingRequestBase enclosingMethod =
            ("POST".equals(methodType)) ? new HttpPost(requestUri) : new HttpPut(requestUri);

        if (request.getPostBodyLength() > 0) {
          enclosingMethod.setEntity(
              new InputStreamEntity(request.getPostBody(), request.getPostBodyLength()));
        }
        httpMethod = enclosingMethod;
      } else if ("GET".equals(methodType)) {
        httpMethod = new HttpGet(requestUri);
      } else if ("HEAD".equals(methodType)) {
        httpMethod = new HttpHead(requestUri);
      } else if ("DELETE".equals(methodType)) {
        httpMethod = new HttpDelete(requestUri);
      }
      for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
        httpMethod.addHeader(entry.getKey(), StringUtils.join(entry.getValue(), ','));
      }

      // Disable following redirects.
      if (!request.getFollowRedirects()) {
        httpMethod.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
      }

      // HttpClient doesn't handle all cases when breaking url (specifically '_' in domain)
      // So lets pass it the url parsed:
      response = FETCHER.execute(host, httpMethod);

      if (response == null) {
        throw new IOException("Unknown problem with request");
      }

      long now = System.currentTimeMillis();
      if (now - started > slowResponseWarning) {
        slowResponseWarning(request, started, now);
      }

      return makeResponse(response);

    } catch (Exception e) {
      long now = System.currentTimeMillis();

      // Find timeout exceptions, respond accordingly
      if (TIMEOUT_EXCEPTIONS.contains(e.getClass())) {
        LOG.info(
            "Timeout for "
                + request.getUri()
                + " Exception: "
                + e.getClass().getName()
                + " - "
                + e.getMessage()
                + " - "
                + (now - started)
                + "ms");
        return HttpResponse.timeout();
      }

      LOG.log(
          Level.INFO,
          "Got Exception fetching " + request.getUri() + " - " + (now - started) + "ms",
          e);

      // Separate shindig error from external error
      throw new GadgetException(
          GadgetException.Code.INTERNAL_SERVER_ERROR,
          e,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    } finally {
      // cleanup any outstanding resources..
      if (httpMethod != null)
        try {
          httpMethod.abort();
        } catch (UnsupportedOperationException e) {
          // ignore
        }
    }
  }