Skip to content

Commit b89fce5

Browse files
authored
Merge pull request #80 from nicolgit/main
Throttling
2 parents 638dfa2 + 381ff1b commit b89fce5

File tree

3 files changed

+91
-33
lines changed

3 files changed

+91
-33
lines changed

firewall-mon-api/backend.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System.Collections.Concurrent;
2+
using System.Net;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.Azure.Functions.Worker;
6+
using Microsoft.Extensions.Logging;
7+
8+
namespace firewallmon.function;
9+
10+
class RequestLog
11+
    {
12+
        public List<DateTime> Requests { get; } = new();
13+
    }
14+
15+
16+
public class Backend
17+
{
18+
private static readonly ConcurrentDictionary<string, RequestLog> IpLogs = new();
19+
20+
private readonly ILogger<Backend> _logger;
21+
22+
private int ThrottlingInterval = int.TryParse(Environment.GetEnvironmentVariable("aiao_throttling_window"), out var interval) ? interval : 0; // minutes
23+
private int ThrottlingRequests = int.TryParse(Environment.GetEnvironmentVariable("aiao_throttling_calls"), out var requests) ? requests : 0; // max requests in the interval
24+
private bool IsThrottlingEnabled => ThrottlingInterval > 0 && ThrottlingRequests > 0;
25+
26+
private bool ImplementThrottling(HttpRequest req)
27+
{
28+
if (!IsThrottlingEnabled)
29+
{
30+
return false;
31+
}
32+
33+
string ip = req.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
34+
35+
var now = DateTime.UtcNow;
36+
var logEntry = IpLogs.GetOrAdd(ip, _ => new RequestLog());
37+
38+
lock (logEntry)
39+
{
40+
logEntry.Requests.RemoveAll(t => (now - t).TotalMinutes > ThrottlingInterval);
41+
42+
int count = logEntry.Requests.Count;
43+
if (count >= ThrottlingRequests)
44+
{
45+
// Log the throttling event
46+
_logger.LogError($"Throttling request from IP: {ip}");
47+
return true;
48+
}
49+
else
50+
{
51+
_logger.LogInformation($"Request {count} from IP {ip}.");
52+
}
53+
54+
logEntry.Requests.Add(now);
55+
}
56+
57+
return false;
58+
}
59+
60+
public Backend(ILogger<Backend> logger)
61+
{
62+
_logger = logger;
63+
}
64+
65+
[Function("helloWorld")]
66+
public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
67+
{
68+
if (ImplementThrottling(req))
69+
{
70+
return new ContentResult
71+
{
72+
StatusCode = StatusCodes.Status429TooManyRequests,
73+
Content = "Too many requests. Please try again later."
74+
};
75+
}
76+
77+
        string? author = "";
78+
79+
author = Environment.GetEnvironmentVariable("author");
80+
        if (string.IsNullOrEmpty(author))
81+
        {
82+
            author = "unknown";
83+
}
84+
85+
return new OkObjectResult($"Hello from the other side... of the endpoint.\r\nbackend owned by {author}.\r\n");
86+
}
87+
}

firewall-mon-api/helloWorld.cs

Lines changed: 0 additions & 31 deletions
This file was deleted.

firewall-mon-api/local.settings.json.sample

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"Values": {
44
"AzureWebJobsStorage": "",
55
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
6-
"author" : "john john"
6+
"author" : "john john",
7+
"aiao_throttling_window" : "10",
8+
"aiao_throttling_calls" : "3"
79
}
8-
}
10+
}

0 commit comments

Comments
 (0)