rate-limiter-memory
Version:
Node.js rate limiter by key and protection from DDoS and Brute-Force attacks in process Memory, Redis, MongoDb, Memcached, MySQL, PostgreSQL, Cluster or PM
84 lines (73 loc) • 2.14 kB
JavaScript
const Record = require('./Record');
const RateLimiterRes = require('../../RateLimiterRes');
module.exports = class MemoryStorage {
constructor() {
/**
* @type {Object.<string, Record>}
* @private
*/
this._storage = {};
}
incrby(key, value, durationSec) {
if (this._storage[key]) {
const msBeforeExpires = this._storage[key].expiresAt
? this._storage[key].expiresAt.getTime() - new Date().getTime()
: -1;
if (!this._storage[key].expiresAt || msBeforeExpires > 0) {
// Change value
this._storage[key].value = this._storage[key].value + value;
return new RateLimiterRes(0, msBeforeExpires, this._storage[key].value, false);
}
return this.set(key, value, durationSec);
}
return this.set(key, value, durationSec);
}
set(key, value, durationSec) {
const durationMs = durationSec * 1000;
if (this._storage[key] && this._storage[key].timeoutId) {
clearTimeout(this._storage[key].timeoutId);
}
this._storage[key] = new Record(
value,
durationMs > 0 ? new Date(Date.now() + durationMs) : null
);
if (durationMs > 0) {
this._storage[key].timeoutId = setTimeout(() => {
delete this._storage[key];
}, durationMs);
if (this._storage[key].timeoutId.unref) {
this._storage[key].timeoutId.unref();
}
}
return new RateLimiterRes(0, durationMs === 0 ? -1 : durationMs, this._storage[key].value, true);
}
/**
*
* @param key
* @returns {*}
*/
get(key) {
if (this._storage[key]) {
const msBeforeExpires = this._storage[key].expiresAt
? this._storage[key].expiresAt.getTime() - new Date().getTime()
: -1;
return new RateLimiterRes(0, msBeforeExpires, this._storage[key].value, false);
}
return null;
}
/**
*
* @param key
* @returns {boolean}
*/
delete(key) {
if (this._storage[key]) {
if (this._storage[key].timeoutId) {
clearTimeout(this._storage[key].timeoutId);
}
delete this._storage[key];
return true;
}
return false;
}
};