public virtual RewriterResults rewrite(sRequest request, sResponse original, MutableContent content) { ByteArrayOutputStream baos = new ByteArrayOutputStream((content.getContent().Length * 110) / 100); OutputStreamWriter output = new OutputStreamWriter(baos); String mimeType = original.getHeader("Content-Type"); if (request.RewriteMimeType != null) { mimeType = request.RewriteMimeType; } GadgetSpec spec = null; if (request.Gadget != null) { spec = _specFactory.getGadgetSpec(request.Gadget.toJavaUri(), false); } if (rewrite(spec, request.getUri(), content, mimeType, output)) { content.setContent(Encoding.Default.GetString(baos.toByteArray())); return(RewriterResults.cacheableIndefinitely()); } return(null); }
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); }
private static void addHeaders(JsonObject headers, sResponse response, String headerName) { string[] values = response.getHeaders(headerName); if (values != null) { headers.Put(headerName.ToLower(), new JsonArray(values)); } }
/** * Notification that the content of the document has changed. Causes the content * string to be cleared */ public void documentChanged() { if (document != null) { content = null; contentSource = null; } }
/** * Sets the object's content as a raw String. Note, this operation * may clears the document if the content has changed * @param newContent New content. */ public void setContent(String newContent) { // TODO - Equality check may be unnecessary overhead if (content == null || !content.Equals(newContent)) { content = newContent; document = null; contentSource = null; } }
/** * 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); } }
/** * 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); }
/** * Parse OAuth WWW-Authenticate header and either add them to an existing * message or create a new message. * * @param msg * @param resp * @return the updated message. */ private static OAuthMessage parseAuthHeader(OAuthMessage msg, sResponse resp) { if (msg == null) { msg = new OAuthMessage(null, null, null); } foreach (String auth in resp.getHeaders("WWW-Authenticate")) { msg.addParameters(OAuthMessage.decodeAuthorization(auth)); } return(msg); }
/** * 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()); } }
public HttpPreloadData(sResponse response, String key) { JsonObject _data; try { _data = FetchResponseUtils.getResponseAsJson(response, response.responseString); } catch (JsonException) { _data = new JsonObject(); } this.data = _data; this.key = key; }
/** * Retrieves the current content for this object in String form. * If content has been retrieved in parse tree form and has * been edited, the String form is computed from the parse tree by * rendering it. It is <b>strongly</b> encouraged to avoid switching * between retrieval of parse tree (through {@code getParseTree}), * with subsequent edits and retrieval of String contents to avoid * repeated serialization and deserialization. * @return Renderable/active content. */ public String getContent() { if (content == null) { if (contentSource != null) { content = contentSource.responseString; // Clear on first use contentSource = null; } else if (document != null) { content = HtmlSerializer.serialize(document); } } return(content); }
/** * Retrieves the current content for this object in String form. * If content has been retrieved in parse tree form and has * been edited, the String form is computed from the parse tree by * rendering it. It is <b>strongly</b> encouraged to avoid switching * between retrieval of parse tree (through {@code getParseTree}), * with subsequent edits and retrieval of String contents to avoid * repeated serialization and deserialization. * @return Renderable/active content. */ public String getContent() { if (content == null) { if (contentSource != null) { content = contentSource.responseString; // Clear on first use contentSource = null; } else if (document != null) { content = HtmlSerializer.serialize(document); } } return content; }
/** * Get honest-to-goodness user data. * * @throws OAuthProtocolException if the service provider returns an OAuth * related error instead of user data. */ private HttpResponseBuilder fetchData() { HttpResponseBuilder builder; if (accessTokenData != null) { // This is a request for access token data, return it. builder = formatAccessTokenData(); } else { sRequest signed = sanitizeAndSign(realRequest, null); sResponse response = fetchFromServer(signed); checkForProtocolProblem(response); builder = new HttpResponseBuilder(response); } return(builder); }
/** * 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); }
public sResponse rewriteHttpResponse(sRequest req, sResponse resp) { String originalContent = resp.responseString; MutableContent mc = GetMutableContent(originalContent); foreach (IContentRewriter rewriter in rewriters) { rewriter.rewrite(req, resp, mc); } String rewrittenContent = mc.getContent(); if (rewrittenContent.Equals(originalContent)) { return(resp); } return(new HttpResponseBuilder(resp).setResponseString(rewrittenContent).create()); }
/** * 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); }
/** * Sends OAuth request token and access token messages. * @throws GadgetException * @throws IOException * @throws OAuthProtocolException */ private OAuthMessage sendOAuthMessage(sRequest request) { sResponse response = fetchFromServer(request); checkForProtocolProblem(response); OAuthMessage reply = new OAuthMessage(null, null, null); reply.addParameters(OAuth.decodeForm(response.responseString)); reply = parseAuthHeader(reply, response); if (OAuthUtil.getParameter(reply, OAuth.OAUTH_TOKEN) == null) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "No oauthToken returned from service provider"); } if (OAuthUtil.getParameter(reply, OAuth.OAUTH_TOKEN_SECRET) == null) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "No oauthToken_secret returned from service provider"); } return(reply); }
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); }
private sResponse fetchFromServer(sRequest request) { sResponse response = null; try { response = fetcher.fetch(request); if (response == null) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "No response from server"); } return(response); } catch (GadgetException e) { throw responseParams.oauthRequestException( OAuthError.UNKNOWN_PROBLEM, "No response from server", e); } finally { responseParams.addRequestTrace(request, response); } }
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); }
public override void Fetch(HttpRequestWrapper request, HttpResponseWrapper response) { sRequest rcr = buildHttpRequest(request); // Serialize the response sResponse results = requestPipeline.execute(rcr); // Rewrite the response if (contentRewriterRegistry != null) { results = contentRewriterRegistry.rewriteHttpResponse(rcr, results); } // Serialize the response String output = convertResponseToJson(rcr.getSecurityToken(), request, results); // Find and set the refresh interval SetResponseHeaders(request, response.getResponse(), results); response.setStatus((int)HttpStatusCode.OK); response.setContentType("application/json"); response.getResponse().ContentEncoding = Encoding.UTF8; response.Write(Encoding.UTF8.GetBytes(UNPARSEABLE_CRUFT + output)); }
protected static void SetResponseHeaders(HttpRequestWrapper request, HttpResponse response, sResponse results) { int refreshInterval; if (results.isStrictNoCache()) { refreshInterval = 0; } else if (request.getParameter(REFRESH_PARAM) != null) { int.TryParse(request.getParameter(REFRESH_PARAM), out refreshInterval); } else { refreshInterval = Math.Max(60 * 60, (int)(results.getCacheTtl() / 1000L)); } HttpUtil.SetCachingHeaders(response, refreshInterval); // We're skipping the content disposition header for flash due to an issue with Flash player 10 // This does make some sites a higher value phishing target, but this can be mitigated by // additional referer checks. if (!results.getHeader("Content-Type").ToLower().Equals("application/x-shockwave-flash")) { response.AddHeader("Content-Disposition", "attachment;filename=p.txt"); } }
/** * Sets the object's content as a raw String. Note, this operation * may clears the document if the content has changed * @param newContent New content. */ public void setContent(String newContent) { // TODO - Equality check may be unnecessary overhead if (content == null || !content.Equals(newContent)) { content = newContent; document = null; contentSource = null; } }
/** * Add a request/response pair to our trace of actions associated with this request. */ public void addRequestTrace(sRequest request, sResponse response) { requestTrace.Add(new Pair(request, response)); }
public RewriterResults rewrite(sRequest req, sResponse resp, MutableContent content) { return(RewriterResults.cacheableIndefinitely()); }
/** * Construct with HttpResponse so we can defer string decoding until we actually need * the content. Given that we dont rewrite many mime types this is a performance advantage */ public MutableContent(GadgetHtmlParser contentParser, sResponse contentSource) { this.contentParser = contentParser; this.contentSource = contentSource; }
public RewriterResults rewrite(sRequest req, sResponse resp, MutableContent content) { return(null); }
/** * Format a response as JSON, including additional JSON inserted by * chained content fetchers. */ private String convertResponseToJson(ISecurityToken authToken, HttpRequestWrapper request, sResponse results) { try { String originalUrl = request.getParameter(URL_PARAM); String body = results.responseString; if ("FEED".Equals(request.getParameter(CONTENT_TYPE_PARAM))) { body = processFeed(originalUrl, request, body); } JsonObject resp = FetchResponseUtils.getResponseAsJson(results, body); if (authToken != null) { String updatedAuthToken = authToken.getUpdatedToken(); if (updatedAuthToken != null) { resp.Put("st", updatedAuthToken); } } // Use raw param as key as URL may have to be decoded return(new JsonObject().Put(originalUrl, resp).ToString()); } catch (JsonException) { return(""); } }
/** * Construct with HttpResponse so we can defer string decoding until we actually need * the content. Given that we dont rewrite many mime types this is a performance advantage */ public MutableContent(GadgetHtmlParser contentParser, sResponse contentSource) { this.contentParser = contentParser; this.contentSource = contentSource; }
/** * Notification that the content of the document has changed. Causes the content * string to be cleared */ public void documentChanged() { if (document != null) { content = null; contentSource = null; } }