public override void Fetch(HttpRequestWrapper request, HttpResponseWrapper response) { if (request.getHeaders("If-Modified-Since") != null) { if (!request.isConcat) { response.setStatus((int)HttpStatusCode.NotModified); } return; } String host = request.getHeaders("Host"); if (!lockedDomainService.isSafeForOpenProxy(host)) { // Force embedded images and the like to their own domain to avoid XSS // in gadget domains. return; } sRequest rcr = buildHttpRequest(request); sResponse results = fetcher.fetch(rcr); if (contentRewriterRegistry != null) { results = contentRewriterRegistry.rewriteHttpResponse(rcr, results); } if (!request.isConcat) { SetResponseHeaders(request, response.getResponse(), results); for (int i = 0; i < results.getHeaders().Count; i++) { String name = results.getHeaders().GetKey(i); if (!DISALLOWED_RESPONSE_HEADERS.Contains(name.ToLower())) { foreach (String value in results.getHeaders().GetValues(i)) { response.AddHeader(name, value); } } } } if (request.getParameter("rewriteMime") != null) { response.setContentType(request.getParameter("rewriteMime")); } if (results.getHttpStatusCode() != (int)HttpStatusCode.OK) { response.setStatus((int)results.getHttpStatusCode()); } else { response.setStatus((int)HttpStatusCode.OK); } response.Write(results.responseBytes); }
/** * Render the gadget into a string by performing the following steps: * * - Retrieve gadget specification information (GadgetSpec, MessageBundle, etc.) * * - Fetch any preloaded data needed to handle the request, as handled by Preloader. * * - Perform rewriting operations on the output content, handled by Rewriter. * * @param gadget The gadget for the rendering operation. * @return The rendered gadget content * @throws RenderingException if any issues arise that prevent rendering. */ public String render(Gadget gadget) { try { View view = gadget.getCurrentView(); GadgetContext context = gadget.getContext(); GadgetSpec spec = gadget.getSpec(); IPreloads preloads = preloader.preload(context, spec, PreloaderService.PreloadPhase.HTML_RENDER); gadget.setPreloads(preloads); String content; if (view.getHref() == null) { content = view.getContent(); } else { // TODO: Add current url to GadgetContext to support transitive proxying. UriBuilder uri = new UriBuilder(view.getHref()); uri.addQueryParameter("lang", context.getLocale().getLanguage()); uri.addQueryParameter("country", context.getLocale().getCountry()); sRequest request = new sRequest(uri.toUri()) .setIgnoreCache(context.getIgnoreCache()) .setOAuthArguments(new OAuthArguments(view)) .setAuthType(view.getAuthType()) .setSecurityToken(context.getToken()) .setContainer(context.getContainer()) .setGadget(spec.getUrl()); sResponse response = DefaultHttpCache.Instance.getResponse(request); if (response == null || response.isStale()) { sRequest proxyRequest = createPipelinedProxyRequest(gadget, request); response = requestPipeline.execute(proxyRequest); DefaultHttpCache.Instance.addResponse(request, response); } if (response.isError()) { throw new RenderingException("Unable to reach remote host. HTTP status " + response.getHttpStatusCode()); } content = response.responseString; } return(rewriter.rewriteGadget(gadget, content)); } catch (GadgetException e) { throw new RenderingException(e.Message, e); } }
/** * Check if a response might be due to an OAuth protocol error. We don't want to intercept * errors for signed fetch, we only care about places where we are dealing with OAuth request * and/or access tokens. */ private bool isFullOAuthError(sResponse response) { // 400, 401 and 403 are likely to be authentication errors. if (response.getHttpStatusCode() != 400 && response.getHttpStatusCode() != 401 && response.getHttpStatusCode() != 403) { return(false); } // If the client forced us to use full OAuth, this might be OAuth related. if (realRequest.getOAuthArguments().mustUseToken()) { return(true); } // If we're using an access token, this might be OAuth related. if (accessorInfo.getAccessor().accessToken != null) { return(true); } // Not OAuth related. return(false); }
/** * Retrieves js content from the given url. * * @param url * @param fetcher * @return The contents of the JS file, or null if it can't be fetched. * @throws GadgetException */ private static String LoadDataFromUrl(String url, IHttpFetcher fetcher) { // set up the request and response objects Uri uri = Uri.parse(url); sRequest request = new sRequest(uri); sResponse response = fetcher.fetch(request); if (response.getHttpStatusCode() == (int)HttpStatusCode.OK) { return(response.responseString); } return(null); }
protected MessageBundle fetchBundle(LocaleSpec locale, bool ignoreCache) { Uri url = locale.getMessages(); sRequest request = new sRequest(url).setIgnoreCache(ignoreCache); // Since we don't allow any variance in cache time, we should just force the cache time // globally. This ensures propagation to shared caches when this is set. request.setCacheTtl((int)(refresh / 1000)); sResponse response = fetcher.fetch(request); if (response.getHttpStatusCode() != (int)HttpStatusCode.OK) { throw new GadgetException(GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT, "Unable to retrieve message bundle xml. HTTP error " + response.getHttpStatusCode()); } MessageBundle bundle = new MessageBundle(locale, response.responseString); return(bundle); }
/** * Look for an OAuth protocol problem. For cases where no access token is in play * @param response * @throws OAuthProtocolException * @throws IOException */ private void checkForProtocolProblem(sResponse response) { if (isFullOAuthError(response)) { OAuthMessage message = parseAuthHeader(null, response); if (message.getParameter(OAuthProblemException.OAUTH_PROBLEM) != null) { // SP reported extended error information throw new OAuthProtocolException(message); } // No extended information, guess based on HTTP response code. throw new OAuthProtocolException(response.getHttpStatusCode()); } }
private GadgetSpec FetchObjectAndCache(Uri url, bool ignoreCache) { sRequest request = new sRequest(url) .setIgnoreCache(ignoreCache) .setGadget(url); // Since we don't allow any variance in cache time, we should just force the cache time // globally. This ensures propagation to shared caches when this is set. request.setCacheTtl((int)(refresh / 1000)); sResponse response = fetcher.fetch(request); if (response.getHttpStatusCode() != (int)HttpStatusCode.OK) { throw new GadgetException(GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT, "Unable to retrieve gadget xml. HTTP error " + response.getHttpStatusCode()); } GadgetSpec spec = new GadgetSpec(url, response.responseString); HttpRuntime.Cache.Insert(url.ToString(), spec, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(refresh)); return(spec); }
/** * Convert a response to a JSON object. static so it can be used by HttpPreloaders as well. * * The returned JSON object contains the following values: * rc: integer response code * body: string response body * headers: object, keys are header names, values are lists of header values * * @param response the response body * @param body string to use as the body of the response. * @return a JSONObject representation of the response body. */ public static JsonObject getResponseAsJson(sResponse response, String body) { JsonObject resp = new JsonObject(); resp.Put("rc", response.getHttpStatusCode()); resp.Put("body", body); JsonObject headers = new JsonObject(); addHeaders(headers, response, "set-cookie"); addHeaders(headers, response, "location"); resp.Put("headers", headers); // Merge in additional response data foreach (var entry in response.getMetadata()) { resp.Put(entry.Key, entry.Value); } return(resp); }