public List <RateLimitRule> GetMatchingRules(ClientRequestIdentity identity) { var limits = new List <RateLimitRule>(); var policies = _policyStore.Get($"{_options.IpPolicyPrefix}"); if (policies != null && policies.IpRules != null && policies.IpRules.Any()) { // search for rules with IP intervals containing client IP var matchPolicies = policies.IpRules.Where(r => _ipParser.ContainsIp(r.Ip, identity.ClientIp)).AsEnumerable(); var rules = new List <RateLimitRule>(); foreach (var item in matchPolicies) { rules.AddRange(item.Rules); } foreach (var rule in rules) { var regex = new Regex(rule.UrlRegex, RegexOptions.IgnoreCase); var match = regex.Match(identity.HttpVerb + ":" + identity.Path); if (match.Success) { limits.Add(rule); } } } // get the most restrictive limit for each period limits = limits.GroupBy(l => l.Period).Select(l => l.OrderBy(x => x.Limit)).Select(l => l.First()).ToList(); // search for matching general rules if (_options.GeneralRules != null) { var matchingGeneralLimits = new List <RateLimitRule>(); foreach (var generalRule in _options.GeneralRules) { var regex = new Regex(generalRule.UrlRegex, RegexOptions.IgnoreCase); var match = regex.Match(identity.HttpVerb + ":" + identity.Path); if (match.Success) { matchingGeneralLimits.Add(generalRule); } } // get the most restrictive general limit for each period var generalLimits = matchingGeneralLimits.GroupBy(l => l.Period).Select(l => l.OrderBy(x => x.Limit)).Select(l => l.First()).ToList(); foreach (var generalLimit in generalLimits) { // add general rule if no specific rule is declared for the specified period if (!limits.Exists(l => l.Period == generalLimit.Period)) { limits.Add(generalLimit); } } } foreach (var item in limits) { //parse period text into time spans item.PeriodTimespan = _core.ConvertToTimeSpan(item.Period); } limits = limits.OrderBy(l => l.PeriodTimespan).ToList(); if (_options.StackBlockedRequests) { limits.Reverse(); } return(limits); }
public RateLimitCounter ProcessRequest(ClientRequestIdentity requestIdentity, RateLimitRule rule) { return(_core.ProcessRequest(requestIdentity, rule)); }
public RateLimitHeaders GetRateLimitHeaders(ClientRequestIdentity requestIdentity, RateLimitRule rule) { return(_core.GetRateLimitHeaders(requestIdentity, rule)); }
public virtual void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity, RateLimitCounter counter, RateLimitRule rule) { _logger.LogInformation($"Request {identity.HttpVerb}:{identity.Path} from ClientId {identity.ClientId} has been blocked, quota {rule.Limit}/{rule.Period} exceeded by {counter.TotalRequests}. Blocked by rule {rule.UrlRegex}, TraceIdentifier {httpContext.TraceIdentifier}."); }