RequestRateLimiter 1.0.0
dotnet add package RequestRateLimiter --version 1.0.0
NuGet\Install-Package RequestRateLimiter -Version 1.0.0
<PackageReference Include="RequestRateLimiter" Version="1.0.0" />
<PackageVersion Include="RequestRateLimiter" Version="1.0.0" />
<PackageReference Include="RequestRateLimiter" />
paket add RequestRateLimiter --version 1.0.0
#r "nuget: RequestRateLimiter, 1.0.0"
#:package RequestRateLimiter@1.0.0
#addin nuget:?package=RequestRateLimiter&version=1.0.0
#tool nuget:?package=RequestRateLimiter&version=1.0.0
RequestRateLimiter
This is an ASP.NET Core middleware that allows configuring request rate limitations on your web application.
Request limits can be configured per route and/or per IP.
Requests statistics is stored in-memory, keep this in mind when scaling the app.
This rate limiter is using a circular buffer to keep track of the request rate per configured period.
Setup
The easiest way to set up this middleware is to use ConfigureRequestRateLimiter() in ConfigureServices() in Startup.cs.
In the example below we configure the rate limiter to allow 20 requests per 1day for every endpoint.
services.ConfigureRequestRateLimiter(config =>
{
config.GlobalLimitPeriod = TimeSpan.FromDays(1);
config.GlobalRequestLimit = 20;
});
Add UseRequestRateLimiter() in Startup.cs Configure() method to register the middleware. Pay attention to the order of middlewares in Configure(), RequestRateLimiter should be registered as early as possible to prevent execution of other middlewares when limits are reached.
app.UseRequestRateLimiter();
Configuration
This middleware can be configured via appsettings.json and/or with the ConfigureRequestRateLimiter() method.
Configuring with appsettings.json
To configure the rate limiter via appsettings.json use the following:
services.ConfigureRequestRateLimiter(IConfiguration);
Or if you want to also use the configuration from the code at the same time consider using the following:
services.ConfigureRequestRateLimiter(IConfiguration, Action<RequestRateLimiterConfiguration>);
IsEnabled - enables/disables the middleware.
GlobalRequestLimit - a maximum request count for every endpoint. When the configured number is exceeded, the middelware returns a configured response and prevents execution of further middlewares.
GlobalLimitPeriod - sets a timespan for checking request rates for every endpoint.
LimitRules - an array of rules for specific endpoints. A rule in this array has these parameters:
Route- specifies the route for which the rule is being applied to.RequestLimit- a maximum request count per configured period for the specified endpoint. When the configured number is exceeded, the middelware returns a configured response and prevents execution of further middlewares.LimitPeriod- sets a timespan for checking request rates for the specified endpoint.
Examples:
In the example below we have configured the middleware to:
- Limit
/some-routeto3requests per10seconds - Limit
/some-other-routeto15request per30seconds - Limit every other route to
10requests per1minute
"RequestRateLimiter": {
"IsEnabled": true,
"GlobalRequestLimit": 10,
"GlobalLimitPeriod": "00:01:00",
"LimitRules": [
{
"RequestLimit": 3,
"LimitPeriod": "00:00:10",
"Route": "/some-route"
},
{
"RequestLimit": 15,
"LimitPeriod": "00:00:30",
"Route": "/some-other-route"
}
]
}
Configuring with ConfigureRequestRateLimiter()
ConfigureRequestRateLimiter() method has several overloads for a more flexible configuration.
Configure the middleware using IConfiguration:
services.ConfigureRequestRateLimiter(IConfiguration);
Configure the middleware using Action<RequestRateLimiterConfiguration>:
services.ConfigureRequestRateLimiter(Action<RequestRateLimiterConfiguration>);
Configure the middleware using both IConfiguration and Action<RequestRateLimiterConfiguration>:
services.ConfigureRequestRateLimiter(IConfiguration, Action<RequestRateLimiterConfiguration>);
Using Action<RequestRateLimiterConfiguration>:
Using Action<RequestRateLimiterConfiguration> enables configuration in the code rather than using appsettings.json. It contains the same configurable properties with some additions:
bool IsEnabled- enables/disables the middleware.int GlobalRequestLimit- a maximum request count for every endpoint. When the configured number is exceeded, the middelware returns a configured response and prevents execution of further middlewares.TimeSpan GlobalLimitPeriod- sets a timespan for checking request rates for every endpoint.Func<HttpContext, Task> GlobalLimitBreakHandler- aFuncthat gets executed whenever a client breaks any other rate limit. By default it sets theHttpContext.Response.StatusCodeto429with the message"Too many requests."public Func<HttpContext, Task<string>> GetClientKeyFunc- aFuncthat returns a string indicating a unique client. By default the middleware takesHttpContext.Connection.RemoteIpAddressas the client key.IList<LimitRule> LimitRules- a list of rules for specific endpoints. A rule in this list contains these parameters:TimeSpan limiterTimeout- sets a timespan for checking request rates for the specified endpoint.int maxRequests- a maximum request count per configured period for the specified endpoint. When the configured number is exceeded, the middelware returns a configured response and prevents execution of further middlewares.string route- specifies the route for which the rule is being applied to.Func<HttpContext, Task<bool>> contextPreidcate- aFuncthat determines if theHttpContextmatches the requirements. By default it checks ifHttpContext.Request.Pathmatches the specified route.Func<HttpContext, Task> limitBreakHandler- aFuncthat gets executed whenever a client breaks the specified routes rate limit. By default it sets theHttpContext.Response.StatusCodeto429with the message"Too many requests."
Examples:
Setting up global settings:
Overriding RequestRateLimiterConfiguration.GetClientKeyFunc:
services.ConfigureRequestRateLimiter(config =>
{
config.GlobalRequestLimit = 5;
config.GlobalLimitPeriod = TimeSpan.FromMinutes(10);
config.GetClientKeyFunc = context =>
{
return Task.FromResult($"{context.Connection.RemoteIpAddress}-{context.Request.Headers["User-Agent"]}");
};
});
The example above configures the middleware so that:
- A unique client key is considered to be a combination of client IP address and their user agent
- Each client is limited to
5requests per10minutes
Overriding RequestRateLimiterConfiguration.GlobalLimitBreakHandler:
services.ConfigureRequestRateLimiter(config =>
{
config.GlobalRequestLimit = 10;
config.GlobalLimitPeriod = TimeSpan.FromSeconds(50);
config.GlobalLimitBreakHandler = context =>
{
context.Response.StatusCode = 400;
return Task.CompletedTask;
};
});
The example above configures the middleware so that:
- When the global rate limit is exceeded the client receives an HTTP status code
400 - Each client is limited to
10requests per50seconds
Setting up LimitRules:
Setting a rule for a route:
services.ConfigureRequestRateLimiter(config =>
{
config.GlobalRequestLimit = 5;
config.GlobalLimitPeriod = TimeSpan.FromSeconds(10);
config.LimitRules = new List<LimitRule>
{
new LimitRule(TimeSpan.FromSeconds(30), 2, "/some-route")
};
});
The example above configures the middleware so that:
- A client requesting
/some-routewill be limited to2requests per30seconds - Requests to other endpoints will be limited to
5requests per10seconds
Overriding LimitRule.LimitBreakHandler for custom limit break handling:
services.ConfigureRequestRateLimiter(config =>
{
Func<HttpContext, Task> limitBreakHandler = context =>
{
context.Response.StatusCode = 400;
return Task.CompletedTask;
};
config.GlobalRequestLimit = 20;
config.GlobalLimitPeriod = TimeSpan.FromHours(1);
config.LimitRules = new List<LimitRule>
{
new LimitRule(TimeSpan.FromSeconds(30), 2, "/some-route", limitBreakHandler: limitBreakHandler)
};
});
The example above configures the middleware so that:
- A client requesting
/some-routewill be limited to2requests per30seconds - If the client exceeds the rate limit for
/some-routethey will receive an HTTP status code400 - Requests to other endpoints will be limited to
5requests per10seconds
Overriding LimitRule.ConditionPredicate for custom request evaluation:
var conditionPredicate = new Func<HttpContext, Task<bool>> (context =>
{
var headerValue = context.Request.Headers["test"].ToString();
return Task.FromResult(headerValue != "testHeader");
});
services.ConfigureRequestRateLimiter(config =>
{
config.GlobalLimitPeriod = TimeSpan.FromDays(1);
config.GlobalRequestLimit = 20;
config.LimitRules = new List<LimitRule>
{
new (TimeSpan.FromHours(1), 5, null, conditionPredicate)
};
});
The example above configures the middleware so that:
- Any request with a HTTP header named
testwill be limited to5requests per1hour - Requests to other routes are limited to
20requests per1day per client key (IP by default)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.AspNetCore.Http (>= 2.2.2)
- Microsoft.Extensions.Caching.Memory (>= 5.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 5.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 5.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 364 | 3/28/2022 |