public override List <RateLimitRule> GetMatchingRules(ClientRequest clientRequest) { var result = new List <RateLimitRule>(); var rulePeriodComparer = new RateLimitRule.PeriodComparer(); // get matching client rules var policy = _policyStore.Get($"{_options.ClientPolicyPrefix}_{clientRequest.ClientId}"); if (policy?.Rules != null && policy.Rules.Any()) { if (_options.EnableEndpointRateLimiting) { var endpointRules = policy.Rules.GetEndpointRules(clientRequest.HttpVerb, clientRequest.Path); result.AddRange(endpointRules); } // add client specific global rules where no rule exists for period var globalRules = policy.Rules.GetGlobalRules(clientRequest.HttpVerb); result.AddRange(globalRules.Except(result, rulePeriodComparer)); } // add general rules where no rule exists for period var generalRules = GetMatchingGeneralRules(clientRequest); if (generalRules != null) { result.AddRange(generalRules.Except(result, rulePeriodComparer)); } // order by period result = result.OrderBy(x => x.PeriodTimeSpan).ToList(); if (_options.StackBlockedRequests) { result.Reverse(); } return(result); }
public ClientRateLimitPolicy Get() { return(_clientPolicyStore.Get($"{_options.ClientPolicyPrefix}_cl-key-1")); }
public List <RateLimitRule> GetMatchingRules(ClientRequestIdentity identity) { var limits = new List <RateLimitRule>(); var policy = _policyStore.Get($"{_options.ClientPolicyPrefix}_{identity.ClientId}"); if (policy != null) { if (_options.EnableEndpointRateLimiting) { // search for rules with endpoints like "*" and "*:/matching_path" var pathLimits = policy.Rules.Where(l => $"*:{identity.Path}".ContainsIgnoreCase(l.Endpoint)).AsEnumerable(); limits.AddRange(pathLimits); // search for rules with endpoints like "matching_verb:/matching_path" var verbLimits = policy.Rules.Where(l => $"{identity.HttpVerb}:{identity.Path}".ContainsIgnoreCase(l.Endpoint)).AsEnumerable(); limits.AddRange(verbLimits); } else { //ignore endpoint rules and search for global rules only var genericLimits = policy.Rules.Where(l => l.Endpoint == "*").AsEnumerable(); limits.AddRange(genericLimits); } } // 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>(); if (_options.EnableEndpointRateLimiting) { // search for rules with endpoints like "*" and "*:/matching_path" in general rules var pathLimits = _options.GeneralRules.Where(l => $"*:{identity.Path}".ContainsIgnoreCase(l.Endpoint)).AsEnumerable(); matchingGeneralLimits.AddRange(pathLimits); // search for rules with endpoints like "matching_verb:/matching_path" in general rules var verbLimits = _options.GeneralRules.Where(l => $"{identity.HttpVerb}:{identity.Path}".ContainsIgnoreCase(l.Endpoint)).AsEnumerable(); matchingGeneralLimits.AddRange(verbLimits); } else { //ignore endpoint rules and search for global rules in general rules var genericLimits = _options.GeneralRules.Where(l => l.Endpoint == "*").AsEnumerable(); matchingGeneralLimits.AddRange(genericLimits); } // 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 List <RateLimitRule> GetMatchingRules(ClientRequestIdentity identity) { var limits = new List <RateLimitRule>(); var policy = _policyStore.Get($"{_options.ClientPolicyPrefix}_{identity.ClientId}"); if (policy != null) { foreach (var rule in policy.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); }