AngleSharp by AngleSharp

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

 HttpRequester

public sealed class HttpRequester : IRequester
The default (ready-to-use) HTTP requester.
using AngleSharp.Extensions; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Threading; using System.Threading.Tasks; namespace AngleSharp.Network.Default { public sealed class HttpRequester : IRequester { private sealed class RequestState { private readonly CookieContainer _cookies; private readonly HttpWebRequest _http; private readonly IRequest _request; private readonly byte[] _buffer; public RequestState(IRequest request, IDictionary<string, string> headers) { string orDefault = request.Headers.GetOrDefault(HeaderNames.Cookie, string.Empty); _cookies = new CookieContainer(); _request = request; _http = (WebRequest.Create(request.Address) as HttpWebRequest); _http.CookieContainer = _cookies; _http.Method = request.Method.ToString().ToUpperInvariant(); _buffer = new byte[4096]; foreach (KeyValuePair<string, string> header in headers) { AddHeader(header.Key, header.Value); } foreach (KeyValuePair<string, string> header2 in request.Headers) { AddHeader(header2.Key, header2.Value); } _cookies.SetCookies(_http.RequestUri, orDefault); } public async Task<IResponse> RequestAsync(CancellationToken cancellationToken) { HttpWebRequest http = _http; cancellationToken.Register(((WebRequest)http).Abort); if (_request.Method == HttpMethod.Post || _request.Method == HttpMethod.Put) { TaskFactory factory = Task.Factory; HttpWebRequest http2 = _http; Func<AsyncCallback, object, IAsyncResult> beginMethod = ((WebRequest)http2).BeginGetRequestStream; HttpWebRequest http3 = _http; SendRequest(await factory.FromAsync(beginMethod, (Func<IAsyncResult, Stream>)((WebRequest)http3).EndGetRequestStream, (object)null).ConfigureAwait(false)); } WebResponse response; try { TaskFactory factory2 = Task.Factory; HttpWebRequest http4 = _http; Func<AsyncCallback, object, IAsyncResult> beginMethod2 = ((WebRequest)http4).BeginGetResponse; HttpWebRequest http5 = _http; response = await factory2.FromAsync(beginMethod2, (Func<IAsyncResult, WebResponse>)((WebRequest)http5).EndGetResponse, (object)null).ConfigureAwait(false); } catch (WebException ex) { response = ex.Response; } return GetResponse(response as HttpWebResponse); } private void SendRequest(Stream target) { Stream content = _request.Content; while (content != null) { int num = content.Read(_buffer, 0, 4096); if (num == 0) break; target.Write(_buffer, 0, num); } } private Response GetResponse(HttpWebResponse response) { if (response != null) { Response response2 = new Response(); string cookieHeader = _cookies.GetCookieHeader(response.ResponseUri); var enumerable = from m in response.Headers.AllKeys select new { Key = m, Value = response.Headers.get_Item(m) }; response2.Content = response.GetResponseStream(); response2.StatusCode = response.StatusCode; response2.Address = Url.Convert(response.ResponseUri); foreach (var item in enumerable) { response2.Headers.Add(item.Key, item.Value); } if (cookieHeader != null) response2.Headers[HeaderNames.SetCookie] = cookieHeader; return response2; } return null; } private void AddHeader(string key, string value) { if (key == HeaderNames.Accept) _http.Accept = value; else if (key == HeaderNames.ContentType) { _http.ContentType = value; } else if (key == HeaderNames.Expect) { SetProperty(HeaderNames.Expect, value); } else if (key == HeaderNames.Date) { SetProperty(HeaderNames.Date, DateTime.Parse(value)); } else if (key == HeaderNames.Host) { SetProperty(HeaderNames.Host, value); } else if (key == HeaderNames.IfModifiedSince) { SetProperty("IfModifiedSince", DateTime.Parse(value)); } else if (key == HeaderNames.Referer) { SetProperty(HeaderNames.Referer, value); } else if (key == HeaderNames.UserAgent) { SetProperty("UserAgent", value); } else if (key != HeaderNames.Connection && key != HeaderNames.Range && key != HeaderNames.ContentLength && key != HeaderNames.TransferEncoding) { _http.Headers.set_Item(key, value); } } private void SetProperty(string name, object value) { if (!_propCache.ContainsKey(name)) _propCache.Add(name, _http.GetType().GetTypeInfo().GetDeclaredProperty(name)); PropertyInfo propertyInfo = _propCache[name]; if (!_restricted.Contains(name) && (object)propertyInfo != null && propertyInfo.CanWrite) try { propertyInfo.SetValue(_http, value, null); } catch { _restricted.Add(name); } } } private const int BufferSize = 4096; private static readonly string _version; private static readonly string _agentName; private static readonly Dictionary<string, PropertyInfo> _propCache; private static readonly List<string> _restricted; private TimeSpan _timeOut; private readonly Dictionary<string, string> _headers; public Dictionary<string, string> Headers => _headers; public TimeSpan Timeout { get { return _timeOut; } set { _timeOut = value; } } static HttpRequester() { _version = typeof(HttpRequester).GetTypeInfo().get_Assembly().GetCustomAttribute<AssemblyFileVersionAttribute>() .Version; _agentName = "AngleSharp/" + _version; _propCache = new Dictionary<string, PropertyInfo>(); _restricted = new List<string>(); } public HttpRequester(string userAgent = null) { _timeOut = new TimeSpan(0, 0, 0, 45); _headers = new Dictionary<string, string>(); _headers.Add("User-Agent", userAgent ?? _agentName); } public bool SupportsProtocol(string protocol) { return protocol.IsOneOf(KnownProtocols.Http, KnownProtocols.Https); } public Task<IResponse> RequestAsync(IRequest request, CancellationToken cancellationToken) { RequestState requestState = new RequestState(request, _headers); return requestState.RequestAsync(cancellationToken); } } }