- Updated .gitlab-ci.yml with complete build, test, and deploy stages
- Added authentication redirect fix in Program.cs (302 redirect for admin routes)
- Fixed Cookie vs Bearer authentication conflict for admin panel
- Configure pipeline to build from .NET 9.0 source
- Deploy to Hostinger VPS with proper environment variables
- Include rollback capability for production deployments
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
159 lines
6.9 KiB
C#
159 lines
6.9 KiB
C#
using System.Net;
|
|
using LittleShop.Client.Configuration;
|
|
using LittleShop.Client.Http;
|
|
using LittleShop.Client.Services;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace LittleShop.Client.Extensions;
|
|
|
|
public static class ServiceCollectionExtensions
|
|
{
|
|
public static IServiceCollection AddLittleShopClient(
|
|
this IServiceCollection services,
|
|
Action<LittleShopClientOptions>? configureOptions = null,
|
|
bool useTorProxy = false,
|
|
int torSocksPort = 9050)
|
|
{
|
|
// Configure options
|
|
if (configureOptions != null)
|
|
{
|
|
services.Configure(configureOptions);
|
|
}
|
|
else
|
|
{
|
|
services.Configure<LittleShopClientOptions>(options => { });
|
|
}
|
|
|
|
// Register HTTP handlers
|
|
services.AddTransient<RetryPolicyHandler>();
|
|
services.AddTransient<ErrorHandlingMiddleware>();
|
|
|
|
// Helper function to configure SOCKS5 proxy if TOR is enabled
|
|
Func<IServiceProvider, HttpMessageHandler> createHandler = (serviceProvider) =>
|
|
{
|
|
if (useTorProxy)
|
|
{
|
|
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
|
|
var logger = loggerFactory.CreateLogger("LittleShop.Client.TorProxy");
|
|
var proxyUri = $"socks5://127.0.0.1:{torSocksPort}";
|
|
|
|
logger.LogInformation("LittleShop.Client: Configuring SOCKS5 proxy at {ProxyUri}", proxyUri);
|
|
|
|
return new SocketsHttpHandler
|
|
{
|
|
Proxy = new WebProxy(proxyUri)
|
|
{
|
|
BypassProxyOnLocal = false,
|
|
UseDefaultCredentials = false
|
|
},
|
|
UseProxy = true,
|
|
AllowAutoRedirect = false,
|
|
PooledConnectionLifetime = TimeSpan.FromMinutes(5),
|
|
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2)
|
|
};
|
|
}
|
|
else
|
|
{
|
|
return new SocketsHttpHandler();
|
|
}
|
|
};
|
|
|
|
// Register main HTTP client
|
|
services.AddHttpClient<IAuthenticationService, AuthenticationService>((serviceProvider, client) =>
|
|
{
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
client.BaseAddress = new Uri(options.BaseUrl);
|
|
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
|
|
client.DefaultRequestHeaders.Add("Accept", "application/json");
|
|
})
|
|
.ConfigurePrimaryHttpMessageHandler(createHandler)
|
|
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
|
|
.AddHttpMessageHandler(serviceProvider =>
|
|
{
|
|
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
|
|
});
|
|
|
|
services.AddHttpClient<ICatalogService, CatalogService>((serviceProvider, client) =>
|
|
{
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
client.BaseAddress = new Uri(options.BaseUrl);
|
|
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
|
|
client.DefaultRequestHeaders.Add("Accept", "application/json");
|
|
})
|
|
.ConfigurePrimaryHttpMessageHandler(createHandler)
|
|
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
|
|
.AddHttpMessageHandler(serviceProvider =>
|
|
{
|
|
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
|
|
});
|
|
|
|
services.AddHttpClient<IOrderService, OrderService>((serviceProvider, client) =>
|
|
{
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
client.BaseAddress = new Uri(options.BaseUrl);
|
|
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
|
|
client.DefaultRequestHeaders.Add("Accept", "application/json");
|
|
})
|
|
.ConfigurePrimaryHttpMessageHandler(createHandler)
|
|
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
|
|
.AddHttpMessageHandler(serviceProvider =>
|
|
{
|
|
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
|
|
});
|
|
|
|
services.AddHttpClient<ICustomerService, CustomerService>((serviceProvider, client) =>
|
|
{
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
client.BaseAddress = new Uri(options.BaseUrl);
|
|
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
|
|
client.DefaultRequestHeaders.Add("Accept", "application/json");
|
|
})
|
|
.ConfigurePrimaryHttpMessageHandler(createHandler)
|
|
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
|
|
.AddHttpMessageHandler(serviceProvider =>
|
|
{
|
|
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
|
|
});
|
|
|
|
services.AddHttpClient<IMessageService, MessageService>((serviceProvider, client) =>
|
|
{
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
client.BaseAddress = new Uri(options.BaseUrl);
|
|
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
|
|
client.DefaultRequestHeaders.Add("Accept", "application/json");
|
|
})
|
|
.ConfigurePrimaryHttpMessageHandler(createHandler)
|
|
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
|
|
.AddHttpMessageHandler(serviceProvider =>
|
|
{
|
|
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
|
|
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
|
|
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
|
|
});
|
|
|
|
// Register the main client
|
|
services.AddScoped<ILittleShopClient, LittleShopClient>();
|
|
|
|
return services;
|
|
}
|
|
|
|
public static IServiceCollection AddLittleShopClient(
|
|
this IServiceCollection services,
|
|
string baseUrl)
|
|
{
|
|
return services.AddLittleShopClient(options =>
|
|
{
|
|
options.BaseUrl = baseUrl;
|
|
});
|
|
}
|
|
} |