public bool IsWhitelisted(ClientRequestIdentity requestIdentity, RateLimitOptions option) { if (option.ClientWhitelist.Contains(requestIdentity.ClientId)) { return(true); } return(false); }
private string GetResponseMessage(RateLimitOptions option) { var message = string.IsNullOrEmpty(option.QuotaExceededMessage) ? $"API calls quota exceeded! maximum admitted {option.RateLimitRule.Limit} per {option.RateLimitRule.Period}." : option.QuotaExceededMessage; return(message); }
public void SaveRateLimitCounter(ClientRequestIdentity requestIdentity, RateLimitOptions option, RateLimitCounter counter, TimeSpan expirationTime) { var counterId = ComputeCounterKey(requestIdentity, option); var rule = option.RateLimitRule; // stores: id (string) - timestamp (datetime) - total_requests (long) _counterHandler.Set(counterId, counter, expirationTime); }
public IRateManager Create(string name, RateLimitOptions options) { return(_cache.GetOrAdd(name, key => { var store = _serviceProvider.GetRequiredService <IRateStore>(); IRateManager manager = new RateManager(name, options, store); return manager; })); }
public ClientRateLimitMiddleware(RequestDelegate next, RateLimitOptions options, RateLimitProcessor processor ) { _next = next; _options = options; _processor = processor; }
private void GivenTheRloCreatorReturns() { _rlo1 = new RateLimitOptionsBuilder().Build(); _rlo2 = new RateLimitOptionsBuilder().WithEnableRateLimiting(true).Build(); _rloCreator .SetupSequence(x => x.Create(It.IsAny <FileRateLimitRule>(), It.IsAny <FileGlobalConfiguration>())) .Returns(_rlo1) .Returns(_rlo2); }
protected RateLimitMiddleware( RequestDelegate next, RateLimitOptions options, TProcessor processor, IRateLimitConfiguration config) { _next = next; _options = options; _processor = processor; _config = config; }
protected RateLimitProcessor( RateLimitOptions options, IRateLimitCounterStore counterStore, ICounterKeyBuilder counterKeyBuilder, IRateLimitConfiguration config) { _options = options; _counterStore = counterStore; _counterKeyBuilder = counterKeyBuilder; _config = config; }
protected RateLimitProcessor( ICacheManager cacheManager, RateLimitOptions options, ICounterKeyBuilder counterKeyBuilder, IRateLimitConfiguration config) { _cacheManager = cacheManager; _options = options; _counterKeyBuilder = counterKeyBuilder; _config = config; }
public virtual Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitOptions option, string retryAfter) { var message = this.GetResponseMessage(option); if (!option.DisableRateLimitHeaders) { httpContext.Response.Headers["Retry-After"] = retryAfter; } httpContext.Response.StatusCode = option.HttpStatusCode; return(httpContext.Response.WriteAsync(message)); }
public virtual Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitOptions option, string retryAfter) { var message = string.IsNullOrEmpty(option.QuotaExceededMessage) ? $"API calls quota exceeded! maximum admitted {option.RateLimitRule.Limit} per {option.RateLimitRule.Period}." : option.QuotaExceededMessage; if (!option.DisableRateLimitHeaders) { httpContext.Response.Headers["Retry-After"] = retryAfter; } httpContext.Response.StatusCode = option.HttpStatusCode; return(httpContext.Response.WriteAsync(message)); }
public static Task <string> ResolveClientAsync(HttpContext httpContext, RateLimitOptions options) { string clientId = null; string _headerName = options.ClientIdHeader; if (httpContext.Request.Headers.TryGetValue(_headerName, out var values)) { clientId = values.First(); } return(Task.FromResult(clientId)); }
private void ThenTheFollowingIsReturned(RateLimitOptions expected) { _result.ClientIdHeader.ShouldBe(expected.ClientIdHeader); _result.ClientWhitelist.ShouldBe(expected.ClientWhitelist); _result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders); _result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting); _result.HttpStatusCode.ShouldBe(expected.HttpStatusCode); _result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage); _result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix); _result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit); _result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period); TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks); }
public RateLimitsViewModel(RateLimitOptions model, INotifiableEventPublisher eventPublisher) { this.model = model; if (this.model.PerUser == null) { this.model.PerUser = new RateLimitThresholds(); } if (this.model.PerIP == null) { this.model.PerIP = new RateLimitThresholds(); } eventPublisher.Register(this); }
public string ComputeCounterKey(ClientRequestIdentity requestIdentity, RateLimitOptions option) { var key = $"{option.RateLimitCounterPrefix}_{requestIdentity.ClientId}_{option.RateLimitRule.Period}_{requestIdentity.HttpVerb}_{requestIdentity.Path}"; var idBytes = Encoding.UTF8.GetBytes(key); byte[] hashBytes; using (var algorithm = SHA1.Create()) { hashBytes = algorithm.ComputeHash(idBytes); } return(BitConverter.ToString(hashBytes).Replace("-", string.Empty)); }
public virtual ClientRequestIdentity SetIdentity(HttpContext httpContext, RateLimitOptions option) { var clientId = "client"; if (httpContext.Request.Headers.Keys.Contains(option.ClientIdHeader)) { clientId = httpContext.Request.Headers[option.ClientIdHeader].First(); } return(new ClientRequestIdentity( clientId, httpContext.Request.Path.ToString().ToLowerInvariant(), httpContext.Request.Method.ToLowerInvariant() )); }
private static RateLimitOptions BuildRateLimitOptions(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting) { RateLimitOptions rateLimitOption = null; if (enableRateLimiting) { rateLimitOption = new RateLimitOptions(enableRateLimiting, globalConfiguration.RateLimitOptions.ClientIdHeader, fileReRoute.RateLimitOptions.ClientWhitelist, globalConfiguration.RateLimitOptions.DisableRateLimitHeaders, globalConfiguration.RateLimitOptions.QuotaExceededMessage, globalConfiguration.RateLimitOptions.RateLimitCounterPrefix, new RateLimitRule(fileReRoute.RateLimitOptions.Period, TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan), fileReRoute.RateLimitOptions.Limit) , globalConfiguration.RateLimitOptions.HttpStatusCode); } return(rateLimitOption); }
public RateLimitsViewModel(RateLimitOptions model, INotifyModelChangedEventPublisher eventPublisher, IShellExecuteProvider shellExecuteProvider) { this.shellExecuteProvider = shellExecuteProvider; this.model = model; this.DisplayName = "Rate limits"; if (this.model.PerUser == null) { this.model.PerUser = new RateLimitThresholds(); } if (this.model.PerIP == null) { this.model.PerIP = new RateLimitThresholds(); } eventPublisher.Register(this); }
public NetCoreRateLimit(RateLimitType rateLimitType) { _config = ConfigHelper.GetConfig(); _cache = new MemoryCache(new MemoryCacheOptions()); memoryCacheRateLimitCounterStore = new MemoryCacheRateLimitCounterStore(_cache); memoryCacheIpPolicyStore = new MemoryCacheIpPolicyStore(_cache, _config.IpRateLimitOptions, _config.IpRateLimitPolicies); //添加Policy进内存 memoryCacheIpPolicyStore.SeedAsync().Wait(); memoryCacheClientPolicyStore = new MemoryCacheClientPolicyStore(_cache, _config.ClientRateLimitOptions, _config.ClientRateLimitPolicies); //添加Policy进内存 memoryCacheClientPolicyStore.SeedAsync().Wait(); rateLimitConfiguration = new RateLimitConfiguration(_config.IpRateLimitOptions, _config.ClientRateLimitOptions); switch (rateLimitType) { case RateLimitType.CLIENT_ID: _processor = new ClientRateLimitProcessor(_config.ClientRateLimitOptions , memoryCacheRateLimitCounterStore, memoryCacheClientPolicyStore, rateLimitConfiguration); _options = _config.ClientRateLimitOptions as RateLimitOptions; break; case RateLimitType.IP: _processor = new IpRateLimitProcessor(_config.IpRateLimitOptions , memoryCacheRateLimitCounterStore, memoryCacheIpPolicyStore, rateLimitConfiguration); _options = _config.IpRateLimitOptions as RateLimitOptions; break; default: _processor = new IpRateLimitProcessor(_config.IpRateLimitOptions , memoryCacheRateLimitCounterStore, memoryCacheIpPolicyStore, rateLimitConfiguration); _options = _config.IpRateLimitOptions as RateLimitOptions; break; } }
public RateLimitOptions Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting) { RateLimitOptions rateLimitOption = null; if (enableRateLimiting) { rateLimitOption = new RateLimitOptionsBuilder() .WithClientIdHeader(globalConfiguration.RateLimitOptions.ClientIdHeader) .WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist) .WithDisableRateLimitHeaders(globalConfiguration.RateLimitOptions.DisableRateLimitHeaders) .WithEnableRateLimiting(fileReRoute.RateLimitOptions.EnableRateLimiting) .WithHttpStatusCode(globalConfiguration.RateLimitOptions.HttpStatusCode) .WithQuotaExceededMessage(globalConfiguration.RateLimitOptions.QuotaExceededMessage) .WithRateLimitCounterPrefix(globalConfiguration.RateLimitOptions.RateLimitCounterPrefix) .WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period, TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan), fileReRoute.RateLimitOptions.Limit)) .Build(); } return(rateLimitOption); }
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)); }
public RequestLogMiddleware(RequestDelegate next, IOptions <RateLimitOptions> options) { _next = next; _options = options.Value; }
private void WhenICreate() { _result = _creator.Create(_fileReRoute.RateLimitOptions, _fileGlobalConfig); }
private void WithRateLimitOptions(RateLimitOptions expected) { _result.Data.ReRoute.DownstreamReRoute[0].EnableEndpointEndpointRateLimiting.ShouldBeTrue(); _result.Data.ReRoute.DownstreamReRoute[0].RateLimitOptions.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting); _result.Data.ReRoute.DownstreamReRoute[0].RateLimitOptions.ClientIdHeader.ShouldBe(expected.ClientIdHeader); }
public DownstreamReRouteBuilder WithRateLimitOptions(RateLimitOptions input) { _rateLimitOptions = input; return(this); }
public MySqlPolicyStore(RateLimitOptions options, MySqlOptions mySqlOptions) { _options = options; _mySqlOptions = mySqlOptions; }
public RateLimitHeaders GetRateLimitHeaders(HttpContext context, ClientRequestIdentity requestIdentity, RateLimitOptions option) { var rule = option.RateLimitRule; RateLimitHeaders headers = null; var counterId = ComputeCounterKey(requestIdentity, option); var entry = _counterHandler.Get(counterId); if (entry.HasValue) { headers = new RateLimitHeaders(context, rule.Period, (rule.Limit - entry.Value.TotalRequests).ToString(), (entry.Value.Timestamp + ConvertToTimeSpan(rule.Period)).ToUniversalTime().ToString("o", DateTimeFormatInfo.InvariantInfo) ); } else { headers = new RateLimitHeaders(context, rule.Period, rule.Limit.ToString(), (DateTime.UtcNow + ConvertToTimeSpan(rule.Period)).ToUniversalTime().ToString("o", DateTimeFormatInfo.InvariantInfo)); } return(headers); }
private void WhenICreate() { _result = _creator.Create(_fileReRoute, _fileGlobalConfig, _enabled); }
public SqlCacheRateLimiter(IOptionsSnapshot <RateLimitOptions> rateLimits, IDbProvider dbProvider) { this.rateLimits = rateLimits.Value; this.dbProvider = dbProvider; }
public RateLimiter(IOptionsSnapshot <RateLimitOptions> rateLimits, IMemoryCache memoryCache) { this.rateLimits = rateLimits.Value; this.memoryCache = memoryCache; }