DigitalData.Core/DigitalData.Core.Client/BaseHttpClientService.cs

96 lines
3.3 KiB
C#

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<HttpClientOptions> clientOptions)
{
_client = client;
_cookies = cookieContainer;
Uri = clientOptions.Value.Uri;
}
public CookieCollection GetCookies(string route = "") => _cookies.GetCookies(uri: new Uri(Uri + route));
public async Task<HttpResponseMessage> FetchAsync(
string? scheme = null,
int? port = null,
string? path = null,
Dictionary<string, string>? queryParams = null,
HttpMethod? method = null,
HttpContent? body = null,
Dictionary<string, string>? form = null,
Dictionary<string, string>? 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;
}
}
}