Created
February 5, 2024 10:39
-
-
Save slavaGanzin/e5ef94868588001445558e38d88a2143 to your computer and use it in GitHub Desktop.
basic rate limiter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const requestLimit = new Map(); | |
| const requestLimitWindow = []; | |
| const CLEANUP_INTERVAL = 100; | |
| const TEST_RATE = 5; | |
| const IP_LIMIT = 10; | |
| const getLimitKey = () => { | |
| const now = new Date(); | |
| return `${now.getHours()}:${now.getMinutes()}:${now.getSeconds().toString().padStart(2, '0')}`; | |
| }; | |
| setInterval(() => { | |
| const limitKey = getLimitKey() | |
| for (const i in requestLimitWindow) { | |
| const limit = requestLimitWindow[i] | |
| if (limit['key'] > limitKey) { | |
| return | |
| } | |
| for (const [ip, numberOfRequests] of Object.entries(limit['ips'])) { | |
| requestLimit.set(ip, requestLimit.get(ip) - numberOfRequests); | |
| } | |
| delete requestLimitWindow[i] | |
| } | |
| }, CLEANUP_INTERVAL) | |
| const rateLimiter = (req, res, next) => { | |
| const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | |
| if (requestLimit.get(ip) > IP_LIMIT) return res.send(429); | |
| requestLimit.set(ip, (requestLimit.get(ip) || 0) + 1); | |
| const limitKey = getLimitKey() | |
| let currentWindow = requestLimitWindow[requestLimitWindow.length-1] | |
| if (!currentWindow || currentWindow['key'] != limitKey) { | |
| currentWindow = { | |
| key: limitKey, | |
| ips: {[ip]: 0} | |
| } | |
| requestLimitWindow.push(currentWindow) | |
| } | |
| currentWindow.ips[ip] += 1 | |
| next() | |
| } | |
| // app.use(rateLimiter) | |
| // FOR TEST | |
| setInterval(() => { | |
| rateLimiter({headers: {}, connection: {remoteAddress: '127.0.0.1'}}, {send: console.log}, m => console.log('next'+(m||''))) | |
| }, TEST_RATE) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment