redis-rate-limiter
Advanced tools
Comparing version 1.0.4 to 1.0.5
var assert = require('assert'); | ||
var moment = require('moment'); | ||
exports.canonical = function(opts) { | ||
var getMatches = function(opts){ | ||
return getRate(opts).match(/^(\d+)\s*\/\s*([a-z]+)$/); | ||
}; | ||
var canon = {}; | ||
var keyShorthands = { | ||
'ip': function(req) { | ||
return req.connection.remoteAddress; | ||
} | ||
}; | ||
// Redis connection | ||
assert.equal(typeof opts.redis, 'object', 'Invalid redis client'); | ||
canon.redis = opts.redis; | ||
var getRate = function(opts){ | ||
if(typeof opts.rate === 'function') return opts.rate(); | ||
return opts.rate; | ||
}; | ||
// Key function | ||
if (typeof opts.key === 'function') canon.key = opts.key; | ||
if (typeof opts.key === 'string') canon.key = keyShorthands[opts.key]; | ||
var getLimit = function(opts){ | ||
if(getRate(opts)) return parseInt(getMatches(opts)[1], 10); | ||
if(typeof opts.limit === 'function') return opts.limit(); | ||
return opts.limit; | ||
}; | ||
// Rate shorthand | ||
if (opts.rate) { | ||
assert.equal(typeof opts.rate, 'string', 'Invalid rate: ' + opts.rate); | ||
var match = opts.rate.match(/^(\d+)\s*\/\s*([a-z]+)$/); | ||
assert.ok(match, 'Invalid rate: ' + opts.rate); | ||
canon.limit = parseInt(match[1], 10); | ||
canon.window = moment.duration(1, match[2]) / 1000; | ||
assert.notEqual(canon.limit, 0, 'Invalid rate limit: ' + opts.rate); | ||
assert.notEqual(canon.window, 0, 'Invalid rate window: ' + opts.rate); | ||
} | ||
var getWindow = function(opts){ | ||
if(getRate(opts)) return moment.duration(1, getMatches(opts)[2]) / 1000; | ||
if(typeof opts.window === 'function') return opts.window(); | ||
return opts.window; | ||
}; | ||
// Limit + window | ||
if (opts.limit) canon.limit = opts.limit; | ||
if (opts.window) canon.window = opts.window; | ||
var getKey = function(opts){ | ||
if(typeof opts.key === 'function') return opts.key; | ||
return keyShorthands[opts.key]; | ||
}; | ||
// Check option types | ||
assert.equal(typeof canon.key, 'function', 'Invalid key: ' + opts.key); | ||
assert.equal(typeof canon.limit, 'number', 'Invalid limit: ' + canon.limit); | ||
assert.equal(typeof canon.window, 'number', 'Invalid window: ' + canon.window); | ||
var validate = function(opts){ | ||
assert.equal(typeof opts.redis, 'object', 'Invalid redis client'); | ||
assert.equal(typeof getKey(opts), 'function', 'Invalid key: ' + opts.key); | ||
if(opts.rate) assert.ok(getMatches(opts), 'Invalid rate: ' + getRate(opts)); | ||
assert.equal(typeof getLimit(opts), 'number', 'Invalid limit: ' + getLimit(opts)); | ||
assert.equal(typeof getWindow(opts), 'number', 'Invalid window: ' + getWindow(opts)); | ||
assert.notEqual(getLimit(opts), 0, 'Invalid rate limit: ' + getRate(opts)); | ||
assert.notEqual(getWindow(opts), 0, 'Invalid rate window: ' + getRate(opts)); | ||
}; | ||
return canon; | ||
canonical = function(opts) { | ||
validate(opts); | ||
return { | ||
redis: opts.redis, | ||
key: getKey(opts), | ||
rate: getRate.bind(null, opts), | ||
limit: getLimit.bind(null, opts), | ||
window: getWindow.bind(null, opts) | ||
}; | ||
}; | ||
var keyShorthands = { | ||
'ip': function(req) { | ||
return req.connection.remoteAddress; | ||
} | ||
module.exports = { | ||
canonical: canonical | ||
}; |
@@ -10,3 +10,3 @@ var options = require('./options'); | ||
opts.redis.multi() | ||
.setex(tempKey, opts.window, 0) | ||
.setex(tempKey, opts.window(), 0) | ||
.renamenx(tempKey, realKey) | ||
@@ -20,3 +20,3 @@ .incr(realKey) | ||
if (results[3] == -1) { // automatically recover from possible race condition | ||
opts.redis.expire(realKey,opts.window); | ||
opts.redis.expire(realKey,opts.window()); | ||
} | ||
@@ -27,5 +27,5 @@ var current = results[2]; | ||
current: current, | ||
limit: opts.limit, | ||
window: opts.window, | ||
over: (current > opts.limit) | ||
limit: opts.limit(), | ||
window: opts.window(), | ||
over: (current > opts.limit()) | ||
}); | ||
@@ -32,0 +32,0 @@ } |
{ | ||
"name": "redis-rate-limiter", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "Rate-limit any operation, backed by Redis", | ||
@@ -14,3 +14,3 @@ "author": "Tabcorp Digital Team", | ||
"dependencies": { | ||
"moment": "~2.14.1" | ||
"moment": "~2.15.0" | ||
}, | ||
@@ -20,3 +20,3 @@ "devDependencies": { | ||
"express": "~4.14.0", | ||
"lodash": "~4.15.0", | ||
"lodash": "~4.16.0", | ||
"mocha": "~3.0.2", | ||
@@ -23,0 +23,0 @@ "redis": "~2.6.0-0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8559
7
101
1
+ Addedmoment@2.15.2(transitive)
- Removedmoment@2.14.1(transitive)
Updatedmoment@~2.15.0