RequesterExtensions
Useful extensions for IRequester objects.
using AngleSharp.Dom;
using AngleSharp.Events;
using AngleSharp.Network;
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
{
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);
IResponse result = await requester.RequestAsync(request, cancel).ConfigureAwait(false);
evt.FireEnd();
return result;
}
}
return null;
}
public static Task<IResponse> SendAsync(this IDocumentLoader loader, DocumentRequest request, CancellationToken cancel)
{
if (loader == null)
return TaskEx.FromResult<IResponse>(null);
return loader.LoadAsync(request, cancel);
}
public static Task<IResponse> FetchAsync(this IResourceLoader loader, ResourceRequest request, CancellationToken cancel)
{
if (loader == null)
return TaskEx.FromResult<IResponse>(null);
return loader.LoadAsync(request, cancel);
}
public static async Task<IResponse> FetchWithCorsAsync(this IResourceLoader loader, ResourceRequest request, CorsSetting setting, OriginBehavior behavior, CancellationToken cancel)
{
if (loader == null)
return null;
Url url = request.Target;
if (request.Origin == url.Origin || url.Scheme == KnownProtocols.Data || url.Href == "about:blank") {
IResponse result;
while (true) {
ResourceRequest data = new ResourceRequest(request.Source, url) {
Origin = request.Origin,
IsManualRedirectDesired = true
};
result = await loader.LoadAsync(data, cancel).ConfigureAwait(false);
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
};
return await loader.FetchWithCorsAsync(request, setting, behavior, cancel).ConfigureAwait(false);
}
}
return result;
}
switch (setting) {
case CorsSetting.None:
if (behavior == OriginBehavior.Fail)
throw new DomException(DomError.Network);
return await loader.LoadAsync(request, cancel).ConfigureAwait(false);
case CorsSetting.Anonymous:
case CorsSetting.UseCredentials: {
request.IsCredentialOmitted = (setting == CorsSetting.Anonymous);
IResponse result2 = await loader.FetchAsync(request, cancel).ConfigureAwait(false);
if (result2 != null && result2.StatusCode == HttpStatusCode.OK)
return result2;
result2?.Dispose();
break;
}
}
throw new DomException(DomError.Network);
}
public static MimeType GetContentType(this IResponse response)
{
string path = response.Address.Path;
int num = path.LastIndexOf('.');
if (num >= 0)
path.Substring(num);
string defaultType = MimeTypes.FromExtension(MimeTypes.Binary);
return response.GetContentType(defaultType);
}
public static MimeType GetContentType(this IResponse response, string defaultType)
{
return new MimeType(response.Headers.GetOrDefault(HeaderNames.ContentType, defaultType));
}
}
}