BaseLoader
Represents the base class for all loaders.
using AngleSharp.Dom;
using AngleSharp.Events;
using AngleSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace AngleSharp.Network.Default
{
public abstract class BaseLoader : ILoader
{
private readonly IEnumerable<IRequester> _requesters;
private readonly IConfiguration _configuration;
private readonly Predicate<IRequest> _filter;
private readonly List<IDownload> _downloads;
public BaseLoader(IEnumerable<IRequester> requesters, IConfiguration configuration, Predicate<IRequest> filter)
{
_requesters = requesters;
_configuration = configuration;
_filter = (filter ?? ((Predicate<IRequest>)((IRequest _) => true)));
_downloads = new List<IDownload>();
}
protected virtual void Add(IDownload download)
{
lock (this) {
_downloads.Add(download);
}
}
protected virtual void Remove(IDownload download)
{
lock (this) {
_downloads.Remove(download);
}
}
protected virtual string GetCookie(Url url)
{
return _configuration.GetCookie(url.Origin);
}
protected virtual IDownload DownloadAsync(Request request, INode originator)
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
if (_filter(request)) {
Task<IResponse> task = LoadAsync(request, cancellationTokenSource.Token);
Download download = new Download(task, cancellationTokenSource, request.Address, originator);
Add(download);
task.ContinueWith(delegate {
Remove(download);
});
return download;
}
return new Download(TaskEx.FromResult<IResponse>(null), cancellationTokenSource, request.Address, originator);
}
public IEnumerable<IDownload> GetDownloads()
{
lock (this) {
return _downloads.ToArray();
}
}
protected async Task<IResponse> LoadAsync(Request request, CancellationToken cancel)
{
foreach (IRequester requester in _requesters) {
if (requester.SupportsProtocol(request.Address.Scheme)) {
IEventAggregator events = _configuration.Events;
RequestStartEvent evt = new RequestStartEvent(requester, request);
events?.Publish(evt);
IResponse result = await requester.RequestAsync(request, cancel).ConfigureAwait(false);
evt.FireEnd();
return result;
}
}
return null;
}
}
}