adjust signalR limit filter to include connection handling

This commit is contained in:
Stanley Dimant
2022-08-03 23:56:03 +02:00
parent 74efb5eb6a
commit 2170eb127e

View File

@@ -1,6 +1,7 @@
using AspNetCoreRateLimit; using AspNetCoreRateLimit;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -10,12 +11,14 @@ public class SignalRLimitFilter : IHubFilter
{ {
private readonly IRateLimitProcessor _processor; private readonly IRateLimitProcessor _processor;
private readonly IHttpContextAccessor accessor; private readonly IHttpContextAccessor accessor;
private readonly ILogger<SignalRLimitFilter> logger;
public SignalRLimitFilter( public SignalRLimitFilter(
IOptions<IpRateLimitOptions> options, IProcessingStrategy processing, IIpPolicyStore policyStore, IHttpContextAccessor accessor) IOptions<IpRateLimitOptions> options, IProcessingStrategy processing, IIpPolicyStore policyStore, IHttpContextAccessor accessor, ILogger<SignalRLimitFilter> logger)
{ {
_processor = new IpRateLimitProcessor(options?.Value, policyStore, processing); _processor = new IpRateLimitProcessor(options?.Value, policyStore, processing);
this.accessor = accessor; this.accessor = accessor;
this.logger = logger;
} }
public async ValueTask<object> InvokeMethodAsync( public async ValueTask<object> InvokeMethodAsync(
@@ -32,15 +35,15 @@ public class SignalRLimitFilter : IHubFilter
foreach (var rule in await _processor.GetMatchingRulesAsync(client)) foreach (var rule in await _processor.GetMatchingRulesAsync(client))
{ {
var counter = await _processor.ProcessRequestAsync(client, rule); var counter = await _processor.ProcessRequestAsync(client, rule);
Console.WriteLine("time: {0}, count: {1}", counter.Timestamp, counter.Count);
if (counter.Count > rule.Limit) if (counter.Count > rule.Limit)
{ {
var retry = counter.Timestamp.RetryAfterFrom(rule); var retry = counter.Timestamp.RetryAfterFrom(rule);
logger.LogWarning($"Method rate limit triggered from {ip}: {invocationContext.HubMethodName}");
throw new HubException($"call limit {retry}"); throw new HubException($"call limit {retry}");
} }
} }
Console.WriteLine($"Calling hub method '{invocationContext.HubMethodName}'"); //Console.WriteLine($"Calling hub method '{invocationContext.HubMethodName}'");
return await next(invocationContext); return await next(invocationContext);
} }
@@ -57,11 +60,11 @@ public class SignalRLimitFilter : IHubFilter
foreach (var rule in await _processor.GetMatchingRulesAsync(client)) foreach (var rule in await _processor.GetMatchingRulesAsync(client))
{ {
var counter = await _processor.ProcessRequestAsync(client, rule); var counter = await _processor.ProcessRequestAsync(client, rule);
Console.WriteLine("time: {0}, count: {1}", counter.Timestamp, counter.Count);
if (counter.Count > rule.Limit) if (counter.Count > rule.Limit)
{ {
var retry = counter.Timestamp.RetryAfterFrom(rule); var retry = counter.Timestamp.RetryAfterFrom(rule);
throw new HubException($"rate limit {retry}"); logger.LogWarning($"Connection rate limit triggered from {ip}");
throw new HubException($"Connection rate limit {retry}");
} }
} }