generated from shgysk8zer0/npm-template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrate-limit.js
More file actions
42 lines (36 loc) · 976 Bytes
/
rate-limit.js
File metadata and controls
42 lines (36 loc) · 976 Bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { HTTPError } from './HTTPError.js';
/**
*
* @param {object} options
* @param {number} [options.timeout=6000]
* @param {number} [options.maxRequests=9]
* @returns {Function}
*/
export function useRateLimit({ timeout = 60_000, maxRequests = 60 } = {}) {
const reqs = new Map();
setInterval(() => {
const threshold = Date.now() - timeout;
reqs.entries().forEach(([ip, times]) => {
const updated = times.filter(time => time > threshold);
if (updated.length === 0) {
reqs.delete(ip);
} else {
reqs.set(ip, times.filter(time => time > threshold));
}
});
}, timeout);
return function(req, { controller, ip }) {
if (! reqs.has(ip)) {
reqs.set(ip, [Date.now()]);
} else {
const times = reqs.get(ip);
times.push(Date.now());
if (times.length > maxRequests) {
controller.abort(new HTTPError('Too many requests', {
status: 429,
headers: { 'Retry-After': Math.round(timeout / 1000) },
}));
}
}
};
}