public ClientRateLimitProcessor(
     ClientRateLimitOptions options,
     IClientPolicyStore policyStore,
     IProcessingStrategy processingStrategy)
     : base(options)
 {
     _options            = options;
     _policyStore        = policyStore;
     _counterKeyBuilder  = new ClientCounterKeyBuilder(options);
     _processingStrategy = processingStrategy;
 }
Exemple #2
0
 protected RateLimitProcessor(
     RateLimitOptions options,
     IRateLimitCounterStore counterStore,
     ICounterKeyBuilder counterKeyBuilder,
     IRateLimitConfiguration config)
 {
     _options           = options;
     _counterStore      = counterStore;
     _counterKeyBuilder = counterKeyBuilder;
     _config            = config;
 }
Exemple #3
0
 public IpRateLimitProcessor(
     IpRateLimitOptions options,
     IIpPolicyStore policyStore,
     IProcessingStrategy processingStrategy)
     : base(options)
 {
     _options            = options;
     _policyStore        = policyStore;
     _counterKeyBuilder  = new IpCounterKeyBuilder(options);
     _processingStrategy = processingStrategy;
 }
Exemple #4
0
 protected RateLimitProcessor(
     ICacheManager cacheManager,
     RateLimitOptions options,
     ICounterKeyBuilder counterKeyBuilder,
     IRateLimitConfiguration config)
 {
     _cacheManager      = cacheManager;
     _options           = options;
     _counterKeyBuilder = counterKeyBuilder;
     _config            = config;
 }
Exemple #5
0
        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);
        }