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" />
paket add RequestRateLimiter --version 1.0.0
#r "nuget: RequestRateLimiter, 1.0.0"
// Install RequestRateLimiter as a Cake Addin #addin nuget:?package=RequestRateLimiter&version=1.0.0 // Install RequestRateLimiter as a Cake Tool #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 1
day 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-route
to3
requests per10
seconds - Limit
/some-other-route
to15
request per30
seconds - Limit every other route to
10
requests per1
minute
"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
- aFunc
that gets executed whenever a client breaks any other rate limit. By default it sets theHttpContext.Response.StatusCode
to429
with the message"Too many requests."
public Func<HttpContext, Task<string>> GetClientKeyFunc
- aFunc
that returns a string indicating a unique client. By default the middleware takesHttpContext.Connection.RemoteIpAddress
as 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
- aFunc
that determines if theHttpContext
matches the requirements. By default it checks ifHttpContext.Request.Path
matches the specified route.Func<HttpContext, Task> limitBreakHandler
- aFunc
that gets executed whenever a client breaks the specified routes rate limit. By default it sets theHttpContext.Response.StatusCode
to429
with 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
5
requests per10
minutes
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
10
requests per50
seconds
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-route
will be limited to2
requests per30
seconds - Requests to other endpoints will be limited to
5
requests per10
seconds
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-route
will be limited to2
requests per30
seconds - If the client exceeds the rate limit for
/some-route
they will receive an HTTP status code400
- Requests to other endpoints will be limited to
5
requests per10
seconds
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
test
will be limited to5
requests per1
hour - Requests to other routes are limited to
20
requests per1
day 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. |
.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 | 227 | 3/28/2022 |