private static IDownload FetchWithoutCorsAsync(this IResourceLoader loader, ResourceRequest request, OriginBehavior behavior) { if (behavior == OriginBehavior.Fail) { throw new DomException(DomError.Network); } return(loader.FetchAsync(request)); }
/// <summary> /// Processes the given request asynchronously. /// </summary> public virtual Task ProcessAsync(ResourceRequest request) { if (IsAvailable && IsDifferentToCurrentDownloadUrl(request.Target)) { CancelDownload(); Download = _loader.FetchAsync(request); return(FinishDownloadAsync()); } return(null); }
private static IDownload FetchFromDifferentOriginAsync(this IResourceLoader loader, CorsRequest cors) { var request = cors.Request; request.IsCredentialOmitted = cors.IsAnonymous(); var download = loader.FetchAsync(request); return(download.Wrap(response => { if (response?.StatusCode != HttpStatusCode.OK) { response?.Dispose(); throw new DomException(DomError.Network); } return cors.CheckIntegrity(download); })); }
private static IDownload FetchFromSameOriginAsync(this IResourceLoader loader, Url url, CorsRequest cors) { var request = cors.Request; var download = loader.FetchAsync(new ResourceRequest(request.Source, url) { Origin = request.Origin, IsManualRedirectDesired = true }); return(download.Wrap(response => { if (response.IsRedirected()) { url.Href = response.Headers.GetOrDefault(HeaderNames.Location, url.Href); return request.Origin.Is(url.Origin) ? loader.FetchWithCorsAsync(cors.RedirectTo(url)) : loader.FetchFromSameOriginAsync(url, cors); } return cors.CheckIntegrity(download); })); }
/// <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); } } } else if (setting == CorsSetting.None) { if (behavior == OriginBehavior.Fail) { throw new DomException(DomError.Network); } return(await loader.LoadAsync(request, cancel).ConfigureAwait(false)); } else if (setting == CorsSetting.Anonymous || setting == CorsSetting.UseCredentials) { request.IsCredentialOmitted = setting == CorsSetting.Anonymous; var result = await loader.FetchAsync(request, cancel).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 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); }