Esempio n. 1
0
        private async Task <RateLimiterContext> GetRateLimiterContextAsync(HttpContext context)
        {
            var ip = context.Connection.RemoteIpAddress?.ToString();
            var rateLimiterContext = new RateLimiterContext();

            rateLimiterContext.IpNumber = ip;

            foreach (var rule in Settings.Rules)
            {
                var cacheKey      = $"{rule.Name}:{ip}";
                var contextString = await _cache.GetStringAsync(cacheKey);

                RateLimiterRuleContext ruleContext;
                if (contextString != null)
                {
                    ruleContext = new RateLimiterRuleContext(contextString);
                    ruleContext.ExistsInCache = true;
                    ruleContext.Rule          = Settings.Rules.Find(r => r.Name == rule.Name);
                }
                else
                {
                    ruleContext = new RateLimiterRuleContext(rule);
                }
                ruleContext.Context = rateLimiterContext;
                rateLimiterContext.Rules.Add(ruleContext);
            }

            return(rateLimiterContext);
        }
Esempio n. 2
0
        private void ProcessFailedRequest(Exception exception, RateLimiterRuleContext ruleContext)
        {
            var rule          = ruleContext.Rule;
            var exceptionName = exception.GetType().Name;

            if (!rule.RateLimitExceptions.Contains(exceptionName))
            {
                ProcessSuccessfulRequest(ruleContext);
                return;
            }

            ruleContext.SoftRequests++;
            ruleContext.HardRequests++;

            // Use HarmlessRequests (i.e. successful requests with low response time)
            // to reduce the value of SoftRequests when comparing to the limit.
            // This way, a caller with many clients won't be banned if there are many
            // users that are failing their requests due to natural reasons.
            var modulatedRequests = ruleContext.SoftRequests - ruleContext.HarmlessRequests / ruleContext.Rule.SuccessfulToFailedRatio;

            if (modulatedRequests > rule.SoftRequestLimit || ruleContext.HardRequests > rule.HardRequestLimit)
            {
                ruleContext.BannedUntil = DateTime.UtcNow.AddMinutes(rule.BanForMinutes);
            }
        }
Esempio n. 3
0
 private void ProcessSuccessfulRequest(RateLimiterRuleContext ruleContext)
 {
     if (ruleContext.Context.ResponseTime > ruleContext.Rule.RateLimitResponseMilliseconds)
     {
         ruleContext.SoftRequests++;
         ruleContext.HardRequests++;
     }
     else
     {
         ruleContext.HarmlessRequests++;
     }
 }