api: add support for redis to ratelimiter cache

This commit is contained in:
jj
2024-11-01 13:26:18 +00:00
parent d466f8a4af
commit 2317da5ba5
4 changed files with 39 additions and 1 deletions

View File

@ -46,6 +46,7 @@
},
"optionalDependencies": {
"freebind": "^0.2.2",
"rate-limit-redis": "^4.2.0",
"redis": "^4.7.0"
}
}

View File

@ -12,6 +12,7 @@ import { env, setTunnelPort } from "../config.js";
import { extract } from "../processing/url.js";
import { Green, Bright, Cyan } from "../misc/console-text.js";
import { hashHmac } from "../security/secrets.js";
import { createStore } from "../store/redis-ratelimit.js";
import { randomizeCiphers } from "../misc/randomize-ciphers.js";
import { verifyTurnstileToken } from "../security/turnstile.js";
import { friendlyServiceName } from "../processing/service-alias.js";
@ -40,7 +41,7 @@ const fail = (res, code, context) => {
res.status(status).json(body);
}
export const runAPI = (express, app, __dirname, isPrimary = true) => {
export const runAPI = async (express, app, __dirname, isPrimary = true) => {
const startTime = new Date();
const startTimestamp = startTime.getTime();
@ -76,6 +77,7 @@ export const runAPI = (express, app, __dirname, isPrimary = true) => {
standardHeaders: 'draft-6',
legacyHeaders: false,
keyGenerator,
store: await createStore('session'),
handler: handleRateExceeded
});
@ -85,6 +87,7 @@ export const runAPI = (express, app, __dirname, isPrimary = true) => {
standardHeaders: 'draft-6',
legacyHeaders: false,
keyGenerator: req => req.rateLimitKey || keyGenerator(req),
store: await createStore('api'),
handler: handleRateExceeded
})
@ -94,6 +97,7 @@ export const runAPI = (express, app, __dirname, isPrimary = true) => {
standardHeaders: 'draft-6',
legacyHeaders: false,
keyGenerator: req => req.rateLimitKey || keyGenerator(req),
store: await createStore('tunnel'),
handler: (_, res) => {
return res.sendStatus(429)
}

View File

@ -0,0 +1,19 @@
import { env } from "../config.js";
let client, redis, redisLimiter;
export const createStore = async (name) => {
if (!env.redisURL) return;
if (!client) {
redis = await import('redis');
redisLimiter = await import('rate-limit-redis');
client = redis.createClient({ url: env.redisURL });
await client.connect();
}
return new redisLimiter.default({
prefix: `RL${name}_`,
sendCommand: (...args) => client.sendCommand(args),
});
}