public override Task ReturnQuotaExceededResponse(HttpContext httpContext, AspNetCoreRateLimit.RateLimitRule rule, string retryAfter) { httpContext.Response.Headers.Append("Access-Control-Allow-Origin", "*"); //string str = string.Format("API calls quata exceeded! maximum maximum admitted {0} per {1}", rule. , // rule.Period); //var result = JsonConvert.SerializeObject(new { error = str }); //httpContext.Response.Headers["Retry-After"] = retryAfter; //httpContext.Response.StatusCode = 429; //httpContext.Response.ContentType = "application/json"; return(base.ReturnQuotaExceededResponse(httpContext, rule, retryAfter)); }
private void LogBlockedRequest(HttpContext httpContext, ClientRequest identity, RateLimitRule rule) { _logger.LogInformation($"Request {identity.HttpVerb}:{identity.Path} from ClientId {identity.ClientId} has been blocked, quota {rule.Limit}/{rule.Period} exceeded. Blocked by rule {rule.Endpoint}. TraceIdentifier {httpContext.TraceIdentifier}."); }
private Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitRule rule) { return(ReturnQuotaExceededResponse(httpContext, rule, null)); }
protected override 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.Count - rule.Limit}. Blocked by rule {rule.Endpoint}, TraceIdentifier {httpContext.TraceIdentifier}. MonitorMode: {rule.MonitorMode}"); }
protected virtual string BuildCounterKey(ClientRequestIdentity requestIdentity, RateLimitRule rule, ICounterKeyBuilder counterKeyBuilder, RateLimitOptions rateLimitOptions) { var key = counterKeyBuilder.Build(requestIdentity, rule); if (rateLimitOptions.EnableEndpointRateLimiting && _config.EndpointCounterKeyBuilder != null) { key += _config.EndpointCounterKeyBuilder.Build(requestIdentity, rule); } var bytes = Encoding.UTF8.GetBytes(key); using var algorithm = new SHA1Managed(); var hash = algorithm.ComputeHash(bytes); return(Convert.ToBase64String(hash)); }
public virtual void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity, RateLimitCounter counter, RateLimitRule rule) { _logger.LogInformation($"Request {identity.HttpVerb}:{identity.Path} from IP {identity.ClientIp} has been blocked, quota {rule.Limit}/{rule.Period} exceeded by {counter.TotalRequests}. Blocked by rule {rule.Endpoint}, TraceIdentifier {httpContext.TraceIdentifier}."); if (counter.TotalRequests == (rule.Limit * _options.IpFloodWarningFactor)) { _logger.LogWarning($"Flood tentative from IP Address {identity.ClientIp}"); } else if (counter.TotalRequests == (rule.Limit * _options.IpFloodBanFactor)) { _logger.LogWarning($"Too many Flood tentative from IP Address {identity.ClientIp}"); TempBanIP(identity.ClientIp); } }
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 IP {identity.ClientIp} has been blocked, quota {rule.Limit}/{rule.Period} exceeded by {counter.TotalRequests}. Blocked by rule {rule.Endpoint}, TraceIdentifier {httpContext.TraceIdentifier}."); }
public RateLimitHeaders GetRateLimitHeaders(ClientRequestIdentity requestIdentity, RateLimitRule rule) { var headers = new RateLimitHeaders(); var counterId = ComputeCounterKey(requestIdentity, rule); var entry = _counterStore.Get(counterId); if (entry.HasValue) { headers.Reset = (entry.Value.Timestamp + ConvertToTimeSpan(rule.Period)).ToUniversalTime() .ToString("o", DateTimeFormatInfo.InvariantInfo); headers.Limit = rule.Period; headers.Remaining = (rule.Limit - entry.Value.TotalRequests).ToString(); } else { headers.Reset = (DateTime.UtcNow + ConvertToTimeSpan(rule.Period)).ToUniversalTime() .ToString("o", DateTimeFormatInfo.InvariantInfo); headers.Limit = rule.Period; headers.Remaining = rule.Limit.ToString(); } return(headers); }
protected abstract void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity, RateLimitCounter counter, RateLimitRule rule);
public virtual async Task <RateLimitHeaders> GetRateLimitHeadersAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, CancellationToken cancellationToken = default) { var headers = new RateLimitHeaders(); var counterId = BuildCounterKey(requestIdentity, rule); var entry = await _counterStore.GetAsync(counterId, cancellationToken); long remaining; DateTime reset; if (entry.HasValue) { reset = entry.Value.Timestamp + (rule.PeriodTimespan ?? rule.Period.ToTimeSpan()); remaining = rule.Limit - entry.Value.TotalRequests; } else { reset = DateTime.UtcNow + (rule.PeriodTimespan ?? rule.Period.ToTimeSpan()); remaining = rule.Limit; } headers.Reset = reset.ToUniversalTime().ToString("o", DateTimeFormatInfo.InvariantInfo); headers.Limit = rule.Period; headers.Remaining = remaining.ToString(); return(headers); }
public virtual async Task <RateLimitCounter> ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, CancellationToken cancellationToken = default) { var counter = new RateLimitCounter { Timestamp = DateTime.UtcNow, TotalRequests = 1 }; var counterId = BuildCounterKey(requestIdentity, rule); // serial reads and writes on same key using (await AsyncLock.WriterLockAsync(counterId).ConfigureAwait(false)) { var entry = await _counterStore.GetAsync(counterId, cancellationToken); if (entry.HasValue) { // entry has not expired if (entry.Value.Timestamp + rule.PeriodTimespan.Value >= DateTime.UtcNow) { // increment request count var totalRequests = entry.Value.TotalRequests + 1; // deep copy counter = new RateLimitCounter { Timestamp = entry.Value.Timestamp, TotalRequests = totalRequests }; } } // stores: id (string) - timestamp (datetime) - total_requests (long) await _counterStore.SetAsync(counterId, counter, rule.PeriodTimespan.Value, cancellationToken); } return(counter); }
public virtual RateLimitHeaders GetRateLimitHeaders(RateLimitCounter?counter, RateLimitRule rule, CancellationToken cancellationToken = default) { var headers = new RateLimitHeaders(); double remaining; DateTime reset; if (counter.HasValue) { reset = counter.Value.Timestamp + (rule.PeriodTimespan ?? rule.Period.ToTimeSpan()); remaining = rule.Limit - counter.Value.Count; } else { reset = DateTime.UtcNow + (rule.PeriodTimespan ?? rule.Period.ToTimeSpan()); remaining = rule.Limit; } headers.Reset = reset.ToUniversalTime().ToString("o", DateTimeFormatInfo.InvariantInfo); headers.Limit = rule.Period; headers.Remaining = remaining.ToString(); return(headers); }
protected override void LogBlockedRequest(HttpContext httpContext, AspNetCoreRateLimit.ClientRequestIdentity identity, AspNetCoreRateLimit.RateLimitCounter counter, AspNetCoreRateLimit.RateLimitRule rule) { base.LogBlockedRequest(httpContext, identity, counter, rule); }
protected override void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity, RateLimitCounter counter, RateLimitRule rule) { _logger.LogInformation("Request {HttpVerb}:{Path} from ClientId {ClientId} has been blocked, quota {Limit}/{Period} exceeded by {Count}. Blocked by rule {Endpoint}, TraceIdentifier {TraceIdentifier}.", identity.HttpVerb, identity.Path, identity.ClientId, rule.Limit, rule.Period, counter.Count, rule.Endpoint, httpContext.TraceIdentifier); }
public RateLimitCounter ProcessRequest(ClientRequestIdentity requestIdentity, RateLimitRule rule) { var counter = new RateLimitCounter { Timestamp = DateTime.UtcNow, TotalRequests = 1 }; var counterId = ComputeCounterKey(requestIdentity, rule); // serial reads and writes lock (_processLocker) { var entry = _counterStore.Get(counterId); if (entry.HasValue) { // entry has not expired if (entry.Value.Timestamp + rule.PeriodTimespan.Value >= DateTime.UtcNow) { // increment request count var totalRequests = entry.Value.TotalRequests + 1; // deep copy counter = new RateLimitCounter { Timestamp = entry.Value.Timestamp, TotalRequests = totalRequests }; } } // stores: id (string) - timestamp (datetime) - total_requests (long) _counterStore.Set(counterId, counter, rule.PeriodTimespan.Value); } return(counter); }
public async Task <RateLimitCounter> ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, CancellationToken cancellationToken = default) { return(await _processingStrategy.ProcessRequestAsync(requestIdentity, rule, _counterKeyBuilder, _options, cancellationToken)); }
public RateLimitCounter?GetStoredRateLimitCounter(ClientRequestIdentity requestIdentity, RateLimitRule rule) { var counterId = ComputeCounterKey(requestIdentity, rule); // serial reads and writes lock (_processLocker) { var entry = _counterStore.Get(counterId); if (entry.HasValue) { // entry has not expired if (entry.Value.Timestamp + rule.PeriodTimespan.Value >= DateTime.UtcNow) { // deep copy var counter = new RateLimitCounter { Timestamp = entry.Value.Timestamp, TotalRequests = entry.Value.TotalRequests }; return(counter); } } } return(null); }
public RateLimitCounter ProcessRequest(ClientRequestIdentity requestIdentity, RateLimitRule rule) { return(_core.ProcessRequest(requestIdentity, rule)); }
public abstract Task <RateLimitCounter> ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, ICounterKeyBuilder counterKeyBuilder, RateLimitOptions rateLimitOptions, CancellationToken cancellationToken = default);
public string RetryAfterFrom(DateTime timestamp, RateLimitRule rule) { return(_core.RetryAfterFrom(timestamp, rule)); }
public virtual Task <RateLimitCounter> ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, CancellationToken cancellationToken = default) { var counterId = BuildCounterKey(requestIdentity, rule); return(_counterStore.IncrementAsync(counterId, rule.PeriodTimespan.Value, _config.RateIncrementer)); }