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); }
private void CheckIfCallerIsBanned(RateLimiterContext context) { foreach (var ruleContext in context.Rules) { if (ruleContext.Banned) { throw new TooManyRequestsException("Too many requests", ruleContext.SecondsLeftOnBan); } } }
private Task WriteRateLimiterContextAsync(RateLimiterContext rateLimiterContext) { foreach (var ruleContext in rateLimiterContext.Rules) { var value = ruleContext.ToString(); var cacheKey = $"{ruleContext.Name}:{rateLimiterContext.IpNumber}"; _cache.SetStringAsync(cacheKey, value, new DistributedCacheEntryOptions { AbsoluteExpiration = ruleContext.WindowExpiration }); } return(Task.FromResult(new object())); }