Exemple #1
0
        public async Task Invoke(DownstreamContext context)
        {
            var options = context.DownstreamReRoute.RateLimitOptions;

            // check if rate limiting is enabled
            if (!context.DownstreamReRoute.EnableEndpointEndpointRateLimiting)
            {
                Logger.LogInformation($"EndpointRateLimiting is not enabled for {context.DownstreamReRoute.DownstreamPathTemplate.Value}");
                await _next.Invoke(context);

                return;
            }

            // compute identity from request
            var identity = SetIdentity(context.HttpContext, options);

            // check white list
            if (IsWhitelisted(identity, options))
            {
                Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} is white listed from rate limiting");
                await _next.Invoke(context);

                return;
            }

            var rule = options.RateLimitRule;

            if (rule.Limit > 0)
            {
                // increment counter
                var counter = _processor.ProcessRequest(identity, options);

                // check if limit is reached
                if (counter.TotalRequests > rule.Limit)
                {
                    //compute retry after value
                    var retryAfter = _processor.RetryAfterFrom(counter.Timestamp, rule);

                    // log blocked request
                    LogBlockedRequest(context.HttpContext, identity, counter, rule, context.DownstreamReRoute);

                    var retrystring = retryAfter.ToString(System.Globalization.CultureInfo.InvariantCulture);

                    // break execution
                    await ReturnQuotaExceededResponse(context.HttpContext, options, retrystring);

                    return;
                }
            }

            //set X-Rate-Limit headers for the longest period
            if (!options.DisableRateLimitHeaders)
            {
                var headers = _processor.GetRateLimitHeaders(context.HttpContext, identity, options);
                context.HttpContext.Response.OnStarting(SetRateLimitHeaders, state: headers);
            }

            await _next.Invoke(context);
        }
Exemple #2
0
        public async Task Invoke(HttpContext context)
        {
            _logger.LogDebug("started calling RateLimit middleware");
            var options = DownstreamRoute.ReRoute.RateLimitOptions;

            // check if rate limiting is enabled
            if (!DownstreamRoute.ReRoute.EnableEndpointRateLimiting)
            {
                await _next.Invoke(context);

                return;
            }
            // compute identity from request
            var identity = SetIdentity(context, options);

            // check white list
            if (IsWhitelisted(identity, options))
            {
                await _next.Invoke(context);

                return;
            }

            var rule = options.RateLimitRule;

            if (rule.Limit > 0)
            {
                // increment counter
                var counter = _processor.ProcessRequest(identity, options);

                // check if limit is reached
                if (counter.TotalRequests > rule.Limit)
                {
                    //compute retry after value
                    var retryAfter = _processor.RetryAfterFrom(counter.Timestamp, rule);

                    // log blocked request
                    LogBlockedRequest(context, identity, counter, rule);

                    // break execution
                    await ReturnQuotaExceededResponse(context, options, retryAfter);

                    return;
                }
            }
            //set X-Rate-Limit headers for the longest period
            if (!options.DisableRateLimitHeaders)
            {
                var headers = _processor.GetRateLimitHeaders(context, identity, options);
                context.Response.OnStarting(SetRateLimitHeaders, state: headers);
            }

            await _next.Invoke(context);
        }
        public static void RequestProcessing(HttpContext httpContext)
        {
            if (!Configurationed)
            {
                return;
            }

            // check if rate limiting is enabled
            if (Options == null)
            {
                return;
            }

            // compute identity from request
            var identity = SetIdentity(httpContext);

            // check white list
            if (Processor.IsWhitelisted(identity))
            {
                return;
            }

            var rules = Processor.GetMatchingRules(identity);

            foreach (var rule in rules)
            {
                if (rule.Limit > 0)
                {
                    // increment counter
                    var counter = Processor.ProcessRequest(identity, rule);

                    // check if key expired
                    if (counter.Timestamp + rule.PeriodTimespan.Value < DateTime.UtcNow)
                    {
                        continue;
                    }

                    // check if limit is reached
                    if (counter.TotalRequests > rule.Limit)
                    {
                        //compute retry after value
                        var retryAfter = Processor.RetryAfterFrom(counter.Timestamp, rule);

                        // log blocked request
                        LogBlockedRequest(httpContext, identity, counter, rule);

                        // break execution
                        ReturnQuotaExceededResponse(httpContext, rule, retryAfter);

                        return;
                    }
                }
            }

            //set X-Rate-Limit headers for the longest period
            if (rules.Any() && !Options.DisableRateLimitHeaders)
            {
                var rule    = rules.OrderByDescending(x => x.PeriodTimespan.Value).First();
                var headers = Processor.GetRateLimitHeaders(identity, rule);
                headers.Context = httpContext;
                headers.Context.Response.Headers["X-Rate-Limit-Limit"]     = headers.Limit;
                headers.Context.Response.Headers["X-Rate-Limit-Remaining"] = headers.Remaining;
                headers.Context.Response.Headers["X-Rate-Limit-Reset"]     = headers.Reset;
            }
        }