/** * Create response parameters. */ public OAuthResponseParams(ISecurityToken securityToken, sRequest originalRequest, BlobCrypter stateCrypter) { this.securityToken = securityToken; this.originalRequest = originalRequest; newClientState = new OAuthClientState(stateCrypter); }
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); }
private sRequest buildHttpRequest(HttpRequestWrapper request) { Uri url = ValidateUrl(request.getParameter(URL_PARAM)); sRequest req = new sRequest(url); req.Container = getContainer(request); if (request.getParameter(GADGET_PARAM) != null) { req.setGadget(Uri.parse(request.getParameter(GADGET_PARAM))); } // Allow the rewriter to use an externally forced mime type. This is needed // allows proper rewriting of <script src="x"/> where x is returned with // a content type like text/html which unfortunately happens all too often req.RewriteMimeType = request.getParameter(REWRITE_MIME_TYPE_PARAM); req.setIgnoreCache(getIgnoreCache(request)); // If the proxy request specifies a refresh param then we want to force the min TTL for // the retrieved entry in the cache regardless of the headers on the content when it // is fetched from the original source. if (request.getParameter(REFRESH_PARAM) != null) { int ttl = 0; int.TryParse(request.getParameter(REFRESH_PARAM), out ttl); req.CacheTtl = ttl; } return(req); }
/* * Start with an HttpRequest. * Throw if there are any attacks in the query. * Throw if there are any attacks in the post body. * Build up OAuth parameter list * Sign it. * Add OAuth parameters to new request * Send it. */ public sRequest sanitizeAndSign(sRequest basereq, List <OAuth.Parameter> parameters) { if (parameters == null) { parameters = new List <OAuth.Parameter>(); } UriBuilder target = new UriBuilder(basereq.getUri()); String query = target.getQuery(); target.setQuery(null); parameters.AddRange(sanitize(OAuth.decodeForm(query))); if (OAuth.isFormEncoded(basereq.ContentType)) { parameters.AddRange(sanitize(OAuth.decodeForm(basereq.getPostBodyAsString()))); } addIdentityParams(parameters); addSignatureParams(parameters); try { OAuthMessage signed = accessorInfo.getAccessor().newRequestMessage( basereq.getMethod(), target.ToString(), parameters); sRequest oauthHttpRequest = createHttpRequest(basereq, selectOAuthParams(signed)); // Following 302s on OAuth responses is unlikely to be productive. oauthHttpRequest.FollowRedirects = false; return(oauthHttpRequest); } catch (Exception e) { throw responseParams.oauthRequestException(OAuthError.UNKNOWN_PROBLEM, "Error signing message", e); } }
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); } }
public static sRequest newHttpRequest(GadgetContext context, RequestAuthenticationInfo authenticationInfo) { sRequest request = new sRequest(authenticationInfo.getHref()) .setSecurityToken(context.getToken()) .setOAuthArguments(new OAuthArguments(authenticationInfo)) .setAuthType(authenticationInfo.getAuthType()) .setContainer(context.getContainer()) .setGadget(Uri.fromJavaUri(context.getUrl())); return(request); }
/** * 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); }
/** * Generate a remote content request based on the parameters * sent from the client. * @throws GadgetException */ private sRequest buildHttpRequest(HttpRequestWrapper request) { Uri url = ValidateUrl(request.getParameter(URL_PARAM)); sRequest req = new sRequest(url) .setMethod(GetParameter(request, METHOD_PARAM, "GET")) .setPostBody(request.getRequest().ContentEncoding.GetBytes(GetParameter(request, POST_DATA_PARAM, ""))) .setContainer(getContainer(request)); String headerData = GetParameter(request, HEADERS_PARAM, ""); if (headerData.Length > 0) { String[] headerList = headerData.Split('&'); foreach (String header in headerList) { String[] parts = header.Split('='); if (parts.Length != 2) { throw new GadgetException(GadgetException.Code.INTERNAL_SERVER_ERROR, "Malformed header specified,"); } req.addHeader(HttpUtility.UrlDecode(parts[0]), HttpUtility.UrlDecode(parts[1])); } } //removeUnsafeHeaders(req); req.setIgnoreCache("1".Equals(request.getParameter(NOCACHE_PARAM))); if (request.getParameter(GADGET_PARAM) != null) { req.Gadget = Uri.parse(request.getParameter(GADGET_PARAM)); } // Allow the rewriter to use an externally forced mime type. This is needed // allows proper rewriting of <script src="x"/> where x is returned with // a content type like text/html which unfortunately happens all too often req.setRewriteMimeType(request.getParameter(REWRITE_MIME_TYPE_PARAM)); // Figure out whether authentication is required AuthType auth = AuthType.Parse(GetParameter(request, AUTHZ_PARAM, null)); req.AuthType = auth; if (auth != AuthType.NONE) { req.setSecurityToken(extractAndValidateToken(request.getContext())); req.setOAuthArguments(new OAuthArguments(auth, request.getRequest())); } return(req); }
/** * Removes unsafe headers from the header set. */ private static void removeUnsafeHeaders(sRequest request) { // Host must be removed. String[] badHeaders = new[] { // No legitimate reason to over ride these. // TODO: We probably need to test variations as well. "Accept", "Accept-Encoding" }; foreach (String bad in badHeaders) { request.removeHeader(bad); } }
private sRequest createHttpRequest(sRequest basereq, List <OAuth.Parameter> oauthParams) { AccessorInfo.OAuthParamLocation?paramLocation = accessorInfo.getParamLocation(); // paramLocation could be overriden by a run-time parameter to fetchRequest sRequest result = new sRequest(basereq); // If someone specifies that OAuth parameters go in the body, but then sends a request for // data using GET, we've got a choice. We can throw some type of error, since a GET request // can't have a body, or we can stick the parameters somewhere else, like, say, the header. // We opt to put them in the header, since that stands some chance of working with some // OAuth service providers. if (paramLocation == AccessorInfo.OAuthParamLocation.POST_BODY && !result.getMethod().Equals("POST")) { paramLocation = AccessorInfo.OAuthParamLocation.AUTH_HEADER; } switch (paramLocation) { case AccessorInfo.OAuthParamLocation.AUTH_HEADER: result.addHeader("Authorization", getAuthorizationHeader(oauthParams)); break; case AccessorInfo.OAuthParamLocation.POST_BODY: if (!OAuth.isFormEncoded(result.ContentType)) { throw responseParams.oauthRequestException(OAuthError.INVALID_REQUEST, "OAuth param location can only be post_body if post body is of " + "type x-www-form-urlencoded"); } String oauthData = OAuth.formEncode(oauthParams); if (result.getPostBodyLength() == 0) { result.setPostBody(Encoding.UTF8.GetBytes(oauthData)); } else { result.setPostBody(Encoding.UTF8.GetBytes(result.getPostBodyAsString() + '&' + oauthData)); } break; case AccessorInfo.OAuthParamLocation.URI_QUERY: result.setUri(Uri.parse(OAuth.addParameters(result.getUri().ToString(), oauthParams))); break; } return(result); }
/** * OAuth authenticated fetch. */ public sResponse fetch(sRequest request) { realRequest = request; clientState = new OAuthClientState( fetcherConfig.getStateCrypter(), request.getOAuthArguments().getOrigClientState()); responseParams = new OAuthResponseParams(request.getSecurityToken(), request, fetcherConfig.getStateCrypter()); try { return(fetchNoThrow()); } catch (Exception e) { // We log here to record the request/response pairs that created the failure. responseParams.logDetailedWarning("OAuth fetch unexpected fatal error", e); throw e; } }
/** * 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); }
private void fetchRequestToken() { OAuthAccessor accessor = accessorInfo.getAccessor(); sRequest request = new sRequest(Uri.parse(accessor.consumer.serviceProvider.requestTokenURL)); request.setMethod(accessorInfo.getHttpMethod().ToString()); if (accessorInfo.getHttpMethod().CompareTo(AccessorInfo.HttpMethod.POST) == 0) { request.setContentType(OAuth.FORM_ENCODED); } sRequest signed = sanitizeAndSign(request, null); OAuthMessage reply = sendOAuthMessage(signed); accessor.requestToken = reply.getParameter(OAuth.OAUTH_TOKEN); accessor.TokenSecret = reply.getParameter(OAuth.OAUTH_TOKEN_SECRET); }
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()); }
/** * 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); }
public ContentRewriterFeature get(sRequest request) { Uri gadgetUri = request.Gadget; GadgetSpec spec; if (gadgetUri != null) { URI gadgetJavaUri = gadgetUri.toJavaUri(); try { spec = specFactory.getGadgetSpec(gadgetJavaUri, false); if (spec != null) { return(get(spec)); } } catch (GadgetException) { return(defaultFeature); } } return(defaultFeature); }
/** * Creates a proxy request by fetching pipelined data and adding it to an existing request. * */ private sRequest createPipelinedProxyRequest(Gadget gadget, sRequest original) { sRequest request = new sRequest(original); request.setIgnoreCache(true); GadgetSpec spec = gadget.getSpec(); GadgetContext context = gadget.getContext(); IPreloads proxyPreloads = preloader.preload(context, spec, PreloaderService.PreloadPhase.PROXY_FETCH); // TODO: Add current url to GadgetContext to support transitive proxying. // POST any preloaded content if ((proxyPreloads != null) && proxyPreloads.getData().Count != 0) { JsonArray array = new JsonArray(); foreach (PreloadedData preload in proxyPreloads.getData()) { Dictionary <String, Object> dataMap = preload.toJson(); foreach (var entry in dataMap) { // TODO: the existing, supported content is JSONObjects that contain the // key already. Discarding the key is odd. array.Put(entry.Value); } } String postContent = array.ToString(); // POST the preloaded content, with a method override of GET // to enable caching request.setMethod("POST") .setPostBody(Encoding.UTF8.GetBytes(postContent)) .setHeader("Content-Type", "text/json;charset=utf-8"); } return(request); }
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); }
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); } }
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)); }
/// <summary> /// from org.apache.shindig.gadgets.http.HttpFetcher /// </summary> /// public abstract sResponse fetch(sRequest request);
/** * Implements section 6.3 of the OAuth spec. * @throws OAuthProtocolException */ private void exchangeRequestToken() { if (accessorInfo.getAccessor().accessToken != null) { // session extension per // http://oauth.googlecode.com/svn/spec/ext/session/1.0/drafts/1/spec.html accessorInfo.getAccessor().requestToken = accessorInfo.getAccessor().accessToken; accessorInfo.getAccessor().accessToken = null; } OAuthAccessor accessor = accessorInfo.getAccessor(); Uri accessTokenUri = Uri.parse(accessor.consumer.serviceProvider.accessTokenURL); sRequest request = new sRequest(accessTokenUri); request.setMethod(accessorInfo.getHttpMethod().ToString()); if (accessorInfo.getHttpMethod() == AccessorInfo.HttpMethod.POST) { request.setContentType(OAuth.FORM_ENCODED); } List <OAuth.Parameter> msgParams = new List <OAuth.Parameter> { new OAuth.Parameter(OAuth.OAUTH_TOKEN, accessor.requestToken) }; if (accessorInfo.getSessionHandle() != null) { msgParams.Add(new OAuth.Parameter(OAUTH_SESSION_HANDLE, accessorInfo.getSessionHandle())); } sRequest signed = sanitizeAndSign(request, msgParams); OAuthMessage reply = sendOAuthMessage(signed); accessor.accessToken = OAuthUtil.getParameter(reply, OAuth.OAUTH_TOKEN); accessor.TokenSecret = OAuthUtil.getParameter(reply, OAuth.OAUTH_TOKEN_SECRET); accessorInfo.setSessionHandle(OAuthUtil.getParameter(reply, OAUTH_SESSION_HANDLE)); accessorInfo.setTokenExpireMillis(ACCESS_TOKEN_EXPIRE_UNKNOWN); if (OAuthUtil.getParameter(reply, OAUTH_EXPIRES_IN) != null) { try { int expireSecs = int.Parse(OAuthUtil.getParameter(reply, OAUTH_EXPIRES_IN)); long expireMillis = DateTime.UtcNow.AddSeconds(expireSecs).Ticks; accessorInfo.setTokenExpireMillis(expireMillis); } catch (FormatException) { // Hrm. Bogus server. We can safely ignore this, we'll just wait for the server to // tell us when the access token has expired. responseParams.logDetailedWarning("server returned bogus expiration"); } } // Clients may want to retrieve extra information returned with the access token. Several // OAuth service providers (e.g. Yahoo, NetFlix) return a user id along with the access // token, and the user id is required to use their APIs. Clients signal that they need this // extra data by sending a fetch request for the access token URL. // // We don't return oauth* parameters from the response, because we know how to handle those // ourselves and some of them (such as oauthToken_secret) aren't supposed to be sent to the // client. // // Note that this data is not stored server-side. Clients need to cache these user-ids or // other data themselves, probably in user prefs, if they expect to need the data in the // future. if (accessTokenUri.Equals(realRequest.getUri())) { accessTokenData = new Dictionary <string, string>(); foreach (var param in OAuthUtil.getParameters(reply)) { if (!param.Key.StartsWith("oauth")) { accessTokenData.Add(param.Key, param.Value); } } } }
public PreloadedData call() { sRequest request = newHttpRequest(context, preload); return(new HttpPreloadData(requestPipeline.execute(request), key)); }
public RewriterResults rewrite(sRequest req, sResponse resp, MutableContent content) { return(RewriterResults.cacheableIndefinitely()); }
public RewriterResults rewrite(sRequest req, sResponse resp, MutableContent content) { return(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)); }