This commit was merged in pull request #28.
This commit is contained in:
@@ -11,21 +11,21 @@ const RATE_LIMIT_WINDOW_MS = 60 * 60 * 1000;
|
||||
|
||||
const ipHits = new Map<string, { count: number; resetAt: number }>();
|
||||
|
||||
function checkRateLimit(ip: string): { allowed: boolean; resetAt: number } {
|
||||
function checkRateLimit(ip: string): { allowed: boolean; resetAt: number; remaining: number } {
|
||||
const now = Date.now();
|
||||
const entry = ipHits.get(ip);
|
||||
|
||||
if (!entry || now >= entry.resetAt) {
|
||||
ipHits.set(ip, { count: 1, resetAt: now + RATE_LIMIT_WINDOW_MS });
|
||||
return { allowed: true, resetAt: now + RATE_LIMIT_WINDOW_MS };
|
||||
return { allowed: true, resetAt: now + RATE_LIMIT_WINDOW_MS, remaining: RATE_LIMIT_MAX - 1 };
|
||||
}
|
||||
|
||||
if (entry.count >= RATE_LIMIT_MAX) {
|
||||
return { allowed: false, resetAt: entry.resetAt };
|
||||
return { allowed: false, resetAt: entry.resetAt, remaining: 0 };
|
||||
}
|
||||
|
||||
entry.count += 1;
|
||||
return { allowed: true, resetAt: entry.resetAt };
|
||||
return { allowed: true, resetAt: entry.resetAt, remaining: RATE_LIMIT_MAX - entry.count };
|
||||
}
|
||||
|
||||
router.get("/demo", async (req: Request, res: Response) => {
|
||||
@@ -34,7 +34,12 @@ router.get("/demo", async (req: Request, res: Response) => {
|
||||
req.socket.remoteAddress ??
|
||||
"unknown";
|
||||
|
||||
const { allowed, resetAt } = checkRateLimit(ip);
|
||||
const { allowed, resetAt, remaining } = checkRateLimit(ip);
|
||||
|
||||
res.setHeader("X-RateLimit-Limit", String(RATE_LIMIT_MAX));
|
||||
res.setHeader("X-RateLimit-Remaining", String(remaining));
|
||||
res.setHeader("X-RateLimit-Reset", String(Math.floor(resetAt / 1000)));
|
||||
|
||||
if (!allowed) {
|
||||
const secsUntilReset = Math.ceil((resetAt - Date.now()) / 1000);
|
||||
logger.warn("demo rate limited", { ip, retry_after_s: secsUntilReset });
|
||||
|
||||
Reference in New Issue
Block a user