feat(server): add rate limiting
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.Threading.RateLimiting;
|
||||||
|
|
||||||
|
namespace GroundsForSupport.Server.RateLimiting;
|
||||||
|
|
||||||
|
internal static class Extensions
|
||||||
|
{
|
||||||
|
public static void AddRateLimingPolicies(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddRateLimiter(static o =>
|
||||||
|
{
|
||||||
|
o.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
||||||
|
|
||||||
|
o.OnRejected = static (context, ct) =>
|
||||||
|
{
|
||||||
|
var response = context.HttpContext.Response;
|
||||||
|
|
||||||
|
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
|
||||||
|
{
|
||||||
|
response.Headers.RetryAfter = ((int)retryAfter.TotalSeconds).ToString(CultureInfo.InvariantCulture);
|
||||||
|
var resetTime = DateTimeOffset.UtcNow.Add(retryAfter);
|
||||||
|
var unixTimeMilliseconds = resetTime.ToUnixTimeMilliseconds();
|
||||||
|
response.Headers.Append("X-RateLimit-Reset", unixTimeMilliseconds.ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValueTask.CompletedTask;
|
||||||
|
};
|
||||||
|
|
||||||
|
o.AddPolicy(FixedRateLimitPolicy.Name, FixedRateLimitPolicy.Partitioner);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System.Threading.RateLimiting;
|
||||||
|
|
||||||
|
namespace GroundsForSupport.Server.RateLimiting;
|
||||||
|
|
||||||
|
internal static class FixedRateLimitPolicy
|
||||||
|
{
|
||||||
|
public const string Name = "fixed";
|
||||||
|
|
||||||
|
public static Func<HttpContext, RateLimitPartition<string>> Partitioner =>
|
||||||
|
static context => RateLimitPartition.GetFixedWindowLimiter(
|
||||||
|
partitionKey: context.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||||||
|
factory: static partition => new FixedWindowRateLimiterOptions
|
||||||
|
{
|
||||||
|
PermitLimit = 10,
|
||||||
|
Window = TimeSpan.FromHours(1),
|
||||||
|
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
|
||||||
|
QueueLimit = 0
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user