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;
}
}
}