From aa3eb3a3c6f8646f8cf166d437c5e9ed85172a3b Mon Sep 17 00:00:00 2001 From: Rashik Hasnat Date: Thu, 30 Mar 2023 22:54:21 +0600 Subject: [PATCH] - Added Redis Rate Limit Configuration. - Added Connection multiplexer Factory Property in Redis Rate Limit COnfiguration. - Added a paramter to AddRedisRateLimiting method so that RedisRateLimitConfiguration Can be supplied. - Using the connection multiplexer from the factory if configured. --- .../RedisProcessingStrategy.cs | 16 ++++++++++++--- .../RedisRateLimitConfiguration.cs | 20 +++++++++++++++++++ .../StartupExtensions.cs | 10 ++++++++-- 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/AspNetCoreRateLimit.Redis/RedisRateLimitConfiguration.cs diff --git a/src/AspNetCoreRateLimit.Redis/RedisProcessingStrategy.cs b/src/AspNetCoreRateLimit.Redis/RedisProcessingStrategy.cs index ff97be59..9ee54a25 100644 --- a/src/AspNetCoreRateLimit.Redis/RedisProcessingStrategy.cs +++ b/src/AspNetCoreRateLimit.Redis/RedisProcessingStrategy.cs @@ -3,6 +3,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Options; namespace AspNetCoreRateLimit.Redis { @@ -12,15 +13,24 @@ public class RedisProcessingStrategy : ProcessingStrategy private readonly IRateLimitConfiguration _config; private readonly ILogger _logger; - public RedisProcessingStrategy(IConnectionMultiplexer connectionMultiplexer, IRateLimitConfiguration config, ILogger logger) + public RedisProcessingStrategy(IConnectionMultiplexer connectionMultiplexer, + IRateLimitConfiguration config, + ILogger logger, + IOptions optionAccessor + ) : base(config) { - _connectionMultiplexer = connectionMultiplexer ?? throw new ArgumentException("IConnectionMultiplexer was null. Ensure StackExchange.Redis was successfully registered"); _config = config; _logger = logger; + var options = optionAccessor?.Value; + _connectionMultiplexer = options?.ConnectionMultiplexerFactory == null + ? connectionMultiplexer ?? throw new ArgumentException( + "IConnectionMultiplexer was null. Ensure StackExchange.Redis was successfully registered") + : options.ConnectionMultiplexerFactory().GetAwaiter().GetResult(); + } - static private readonly LuaScript _atomicIncrement = LuaScript.Prepare("local count = redis.call(\"INCRBYFLOAT\", @key, tonumber(@delta)) local ttl = redis.call(\"TTL\", @key) if ttl == -1 then redis.call(\"EXPIRE\", @key, @timeout) end return count"); + private static readonly LuaScript _atomicIncrement = LuaScript.Prepare("local count = redis.call(\"INCRBYFLOAT\", @key, tonumber(@delta)) local ttl = redis.call(\"TTL\", @key) if ttl == -1 then redis.call(\"EXPIRE\", @key, @timeout) end return count"); public override async Task ProcessRequestAsync(ClientRequestIdentity requestIdentity, RateLimitRule rule, ICounterKeyBuilder counterKeyBuilder, RateLimitOptions rateLimitOptions, CancellationToken cancellationToken = default) { diff --git a/src/AspNetCoreRateLimit.Redis/RedisRateLimitConfiguration.cs b/src/AspNetCoreRateLimit.Redis/RedisRateLimitConfiguration.cs new file mode 100644 index 00000000..4977aafe --- /dev/null +++ b/src/AspNetCoreRateLimit.Redis/RedisRateLimitConfiguration.cs @@ -0,0 +1,20 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using StackExchange.Redis; + +namespace AspNetCoreRateLimit.Redis +{ + /// + /// Configuration options for . + /// + public class RedisRateLimitConfiguration : IOptions + { + /// + /// Gets or sets a delegate to create the ConnectionMultiplexer instance. + /// + public Func> ConnectionMultiplexerFactory { get; set; } + + public RedisRateLimitConfiguration Value => this; + } +} diff --git a/src/AspNetCoreRateLimit.Redis/StartupExtensions.cs b/src/AspNetCoreRateLimit.Redis/StartupExtensions.cs index 65d0e464..e5136b24 100644 --- a/src/AspNetCoreRateLimit.Redis/StartupExtensions.cs +++ b/src/AspNetCoreRateLimit.Redis/StartupExtensions.cs @@ -1,11 +1,17 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using Microsoft.Extensions.DependencyInjection; namespace AspNetCoreRateLimit.Redis { public static class StartupExtensions { - public static IServiceCollection AddRedisRateLimiting(this IServiceCollection services) + public static IServiceCollection AddRedisRateLimiting(this IServiceCollection services, Action setupAction = null) { + services.AddOptions(); + if (setupAction != null) + { + services.Configure(setupAction); + } services.AddDistributedRateLimiting(); return services; }