From b9c909ad40da1e9074d846572d119c5291dba1eb Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Wed, 1 Jun 2016 15:02:11 -0400 Subject: [PATCH 1/2] index: configurable ratelimiter options --- lib/index.js | 11 ++++++++++- test/index.js | 25 +++++++++++++++++++++++++ test/{ratelimeter.js => ratelimiter.js} | 0 3 files changed, 35 insertions(+), 1 deletion(-) rename test/{ratelimeter.js => ratelimiter.js} (100%) diff --git a/lib/index.js b/lib/index.js index 189ff36..5317ba3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -46,6 +46,8 @@ var InsightAPI = function(options) { this.cacheShortSeconds = options.cacheShortSeconds; this.cacheLongSeconds = options.cacheLongSeconds; + this.rateLimiterOptions = options.rateLimiterOptions; + this.blockSummaryCacheSize = options.blockSummaryCacheSize || BlockController.DEFAULT_BLOCKSUMMARY_CACHE_SIZE; this.blockCacheSize = options.blockCacheSize || BlockController.DEFAULT_BLOCK_CACHE_SIZE; @@ -116,12 +118,19 @@ InsightAPI.prototype.getRemoteAddress = function(req) { return req.socket.remoteAddress; }; +InsightAPI.prototype._getRateLimiter = function() { + var rateLimiterOptions = _.isUndefined(this.rateLimiterOptions) ? {} : _.clone(this.rateLimiterOptions); + rateLimiterOptions.node = this.node; + var limiter = new RateLimiter(rateLimiterOptions); + return limiter; +}; + InsightAPI.prototype.setupRoutes = function(app) { var self = this; //Enable rate limiter - var limiter = new RateLimiter({node: this.node}); + var limiter = this._getRateLimiter(); app.use(limiter.middleware()); //Setup logging diff --git a/test/index.js b/test/index.js index 4975877..26e1a76 100644 --- a/test/index.js +++ b/test/index.js @@ -5,6 +5,31 @@ var sinon = require('sinon'); var InsightAPI = require('../lib/index'); describe('Index', function() { + describe('@constructor', function() { + it('will set rate limiter options', function() { + var options = {}; + var node = {}; + var index = new InsightAPI({ + rateLimiterOptions: options, + node: node + }); + index.rateLimiterOptions.should.equal(options); + }); + }); + describe('#_getRateLimiter', function() { + it('will pass options to rate limiter', function() { + var options = { + whitelist: ['127.0.0.1'] + }; + var node = {}; + var index = new InsightAPI({ + rateLimiterOptions: options, + node: node + }); + var limiter = index._getRateLimiter(); + limiter.whitelist.should.eql(['127.0.0.1']); + }); + }); describe('#cache', function() { it('will set cache control header', function(done) { var node = { diff --git a/test/ratelimeter.js b/test/ratelimiter.js similarity index 100% rename from test/ratelimeter.js rename to test/ratelimiter.js From 57e65010f161d0f130e3103e4ac084484f698689 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Tue, 7 Jun 2016 11:02:58 -0400 Subject: [PATCH 2/2] index: add option to disable rate limiter entirely for the case that insight-api is used in an internal network where rate limiting isn't necessary --- lib/index.js | 7 +++++-- test/index.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index 5317ba3..422615f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -47,6 +47,7 @@ var InsightAPI = function(options) { this.cacheLongSeconds = options.cacheLongSeconds; this.rateLimiterOptions = options.rateLimiterOptions; + this.disableRateLimiter = options.disableRateLimiter; this.blockSummaryCacheSize = options.blockSummaryCacheSize || BlockController.DEFAULT_BLOCKSUMMARY_CACHE_SIZE; this.blockCacheSize = options.blockCacheSize || BlockController.DEFAULT_BLOCK_CACHE_SIZE; @@ -130,8 +131,10 @@ InsightAPI.prototype.setupRoutes = function(app) { var self = this; //Enable rate limiter - var limiter = this._getRateLimiter(); - app.use(limiter.middleware()); + if (!this.disableRateLimiter) { + var limiter = this._getRateLimiter(); + app.use(limiter.middleware()); + } //Setup logging morgan.token('remote-forward-addr', function(req){ diff --git a/test/index.js b/test/index.js index 26e1a76..964fe6e 100644 --- a/test/index.js +++ b/test/index.js @@ -15,6 +15,14 @@ describe('Index', function() { }); index.rateLimiterOptions.should.equal(options); }); + it('will set disable rate limiter option', function() { + var node = {}; + var index = new InsightAPI({ + disableRateLimiter: true, + node: node + }); + index.disableRateLimiter.should.equal(true); + }); }); describe('#_getRateLimiter', function() { it('will pass options to rate limiter', function() { @@ -156,4 +164,46 @@ describe('Index', function() { }); }); }); + describe('#setupRoutes', function() { + it('will use rate limiter by default', function() { + var node = {}; + var index = new InsightAPI({ + node: node + }); + var middlewareFunc = sinon.stub(); + var middleware = sinon.stub().returns(middlewareFunc); + var limiter = { + middleware: middleware + }; + index._getRateLimiter = sinon.stub().returns(limiter); + var use = sinon.stub(); + var app = { + use: use, + get: sinon.stub(), + param: sinon.stub(), + post: sinon.stub() + }; + index.setupRoutes(app); + use.callCount.should.be.above(0); + use.args[0][0].should.equal(middlewareFunc); + middleware.callCount.should.equal(1); + }); + it('will NOT use rate limiter if disabled', function() { + var node = {}; + var index = new InsightAPI({ + node: node, + disableRateLimiter: true + }); + index._getRateLimiter = sinon.stub(); + var use = sinon.stub(); + var app = { + use: use, + get: sinon.stub(), + param: sinon.stub(), + post: sinon.stub() + }; + index.setupRoutes(app); + index._getRateLimiter.callCount.should.equal(0); + }); + }); });