/** {@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(); } }
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 } } }
// Loosely based off net.oauth.OAuthServlet, and even more loosely related // to the OAuth specification private MessageInfo parseMessage(HttpRequest request) { MessageInfo info = new MessageInfo(); info.request = request; String method = request.getMethod(); ParsedUrl parsed = new ParsedUrl(request.getUri().toString()); List<OAuth.Parameter> params = Lists.newArrayList(); params.addAll(parsed.getParsedQuery()); if (!validParamLocations.contains(OAuthParamLocation.URI_QUERY)) { // Make sure nothing OAuth related ended up in the query string for (OAuth.Parameter p : params) { if (p.getKey().contains("oauth_")) { throw new RuntimeException("Found unexpected query param " + p.getKey()); } } } // Parse authorization header if (validParamLocations.contains(OAuthParamLocation.AUTH_HEADER)) { String aznHeader = request.getHeader("Authorization"); if (aznHeader != null) { info.aznHeader = aznHeader; for (OAuth.Parameter p : OAuthMessage.decodeAuthorization(aznHeader)) { if (!p.getKey().equalsIgnoreCase("realm")) { params.add(p); } } } } // Parse body info.body = request.getPostBodyAsString(); try { info.rawBody = IOUtils.toByteArray(request.getPostBody()); } catch (IOException e) { throw new RuntimeException("Can't read post body bytes", e); } if (OAuth.isFormEncoded(request.getHeader("Content-Type"))) { params.addAll(OAuth.decodeForm(request.getPostBodyAsString())); // If we're not configured to pass oauth parameters in the post body, double check // that they didn't end up there. if (!validParamLocations.contains(OAuthParamLocation.POST_BODY)) { if (info.body.contains("oauth_")) { throw new RuntimeException("Found unexpected post body data" + info.body); } } } // Return the lot info.message = new OAuthMessage(method, parsed.getLocation(), params); // Check for trusted parameters if (checkTrustedParams) { if (!"foo".equals(OAuthUtil.getParameter(info.message, "oauth_magic"))) { throw new RuntimeException("no oauth_trusted=foo parameter"); } if (!"bar".equals(OAuthUtil.getParameter(info.message, "opensocial_magic"))) { throw new RuntimeException("no opensocial_trusted=foo parameter"); } if (!"quux".equals(OAuthUtil.getParameter(info.message, "xoauth_magic"))) { throw new RuntimeException("no xoauth_magic=quux parameter"); } trustedParamCount += 3; } return info; }