try fix download client factory

This commit is contained in:
Flaminel
2025-06-16 21:38:27 +03:00
parent f651663fd3
commit 0a8d1450dd
12 changed files with 495 additions and 115 deletions

View File

@@ -1,11 +1,9 @@
using System.Net;
using Common.Configuration;
using Data.Models.Configuration.General;
using Data;
using Infrastructure.Services;
using Infrastructure.Http.DynamicHttpClientSystem;
using Microsoft.Extensions.Logging;
using Polly;
using Polly.Extensions.Http;
using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Http;
@@ -16,40 +14,22 @@ public class DynamicHttpClientProvider : IDynamicHttpClientProvider
{
private readonly ILogger<DynamicHttpClientProvider> _logger;
private readonly DataContext _dataContext;
private readonly IHttpClientFactory _httpClientFactory;
private readonly CertificateValidationService _certificateValidationService;
private readonly IDynamicHttpClientFactory _dynamicHttpClientFactory;
public DynamicHttpClientProvider(
ILogger<DynamicHttpClientProvider> logger,
DataContext dataContext,
IHttpClientFactory httpClientFactory,
CertificateValidationService certificateValidationService)
IDynamicHttpClientFactory dynamicHttpClientFactory)
{
_logger = logger;
_dataContext = dataContext;
_httpClientFactory = httpClientFactory;
_certificateValidationService = certificateValidationService;
_dynamicHttpClientFactory = dynamicHttpClientFactory;
}
/// <inheritdoc />
public HttpClient CreateClient(DownloadClientConfig downloadClientConfig)
{
if (downloadClientConfig == null)
{
throw new ArgumentNullException(nameof(downloadClientConfig));
}
// Try to use named client if it exists
try
{
string clientName = GetClientName(downloadClientConfig);
return _httpClientFactory.CreateClient(clientName);
}
catch (InvalidOperationException)
{
_logger.LogWarning("Named HTTP client for {clientId} not found, creating generic client", downloadClientConfig.Id);
return CreateGenericClient(downloadClientConfig);
}
return CreateGenericClient(downloadClientConfig);
}
/// <summary>
@@ -63,42 +43,40 @@ public class DynamicHttpClientProvider : IDynamicHttpClientProvider
}
/// <summary>
/// Creates a generic HTTP client with appropriate configuration
/// Creates a generic HTTP client with appropriate configuration using the dynamic system
/// </summary>
/// <param name="downloadClientConfig">The client configuration</param>
/// <returns>A configured HttpClient instance</returns>
private HttpClient CreateGenericClient(DownloadClientConfig downloadClientConfig)
{
// TODO
var httpConfig = _dataContext.GeneralConfigs.First();
var clientName = GetClientName(downloadClientConfig);
// Create handler with certificate validation
var handler = new HttpClientHandler
// Determine the client type based on the download client type
var clientType = downloadClientConfig.TypeName switch
{
ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
_certificateValidationService.ShouldByPassValidationError(
httpConfig.HttpCertificateValidation,
sender,
certificate,
chain,
sslPolicyErrors
),
UseDefaultCredentials = false
Common.Enums.DownloadClientTypeName.Deluge => HttpClientType.Deluge,
_ => HttpClientType.WithRetry
};
if (downloadClientConfig.TypeName == Common.Enums.DownloadClientTypeName.Deluge)
// Create retry configuration
var retryConfig = new RetryConfig
{
handler.AllowAutoRedirect = true;
handler.UseCookies = true;
handler.CookieContainer = new CookieContainer();
handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
}
// Create client with policy
var client = new HttpClient(handler)
{
Timeout = TimeSpan.FromSeconds(httpConfig.HttpTimeout)
MaxRetries = httpConfig.HttpMaxRetries,
ExcludeUnauthorized = true
};
// Register the client configuration dynamically
_dynamicHttpClientFactory.RegisterDownloadClient(
clientName,
httpConfig.HttpTimeout,
clientType,
retryConfig,
httpConfig.HttpCertificateValidation
);
// Create and configure the client
var client = _dynamicHttpClientFactory.CreateClient(clientName);
// Set base address if needed
if (downloadClientConfig.Url != null)
@@ -106,23 +84,9 @@ public class DynamicHttpClientProvider : IDynamicHttpClientProvider
client.BaseAddress = downloadClientConfig.Url;
}
_logger.LogDebug("Created generic HTTP client for client {clientId} with base address {baseAddress}",
downloadClientConfig.Id, client.BaseAddress);
_logger.LogTrace("Created HTTP client for download client {Name} (ID: {Id}) with type {Type}",
downloadClientConfig.Name, downloadClientConfig.Id, clientType);
return client;
}
/// <summary>
/// Creates a retry policy for the HTTP client
/// </summary>
/// <param name="generalConfig">The HTTP configuration</param>
/// <returns>A configured policy</returns>
private static IAsyncPolicy<HttpResponseMessage> CreateRetryPolicy(GeneralConfig generalConfig)
{
return HttpPolicyExtensions
.HandleTransientHttpError()
// Do not retry on Unauthorized
.OrResult(response => !response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.Unauthorized)
.WaitAndRetryAsync(generalConfig.HttpMaxRetries, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
}
}