49 lines
1.8 KiB
JavaScript
Executable file
49 lines
1.8 KiB
JavaScript
Executable file
class RateLimiter {
|
|
constructor({ windowMs, maxRequests }) {
|
|
// windowMs is the time window in milliseconds (e.g., 15 minutes = 15 * 60 * 1000)
|
|
this.windowMs = windowMs;
|
|
// maxRequests is the number of allowed requests in the given window
|
|
this.maxRequests = maxRequests;
|
|
// in-memory store to keep track of requests per client
|
|
this.clients = new Map();
|
|
}
|
|
|
|
// Function to handle a request
|
|
handleRequest(clientId) {
|
|
const currentTime = Date.now();
|
|
|
|
// Check if the client has made requests in the current window
|
|
if (this.clients.has(clientId)) {
|
|
const clientData = this.clients.get(clientId);
|
|
const { requestCount, startTime } = clientData;
|
|
|
|
// If the current time is within the window, check the request count
|
|
if (currentTime - startTime < this.windowMs) {
|
|
if (requestCount >= this.maxRequests) {
|
|
return { allowed: false, remainingTime: (startTime + this.windowMs - currentTime) };
|
|
}
|
|
// If not exceeding the maxRequests, increment the count
|
|
clientData.requestCount += 1;
|
|
this.clients.set(clientId, clientData);
|
|
return { allowed: true, remainingRequests: this.maxRequests - clientData.requestCount };
|
|
}
|
|
}
|
|
|
|
// Reset or start a new window for the client
|
|
this.clients.set(clientId, { requestCount: 1, startTime: currentTime });
|
|
return { allowed: true, remainingRequests: this.maxRequests - 1 };
|
|
}
|
|
|
|
// Function to clear expired clients from the store (optional for memory optimization)
|
|
clearExpiredClients() {
|
|
const currentTime = Date.now();
|
|
this.clients.forEach((clientData, clientId) => {
|
|
if (currentTime - clientData.startTime > this.windowMs) {
|
|
this.clients.delete(clientId);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = RateLimiter;
|