private static IDownload FetchWithoutCors(this IResourceLoader loader, ResourceRequest request, OriginBehavior behavior) { if (behavior == OriginBehavior.Fail) throw new DomException(DomError.Network); return loader.DownloadAsync(request); }
private static CorsRequest RedirectTo(this CorsRequest cors, Url url) { var oldRequest = cors.Request; var newRequest = new ResourceRequest(oldRequest.Source, url) { IsCookieBlocked = oldRequest.IsCookieBlocked, IsSameOriginForced = oldRequest.IsSameOriginForced, Origin = oldRequest.Origin }; return new CorsRequest(newRequest) { Setting = cors.Setting, Behavior = cors.Behavior, Integrity = cors.Integrity }; }
/// <summary> /// Performs a potentially CORS-enabled fetch from the given URI by /// using an asynchronous GET request. For more information see: /// http://www.w3.org/TR/html5/infrastructure.html#potentially-cors-enabled-fetch /// </summary> /// <param name="loader">The resource loader to use.</param> /// <param name="request">The request to issue.</param> /// <param name="setting">The cross origin settings to use.</param> /// <param name="behavior"> /// The default behavior in case it is undefined. /// </param> /// <param name="cancel"> /// The token which can be used to cancel the request. /// </param> /// <returns> /// The task which will eventually return the stream. /// </returns> public static async Task<IResponse> FetchWithCorsAsync(this IResourceLoader loader, ResourceRequest request, CorsSetting setting, OriginBehavior behavior, CancellationToken cancel) { if (loader == null) return null; var url = request.Target; if (request.Origin == url.Origin || url.Scheme == KnownProtocols.Data || url.Href == "about:blank") { while (true) { var data = new ResourceRequest(request.Source, url) { Origin = request.Origin, IsManualRedirectDesired = true }; var result = await loader.LoadAsync(data, cancel).ConfigureAwait(false); if (result.StatusCode == HttpStatusCode.Redirect || result.StatusCode == HttpStatusCode.RedirectKeepVerb || result.StatusCode == HttpStatusCode.RedirectMethod || result.StatusCode == HttpStatusCode.TemporaryRedirect || result.StatusCode == HttpStatusCode.MovedPermanently || result.StatusCode == HttpStatusCode.MultipleChoices) { url = new Url(result.Headers.GetOrDefault(HeaderNames.Location, url.Href)); if (request.Origin == url.Origin) { request = new ResourceRequest(request.Source, url) { IsCookieBlocked = request.IsCookieBlocked, IsSameOriginForced = request.IsSameOriginForced, Origin = request.Origin }; return await loader.FetchWithCorsAsync(request, setting, behavior, cancel).ConfigureAwait(false); } } else { return result; } } } if (setting == CorsSetting.None) { if (behavior == OriginBehavior.Taint) await loader.LoadAsync(request, cancel).ConfigureAwait(false); } if (setting == CorsSetting.Anonymous) request.IsCredentialOmitted = true; if (setting == CorsSetting.Anonymous || setting == CorsSetting.UseCredentials) { var result = await loader.FetchAsync(request, cancel).ConfigureAwait(false); //TODO If CORS cross-origin request is success if (result != null && result.StatusCode == HttpStatusCode.OK) return result; } throw new DomException(DomError.Network); }
/// <summary> /// Performs a fetch from the given URI by using an asynchronous /// request. /// </summary> /// <param name="loader">The resource loader to use.</param> /// <param name="request">The request to issue.</param> /// <param name="cancel"> /// The token which can be used to cancel the request. /// </param> /// <returns> /// The task which will eventually return the stream. /// </returns> public static Task<IResponse> FetchAsync(this IResourceLoader loader, ResourceRequest request, CancellationToken cancel) { if (loader == null) return DefaultResponse; return loader.LoadAsync(request, cancel); }
/// <summary> /// Performs a fetch from the given URI by using an asynchronous /// request. /// </summary> /// <param name="loader">The resource loader to use.</param> /// <param name="request">The request to issue.</param> /// <param name="cancel"> /// The token which can be used to cancel the request. /// </param> /// <returns> /// The task which will eventually return the stream. /// </returns> public static Task<IResponse> FetchAsync(this IResourceLoader loader, ResourceRequest request, CancellationToken cancel) { return loader != null ? loader.LoadAsync(request, cancel) : TaskEx.FromResult(default(IResponse)); }
async Task LoadScriptAsync(IResourceLoader loader, ResourceRequest request) { var setting = CrossOrigin.ToEnum(CorsSetting.None); var behavior = OriginBehavior.Taint; var response = await loader.FetchWithCorsAsync(request, setting, behavior).ConfigureAwait(false); var completion = new TaskCompletionSource<Boolean>(); _runScript = () => { RunFromResponse(response); response.Dispose(); completion.SetResult(true); }; await completion.Task.ConfigureAwait(false); }
/// <summary> /// Performs a potentially CORS-enabled fetch from the given URI by /// using an asynchronous GET request. For more information see: /// http://www.w3.org/TR/html5/infrastructure.html#potentially-cors-enabled-fetch /// </summary> /// <param name="loader">The resource loader to use.</param> /// <param name="request">The request to issue.</param> /// <param name="setting">The cross origin settings to use.</param> /// <param name="behavior"> /// The default behavior in case it is undefined. /// </param> /// <returns> /// The task which will eventually return the stream. /// </returns> public static async Task<IResponse> FetchWithCorsAsync(this IResourceLoader loader, ResourceRequest request, CorsSetting setting, OriginBehavior behavior) { var url = request.Target; if (request.Origin == url.Origin || url.Scheme == ProtocolNames.Data || url.Href == "about:blank") { while (true) { var data = new ResourceRequest(request.Source, url) { Origin = request.Origin, IsManualRedirectDesired = true }; var result = await loader.DownloadAsync(data).Task.ConfigureAwait(false); if (result.IsRedirected()) { url = new Url(result.Headers.GetOrDefault(HeaderNames.Location, url.Href)); if (request.Origin.Is(url.Origin)) { request = new ResourceRequest(request.Source, url) { IsCookieBlocked = request.IsCookieBlocked, IsSameOriginForced = request.IsSameOriginForced, Origin = request.Origin }; return await loader.FetchWithCorsAsync(request, setting, behavior).ConfigureAwait(false); } } else { return result; } } } else if (setting == CorsSetting.None) { if (behavior == OriginBehavior.Fail) { throw new DomException(DomError.Network); } return await loader.DownloadAsync(request).Task.ConfigureAwait(false); } else if (setting == CorsSetting.Anonymous || setting == CorsSetting.UseCredentials) { request.IsCredentialOmitted = setting == CorsSetting.Anonymous; var result = await loader.FetchAsync(request).ConfigureAwait(false); if (result != null && result.StatusCode == HttpStatusCode.OK) { return result; } else if (result != null) { result.Dispose(); } } throw new DomException(DomError.Network); }
/// <summary> /// Performs a fetch from the given URI by using an asynchronous /// request. /// </summary> /// <param name="loader">The resource loader to use.</param> /// <param name="request">The request to issue.</param> /// <returns> /// The task which will eventually return the stream. /// </returns> public static Task<IResponse> FetchAsync(this IResourceLoader loader, ResourceRequest request) { return loader != null ? loader.DownloadAsync(request).Task : TaskEx.FromResult(default(IResponse)); }
/// <summary> /// Creates a new CORS enabled request. /// </summary> /// <param name="request">The original request.</param> public CorsRequest(ResourceRequest request) { Request = request; }