using SharedKernel;
using Microsoft.AspNetCore.HttpOverrides;
using System.Net;
namespace Web.Api.Extensions;
public static class ServiceCollectionExtensions
{
///
/// Cloudflare → IIS reverse proxy → backend 환경에서 X-Forwarded-For/Proto/Host 헤더를 신뢰해
/// HttpContext.Connection.RemoteIpAddress 등을 실 client 값으로 갱신.
///
/// IIS web.config 가 `HTTP_X_FORWARDED_FOR = {HTTP_CF_CONNECTING_IP}` 로 단일 client IP 만 설정함.
/// backend 가 직접 받는 peer 는 IIS (127.0.0.1) 라 KnownProxies 에 127.0.0.1 만 두면 충분.
///
public static void AddApiForwardedHeaders(this IServiceCollection services, AppSettings settings)
{
services.Configure(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
options.ForwardLimit = settings.ForwardedHeaders.ForwardLimit <= 0 ? 1 : settings.ForwardedHeaders.ForwardLimit;
var knownProxies = settings.ForwardedHeaders.KnownProxies;
if (knownProxies != null)
{
foreach (var proxy in knownProxies)
{
if (IPAddress.TryParse(proxy, out var ip))
{
options.KnownProxies.Add(ip);
}
}
}
var knownNetworks = settings.ForwardedHeaders.KnownNetworks;
if (knownNetworks != null)
{
foreach (var net in knownNetworks)
{
var parts = net.Split('/');
if (parts.Length == 2 && IPAddress.TryParse(parts[0], out var networkIp) && int.TryParse(parts[1], out var prefix))
{
options.KnownIPNetworks.Add(new System.Net.IPNetwork(networkIp, prefix));
}
}
}
});
}
}