using DigitalData.Core.Abstractions.Client; using Microsoft.Extensions.Options; using System.Diagnostics.CodeAnalysis; using System.Net; using System.Web; namespace DigitalData.Core.Client { public class BaseHttpClientService : IBaseHttpClientService { protected readonly HttpClient _client; protected readonly CookieContainer _cookies; [StringSyntax("Uri")] public string Uri { get; init; } public BaseHttpClientService(HttpClient client, CookieContainer cookieContainer, IOptions clientOptions) { _client = client; _cookies = cookieContainer; Uri = clientOptions.Value.Uri; } public CookieCollection GetCookies(string route = "") => _cookies.GetCookies(uri: new Uri(Uri + route)); public async Task FetchAsync( string? scheme = null, int? port = null, string? path = null, Dictionary? queryParams = null, HttpMethod? method = null, HttpContent? body = null, Dictionary? form = null, Dictionary? headers = null, bool sendWithCookie = true, bool saveCookie = true ) { // set default HTTP method as GET method ??= HttpMethod.Get; // create URL var uriBuilder = new UriBuilder(Uri); if(scheme is not null) uriBuilder.Scheme = scheme; if (port is int portInt) uriBuilder.Port = portInt; uriBuilder.Path = path; // Add query parameters if provided if (queryParams?.Count > 0) { var query = HttpUtility.ParseQueryString(uriBuilder.Query); foreach (var param in queryParams) query[param.Key] = param.Value; uriBuilder.Query = query.ToString(); } var requestUri = uriBuilder.Uri; var requestMessage = new HttpRequestMessage(method, requestUri); // Add headers if provided headers?.ForEach(header => requestMessage.Headers.Add(header.Key, header.Value)); // Add cookie to request if (sendWithCookie) { var cookieHeader = _cookies.GetCookieHeader(requestUri); if (!string.IsNullOrWhiteSpace(cookieHeader)) { requestMessage.Headers.Add("Cookie", cookieHeader); } } // Add body content if provided if (body != null && form != null) throw new InvalidOperationException("Body content and form data cannot both be set."); else if (body != null) requestMessage.Content = body; else if (form != null) requestMessage.Content = new FormUrlEncodedContent(form); var response = await _client.SendAsync(requestMessage); // Add response cookies to cookies if (saveCookie) if (response.Headers.TryGetValues("Set-Cookie", out var cookies)) foreach (var cookie in cookies) _cookies.SetCookies(requestUri, cookie); return response; } } }