Example #1
0
        public void Execute(EventRequestingArgs e)
        {
            if (ConfigSettings.Instance.IsLimit)
            {
                var ipaddress = e.Request.RemoteIPAddress.Substring(0, e.Request.RemoteIPAddress.LastIndexOf(':'));
                HttpRequestMessageInfo httpRequest = new HttpRequestMessageInfo()
                {
                    IPAddress  = ipaddress,
                    Method     = e.Request.Method,
                    RequestUrL = e.Request.BaseUrl
                };
                //缓存限流
                var reslut = UseCachePolicyWithLocking.Check(new GenericKey(ipaddress));
                //redis 限流
                //var reslut = apiRequestPolicy.Check(httpRequest);

                if (reslut.IsThrottled)
                {
                    e.Cancel = true;
                    e.Gateway.Response(e.Response, new NotFoundResult("请求太频繁,请稍后再试"));
                    Console.WriteLine($"访问太频繁,请稍后再试");
                }
                if (reslut.IsLocked)
                {
                    e.Gateway.Response(e.Response, new NotFoundResult("请求太频繁,请稍后再试"));
                    e.Cancel = true;
                    Console.WriteLine($"访问太频繁,已被锁定{DateTime.Now}锁定时间{reslut.Limiter.LockDuration}");
                }
            }
        }
Example #2
0
        private Task SetRateLimitHeaders(EventRequestingArgs e, object rateLimitHeaders)
        {
            var headers = (RateLimitHeaders)rateLimitHeaders;

            e.Response.Header["X-Rate-Limit-Limit"]     = headers.Limit;
            e.Response.Header["X-Rate-Limit-Remaining"] = headers.Remaining;
            e.Response.Header["X-Rate-Limit-Reset"]     = headers.Reset;

            return(Task.CompletedTask);
        }
Example #3
0
 protected bool OnRequesting(HttpRequest request, HttpResponse response)
 {
     if (Requesting != null)
     {
         EventRequestingArgs e = new EventRequestingArgs(request, response);
         e.Cancel = false;
         Requesting?.Invoke(this, e);
         return(!e.Cancel);
     }
     return(true);
 }
Example #4
0
        public virtual Task ReturnQuotaExceededResponse(EventRequestingArgs e, RateLimitRule rule, string retryAfter)
        {
            var message = string.Format(
                _options.QuotaExceededResponse?.Content ??
                _options.QuotaExceededMessage ??
                "API calls quota exceeded! maximum admitted {0} per {1}.", rule.Limit, rule.Period, retryAfter);

            if (!_options.DisableRateLimitHeaders)
            {
                e.Response.Header["Retry-After"] = retryAfter;
            }
            e.Response.SetStatus(_options.QuotaExceededResponse?.StatusCode.ToString() ?? _options.HttpStatusCode.ToString(), message);

            e.Response.Result(new JsonResult(new { returnCode = _options.QuotaExceededResponse?.StatusCode ?? _options.HttpStatusCode, message }));

            e.Cancel = true;
            return(Task.CompletedTask);
        }
Example #5
0
 public void Execute(EventRequestingArgs e)
 {
     netCoreRateLimit.Invoke(e).GetAwaiter().GetResult();
 }
Example #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        /// <param name="clientId">客户端ID,如有值,覆盖其他数据</param>
        /// <param name="clientIp">客户端IP,如有值,覆盖其他数据</param>
        /// <returns></returns>
        public async Task Invoke(EventRequestingArgs e, string clientId = null, string clientIp = null)
        {
            HttpRequest httpRequest = e.Request;
            // compute identity from request
            var identity = ResolveIdentity(httpRequest);

            if (!String.IsNullOrEmpty(clientId))
            {
                identity.ClientId = clientId;
            }
            if (!String.IsNullOrEmpty(clientIp))
            {
                identity.ClientIp = clientIp;
            }

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


            var rules = await _processor.GetMatchingRulesAsync(identity);

            var rulesDict = new Dictionary <RateLimitRule, RateLimitCounter>();

            foreach (var rule in rules)
            {
                // increment counter
                var rateLimitCounter = await _processor.ProcessRequestAsync(identity, rule);

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

                    // check if limit is reached
                    if (rateLimitCounter.Count > rule.Limit)
                    {
                        //compute retry after value
                        var retryAfter = rateLimitCounter.Timestamp.RetryAfterFrom(rule);

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

                        //if (_options.RequestBlockedBehavior != null)
                        //{
                        //    await _options.RequestBlockedBehavior(context, identity, rateLimitCounter, rule);
                        //}
                        // RequestBlocked?.Invoke(identity, rateLimitCounter, rule);
                        if (RequestBlocked != null)
                        {
                            RequestBlocked.Invoke(this, new EventRequestBlockedArgs()
                            {
                                identity = identity, rateLimitCounter = rateLimitCounter, rateLimitRule = rule
                            });
                        }
                        //// break execution
                        ReturnQuotaExceededResponse(e, rule, retryAfter).Wait();


                        return;
                    }
                }
                // if limit is zero or less, block the request.
                else
                {
                    //// log blocked request
                    //LogBlockedRequest(context, identity, rateLimitCounter, rule);

                    //if (_options.RequestBlockedBehavior != null)
                    //{
                    //    await _options.RequestBlockedBehavior(context, identity, rateLimitCounter, rule);
                    //}
                    if (RequestBlocked != null)
                    {
                        RequestBlocked.Invoke(this, new EventRequestBlockedArgs()
                        {
                            identity = identity, rateLimitCounter = rateLimitCounter, rateLimitRule = rule
                        });
                    }



                    //// break execution (Int32 max used to represent infinity)
                    await ReturnQuotaExceededResponse(e, rule, int.MaxValue.ToString(System.Globalization.CultureInfo.InvariantCulture));

                    return;
                }

                rulesDict.Add(rule, rateLimitCounter);
            }

            // set X-Rate-Limit headers for the longest period
            if (rulesDict.Any() && !_options.DisableRateLimitHeaders)
            {
                var rule    = rulesDict.OrderByDescending(x => x.Key.PeriodTimespan).FirstOrDefault();
                var headers = _processor.GetRateLimitHeaders(rule.Value, rule.Key);

                //  headers.Context = context;

                // context.Response.OnStarting(SetRateLimitHeaders, state: headers);
                await SetRateLimitHeaders(e, headers);
            }

            if (rulesDict.Any())
            {
                //Requested?.Invoke(identity, rulesDict);
                if (Requested != null)
                {
                    Requested.Invoke(this, new EventRequestedArgs()
                    {
                        identity = identity, rules = rulesDict
                    });
                }
            }

            await Task.CompletedTask;
        }
 public void Execute(EventRequestingArgs e)
 {
     e.Cancel     = true;
     e.ResultType = 0;
 }
Example #8
0
 public void Execute(EventRequestingArgs e)
 {
     //e.Gateway.Response(e.Response, new NotFoundResult("Gateway not found!"));
     //e.Cancel = true;
     Console.WriteLine($"{e.Request.Url} requesting");
 }
Example #9
0
 public void Execute(EventRequestingArgs e)
 {
     e.Gateway.Response(e.Response, new NotFoundResult("Gateway not found!"));
     e.Cancel = true;
 }