/// <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="cors">The CORS request to issue.</param> /// <returns> /// The active download. /// </returns> public static IDownload FetchWithCors(this IResourceLoader loader, CorsRequest cors) { var request = cors.Request; var setting = cors.Setting; var url = request.Target; if (request.Origin == url.Origin || url.Scheme == ProtocolNames.Data || url.Href == "about:blank") { return loader.FetchFromSameOrigin(url, cors); } else if (setting == CorsSetting.Anonymous || setting == CorsSetting.UseCredentials) { return loader.FetchFromDifferentOrigin(cors); } else if (setting == CorsSetting.None) { return loader.FetchWithoutCors(request, cors.Behavior); } throw new DomException(DomError.Network); }
private static IDownload FetchFromSameOrigin(this IResourceLoader loader, Url url, CorsRequest cors) { var request = cors.Request; var download = loader.DownloadAsync(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.FetchWithCors(cors.RedirectTo(url)) : loader.FetchFromSameOrigin(url, cors); } return cors.CheckIntegrity(download); }); }
private static IDownload FetchFromDifferentOrigin(this IResourceLoader loader, CorsRequest cors) { var request = cors.Request; request.IsCredentialOmitted = cors.IsAnonymous(); var download = loader.DownloadAsync(request); return download.Wrap(response => { if (response?.StatusCode != HttpStatusCode.OK) { response?.Dispose(); throw new DomException(DomError.Network); } return cors.CheckIntegrity(download); }); }