public ClientRateLimitProcessor( ClientRateLimitOptions options, IClientPolicyStore policyStore, IProcessingStrategy processingStrategy) : base(options) { _options = options; _policyStore = policyStore; _counterKeyBuilder = new ClientCounterKeyBuilder(options); _processingStrategy = processingStrategy; }
protected RateLimitProcessor( RateLimitOptions options, IRateLimitCounterStore counterStore, ICounterKeyBuilder counterKeyBuilder, IRateLimitConfiguration config) { _options = options; _counterStore = counterStore; _counterKeyBuilder = counterKeyBuilder; _config = config; }
public IpRateLimitProcessor( IpRateLimitOptions options, IIpPolicyStore policyStore, IProcessingStrategy processingStrategy) : base(options) { _options = options; _policyStore = policyStore; _counterKeyBuilder = new IpCounterKeyBuilder(options); _processingStrategy = processingStrategy; }
protected RateLimitProcessor( ICacheManager cacheManager, RateLimitOptions options, ICounterKeyBuilder counterKeyBuilder, IRateLimitConfiguration config) { _cacheManager = cacheManager; _options = options; _counterKeyBuilder = counterKeyBuilder; _config = config; }
public override async Task <RateLimitCounter> ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, ICounterKeyBuilder counterKeyBuilder, RateLimitOptions rateLimitOptions, CancellationToken cancellationToken = default) { var counterId = BuildCounterKey(requestIdentity, rule, counterKeyBuilder, rateLimitOptions); return(await IncrementAsync(counterId, rule.PeriodTimespan.Value, _config.RateIncrementer)); }
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 abstract Task <RateLimitCounter> ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, ICounterKeyBuilder counterKeyBuilder, RateLimitOptions rateLimitOptions, CancellationToken cancellationToken = default);
public override async Task <RateLimitCounter> ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, ICounterKeyBuilder counterKeyBuilder, RateLimitOptions rateLimitOptions, CancellationToken cancellationToken = default) { var counter = new RateLimitCounter { Timestamp = DateTime.UtcNow, Count = 1 }; var counterId = BuildCounterKey(requestIdentity, rule, counterKeyBuilder, rateLimitOptions); // 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 totalCount = entry.Value.Count + _config.RateIncrementer?.Invoke() ?? 1; // deep copy counter = new RateLimitCounter { Timestamp = entry.Value.Timestamp, Count = totalCount }; } } // stores: id (string) - timestamp (datetime) - total_requests (long) await _counterStore.SetAsync(counterId, counter, rule.PeriodTimespan.Value, cancellationToken); } return(counter); }