public HttpRequestRateLimiterMiddleware(RequestDelegate next, IOptions <HttpRequestRateLimiterOptions <TKey> > options, IConfiguration config, ILoggerFactory loggerFactory) { Next = next ?? throw new ArgumentNullException(nameof(next)); Config = config ?? throw new ArgumentNullException(nameof(config)); Options = options?.Value ?? throw new ArgumentNullException(nameof(options)); RateLimiter = new RateLimiter <TKey>(RateLimiterOptions); ConcurrentLimiter = new ConcurrentLimiter <TKey>(Options.MaxConcurrentRequestsPerSrcSubnet); }
// Factory メソッド public static IHttpRequestRateLimiterHashKey?CreateFromHttpContext <TKey>(HttpContext context, HttpRequestRateLimiterOptions <TKey> options) where TKey : IHttpRequestRateLimiterHashKey { // Src IP の処理 IPAddress srcIp = context.Connection.RemoteIpAddress._UnmapIPv4(); if (options.SrcIPExcludeLocalNetwork) { // ローカルネットワークを除外する if (srcIp._GetIPAddressType()._IsLocalNetwork()) { return(null); } } // サブネットマスクの AND をする if (srcIp.AddressFamily == AddressFamily.InterNetwork) { // IPv4 srcIp = IPUtil.IPAnd(srcIp, IPUtil.IntToSubnetMask4(options.SrcIPv4SubnetLength)); } else { // IPv6 srcIp = IPUtil.IPAnd(srcIp, IPUtil.IntToSubnetMask6(options.SrcIPv6SubnetLength)); } if (typeof(TKey) == typeof(SrcIPAddress)) { if (srcIp != null) { return(new SrcIPAddress(srcIp)); } } return(null); }