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}"); } } }
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); }
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); }
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); }
public void Execute(EventRequestingArgs e) { netCoreRateLimit.Invoke(e).GetAwaiter().GetResult(); }
/// <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; }
public void Execute(EventRequestingArgs e) { //e.Gateway.Response(e.Response, new NotFoundResult("Gateway not found!")); //e.Cancel = true; Console.WriteLine($"{e.Request.Url} requesting"); }
public void Execute(EventRequestingArgs e) { e.Gateway.Response(e.Response, new NotFoundResult("Gateway not found!")); e.Cancel = true; }