AngleSharp by Florian Rappl

<PackageReference Include="AngleSharp" Version="0.8.2" />

 RequesterExtensions

static class RequesterExtensions
Useful extensions for IRequester objects.
using AngleSharp.Dom; using AngleSharp.Events; using AngleSharp.Network; using Microsoft.Runtime.CompilerServices; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.Extensions { [DebuggerStepThrough] internal static class RequesterExtensions { private static readonly Task<IResponse> DefaultResponse = CreateDefaultResponse(); public static async Task<IResponse> LoadAsync(this IEnumerable<IRequester> requesters, IRequest request, IEventAggregator events, CancellationToken cancel) { foreach (IRequester requester in requesters) { if (requester.SupportsProtocol(request.Address.Scheme)) { RequestStartEvent evt = new RequestStartEvent(requester, request); events?.Publish(evt); ConfiguredTaskAwaiter val = AwaitExtensions.ConfigureAwait<IResponse>(requester.RequestAsync(request, cancel), false).GetAwaiter(); if (!val.get_IsCompleted()) { await val; ConfiguredTaskAwaiter val2 = default(ConfiguredTaskAwaiter); val = val2; } !0 result = val.GetResult(); val = default(ConfiguredTaskAwaiter); IResponse result2 = (IResponse)result; evt.SetResult(result2); return result2; } } return null; } public static Task<IResponse> SendAsync(this IDocumentLoader loader, DocumentRequest request, CancellationToken cancel) { if (loader == null) return DefaultResponse; return loader.LoadAsync(request, cancel); } public static Task<IResponse> FetchAsync(this IResourceLoader loader, ResourceRequest request, CancellationToken cancel) { if (loader == null) return DefaultResponse; return loader.LoadAsync(request, cancel); } public static async Task<IResponse> FetchWithCorsAsync(this IResourceLoader loader, ResourceRequest request, CorsSetting setting, OriginBehavior behavior, CancellationToken cancel) { Url url = request.Target; ConfiguredTaskAwaitable<IResponse> val; ConfiguredTaskAwaiter val2; ConfiguredTaskAwaiter val3 = default(ConfiguredTaskAwaiter); if (request.Origin == url.Origin || url.Scheme == KnownProtocols.Data || url.Href == "about:blank") { IResponse result; while (true) { ResourceRequest request2 = new ResourceRequest(request.Source, url) { Origin = request.Origin, IsManualRedirectDesired = true }; val = AwaitExtensions.ConfigureAwait<IResponse>(loader.LoadAsync(request2, cancel), false); val2 = val.GetAwaiter(); if (!val2.get_IsCompleted()) { await val2; val2 = val3; val3 = default(ConfiguredTaskAwaiter); } !0 result2 = val2.GetResult(); val2 = default(ConfiguredTaskAwaiter); IResponse response = (IResponse)result2; result = response; if (result.StatusCode != HttpStatusCode.Found && result.StatusCode != HttpStatusCode.TemporaryRedirect && result.StatusCode != HttpStatusCode.SeeOther && result.StatusCode != HttpStatusCode.TemporaryRedirect && result.StatusCode != HttpStatusCode.MovedPermanently && result.StatusCode != HttpStatusCode.MultipleChoices) break; 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 }; val = AwaitExtensions.ConfigureAwait<IResponse>(loader.FetchWithCorsAsync(request, setting, behavior, cancel), false); val2 = val.GetAwaiter(); if (!val2.get_IsCompleted()) { await val2; val2 = val3; } !0 result3 = val2.GetResult(); val2 = default(ConfiguredTaskAwaiter); return (IResponse)result3; } } return result; } if (setting == CorsSetting.None && behavior == OriginBehavior.Taint) { val = AwaitExtensions.ConfigureAwait<IResponse>(loader.LoadAsync(request, cancel), false); val2 = val.GetAwaiter(); if (!val2.get_IsCompleted()) { await val2; val2 = val3; val3 = default(ConfiguredTaskAwaiter); } val2.GetResult(); val2 = default(ConfiguredTaskAwaiter); } if (setting == CorsSetting.Anonymous) request.IsCredentialOmitted = true; if (setting == CorsSetting.Anonymous || setting == CorsSetting.UseCredentials) { val = AwaitExtensions.ConfigureAwait<IResponse>(loader.FetchAsync(request, cancel), false); val2 = val.GetAwaiter(); if (!val2.get_IsCompleted()) { await val2; val2 = val3; } !0 result4 = val2.GetResult(); val2 = default(ConfiguredTaskAwaiter); if (((IResponse)result4).StatusCode == HttpStatusCode.OK) return (IResponse)result4; } throw new DomException(DomError.Network); } private static Task<IResponse> CreateDefaultResponse() { TaskCompletionSource<IResponse> taskCompletionSource = new TaskCompletionSource<IResponse>(); taskCompletionSource.SetResult(null); return taskCompletionSource.Task; } } }