mirror of
https://github.com/scratchfoundation/node-redis-rate-limiter.git
synced 2025-07-02 20:40:19 -04:00
Add ability to change the return status
This commit is contained in:
parent
9ee41e205d
commit
dec627b691
4 changed files with 607 additions and 964 deletions
19
README.md
19
README.md
|
@ -1,12 +1,7 @@
|
||||||
# redis-rate-limiter
|
# node-redis-rate-limiter
|
||||||
|
|
||||||
[](https://npmjs.org/package/redis-rate-limiter)
|
Forked from [](https://github.com/Tabcorp/redis-rate-limiter)
|
||||||
[](https://github.com/Tabcorp/redis-rate-limiter)
|
[](https://github.com/scratchfoundation/node-redis-rate-limiter)
|
||||||
|
|
||||||
[](http://travis-ci.org/Tabcorp/redis-rate-limiter)
|
|
||||||
[](https://david-dm.org/Tabcorp/redis-rate-limiter)
|
|
||||||
[](https://david-dm.org/Tabcorp/redis-rate-limiter)
|
|
||||||
[](https://snyk.io/package/npm/redis-rate-limiter)
|
|
||||||
|
|
||||||
Rate-limit any operation, backed by Redis.
|
Rate-limit any operation, backed by Redis.
|
||||||
|
|
||||||
|
@ -14,6 +9,7 @@ Rate-limit any operation, backed by Redis.
|
||||||
- But uses a fixed-window algorithm
|
- But uses a fixed-window algorithm
|
||||||
- Great performance (>10000 checks/sec on local redis)
|
- Great performance (>10000 checks/sec on local redis)
|
||||||
- No race conditions
|
- No race conditions
|
||||||
|
- Configuration of status return to avoid giving away the game with a 429, when appropriate
|
||||||
|
|
||||||
Very easy to plug into `Express` or `Restify` to rate limit your `Node.js` API.
|
Very easy to plug into `Express` or `Restify` to rate limit your `Node.js` API.
|
||||||
|
|
||||||
|
@ -29,7 +25,7 @@ var client = redis.createClient(6379, 'localhost', {enable_offline_queue: false}
|
||||||
Step 2: create your rate limiter
|
Step 2: create your rate limiter
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var rateLimiter = require('redis-rate-limiter');
|
var rateLimiter = require('node-redis-rate-limiter');
|
||||||
var limit = rateLimiter.create({
|
var limit = rateLimiter.create({
|
||||||
redis: client,
|
redis: client,
|
||||||
key: function(x) { return x.id },
|
key: function(x) { return x.id },
|
||||||
|
@ -144,12 +140,13 @@ which takes the same options
|
||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var rateLimiter = require('redis-rate-limiter');
|
var rateLimiter = require('node-redis-rate-limiter');
|
||||||
|
|
||||||
var middleware = rateLimiter.middleware({
|
var middleware = rateLimiter.middleware({
|
||||||
redis: client,
|
redis: client,
|
||||||
key: 'ip',
|
key: 'ip',
|
||||||
rate: '100/minute'
|
rate: '100/minute',
|
||||||
|
status: 200
|
||||||
});
|
});
|
||||||
|
|
||||||
server.use(middleware);
|
server.use(middleware);
|
||||||
|
|
|
@ -28,6 +28,14 @@ var getWindow = function(opts){
|
||||||
return opts.window;
|
return opts.window;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var getStatus = function(opts){
|
||||||
|
if ("status" in opts) {
|
||||||
|
return opts.status;
|
||||||
|
} else {
|
||||||
|
return 429;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var getKey = function(opts){
|
var getKey = function(opts){
|
||||||
if(typeof opts.key === 'function') return opts.key;
|
if(typeof opts.key === 'function') return opts.key;
|
||||||
return keyShorthands[opts.key];
|
return keyShorthands[opts.key];
|
||||||
|
@ -41,6 +49,11 @@ var validate = function(opts){
|
||||||
assert.equal(typeof getWindow(opts), 'number', 'Invalid window: ' + getWindow(opts));
|
assert.equal(typeof getWindow(opts), 'number', 'Invalid window: ' + getWindow(opts));
|
||||||
assert.notEqual(getLimit(opts), 0, 'Invalid rate limit: ' + getRate(opts));
|
assert.notEqual(getLimit(opts), 0, 'Invalid rate limit: ' + getRate(opts));
|
||||||
assert.notEqual(getWindow(opts), 0, 'Invalid rate window: ' + getRate(opts));
|
assert.notEqual(getWindow(opts), 0, 'Invalid rate window: ' + getRate(opts));
|
||||||
|
assert.equal(typeof getSTatus(opts), 'number', 'Invalid status response code: ' + getStatus(opts));
|
||||||
|
assert.equal(getSTatus(opts), 'number', 'Invalid status response code: ' + getStatus(opts));
|
||||||
|
var validStatuses = new Set([200,429]);
|
||||||
|
assert.ok(validStatuses.has(getStatus(opts)),
|
||||||
|
'Invalid status response code, must one of ' + validStatuses + ' found ' + getStatus(opts));
|
||||||
};
|
};
|
||||||
|
|
||||||
canonical = function(opts) {
|
canonical = function(opts) {
|
||||||
|
@ -51,6 +64,7 @@ canonical = function(opts) {
|
||||||
rate: getRate.bind(null, opts),
|
rate: getRate.bind(null, opts),
|
||||||
limit: getLimit.bind(null, opts),
|
limit: getLimit.bind(null, opts),
|
||||||
window: getWindow.bind(null, opts),
|
window: getWindow.bind(null, opts),
|
||||||
|
status: getStatus.bind(null, opts),
|
||||||
deleteImmediatelyIfRaceCondition: opts.deleteImmediatelyIfRaceCondition,
|
deleteImmediatelyIfRaceCondition: opts.deleteImmediatelyIfRaceCondition,
|
||||||
onPossibleRaceCondition: opts.onPossibleRaceCondition
|
onPossibleRaceCondition: opts.onPossibleRaceCondition
|
||||||
};
|
};
|
||||||
|
|
1530
package-lock.json
generated
1530
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "redis-rate-limiter",
|
"name": "node-redis-rate-limiter",
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"description": "Rate-limit any operation, backed by Redis",
|
"description": "Rate-limit any operation, backed by Redis",
|
||||||
"author": "Tabcorp Digital Team",
|
"author": "Scratch Foundation",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"repository": "Tabcorp/redis-rate-limiter",
|
"repository": "scratchfoundation/node-redis-rate-limiter",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "require-lint",
|
"lint": "require-lint",
|
||||||
"test": "mocha"
|
"test": "mocha"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue