Added configurable caching.
This commit is contained in:
parent
2a14955d74
commit
94f584f792
@ -3,7 +3,6 @@
|
||||
var common = require('./common');
|
||||
var async = require('async');
|
||||
var bitcore = require('bitcore-lib');
|
||||
var BufferUtil = bitcore.util.buffer;
|
||||
var pools = require('../pools.json');
|
||||
var BN = bitcore.crypto.BN;
|
||||
|
||||
|
||||
78
lib/index.js
78
lib/index.js
@ -15,6 +15,15 @@ var $ = bitcore.util.preconditions;
|
||||
var Transaction = bitcore.Transaction;
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
/**
|
||||
* A service for Bitcore to enable HTTP routes to query information about the blockchain.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Boolean} options.enableCache - This will enable cache-control headers
|
||||
* @param {Number} options.cacheShortSeconds - The time to cache short lived cache responses.
|
||||
* @param {Number} options.cacheLongSeconds - The time to cache long lived cache responses.
|
||||
* @param {String} options.routePrefix - The URL route prefix
|
||||
*/
|
||||
var InsightAPI = function(options) {
|
||||
BaseService.call(this, options);
|
||||
|
||||
@ -25,6 +34,13 @@ var InsightAPI = function(options) {
|
||||
inv: []
|
||||
};
|
||||
|
||||
if (!_.isUndefined(options.enableCache)) {
|
||||
$.checkArgument(_.isBoolean(options.enableCache));
|
||||
this.enableCache = options.enableCache;
|
||||
}
|
||||
this.cacheShortSeconds = options.cacheShortSeconds;
|
||||
this.cacheLongSeconds = options.cacheLongSeconds;
|
||||
|
||||
if (!_.isUndefined(options.routePrefix)) {
|
||||
this.routePrefix = options.routePrefix;
|
||||
} else {
|
||||
@ -38,6 +54,26 @@ InsightAPI.dependencies = ['address', 'web'];
|
||||
|
||||
inherits(InsightAPI, BaseService);
|
||||
|
||||
InsightAPI.prototype.cache = function(maxAge) {
|
||||
var self = this;
|
||||
return function(req, res, next) {
|
||||
if (self.enableCache) {
|
||||
res.header('Cache-Control', 'public, max-age=' + maxAge);
|
||||
}
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
InsightAPI.prototype.cacheShort = function() {
|
||||
var seconds = this.cacheShortSeconds || 30; // thirty seconds
|
||||
return this.cache(seconds);
|
||||
};
|
||||
|
||||
InsightAPI.prototype.cacheLong = function() {
|
||||
var seconds = this.cacheLongSeconds || 86400; // one day
|
||||
return this.cache(seconds);
|
||||
};
|
||||
|
||||
InsightAPI.prototype.getRoutePrefix = function() {
|
||||
return this.routePrefix;
|
||||
};
|
||||
@ -49,6 +85,7 @@ InsightAPI.prototype.start = function(callback) {
|
||||
};
|
||||
|
||||
InsightAPI.prototype.setupRoutes = function(app) {
|
||||
|
||||
//Enable CORS
|
||||
app.use(function(req, res, next) {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
@ -58,48 +95,47 @@ InsightAPI.prototype.setupRoutes = function(app) {
|
||||
|
||||
//Block routes
|
||||
var blocks = new BlockController(this.node);
|
||||
app.get('/blocks', blocks.list.bind(blocks));
|
||||
app.get('/blocks', this.cacheShort(), blocks.list.bind(blocks));
|
||||
|
||||
|
||||
app.get('/block/:blockHash', blocks.show.bind(blocks));
|
||||
app.get('/block/:blockHash', this.cacheLong(), blocks.show.bind(blocks));
|
||||
app.param('blockHash', blocks.block.bind(blocks));
|
||||
|
||||
app.get('/block-index/:height', blocks.blockIndex.bind(blocks));
|
||||
app.get('/block-index/:height', this.cacheLong(), blocks.blockIndex.bind(blocks));
|
||||
app.param('height', blocks.blockIndex.bind(blocks));
|
||||
|
||||
|
||||
// Transaction routes
|
||||
var transactions = new TxController(this.node);
|
||||
app.get('/tx/:txid', transactions.show.bind(transactions));
|
||||
app.get('/tx/:txid', this.cacheLong(), transactions.show.bind(transactions));
|
||||
app.param('txid', transactions.transaction.bind(transactions));
|
||||
app.get('/txs', transactions.list.bind(transactions));
|
||||
app.get('/txs', this.cacheShort(), transactions.list.bind(transactions));
|
||||
app.post('/tx/send', transactions.send.bind(transactions));
|
||||
|
||||
// Raw Routes
|
||||
app.get('/rawtx/:txid', transactions.showRaw.bind(transactions));
|
||||
app.get('/rawtx/:txid', this.cacheLong(), transactions.showRaw.bind(transactions));
|
||||
app.param('txid', transactions.rawTransaction.bind(transactions));
|
||||
|
||||
// Address routes
|
||||
var addresses = new AddressController(this.node);
|
||||
app.get('/addr/:addr', addresses.checkAddr.bind(addresses), addresses.show.bind(addresses));
|
||||
app.get('/addr/:addr/utxo', addresses.checkAddr.bind(addresses), addresses.utxo.bind(addresses));
|
||||
app.get('/addrs/:addrs/utxo', addresses.checkAddrs.bind(addresses), addresses.multiutxo.bind(addresses));
|
||||
app.post('/addrs/utxo', addresses.checkAddrs.bind(addresses), addresses.multiutxo.bind(addresses));
|
||||
app.get('/addrs/:addrs/txs', addresses.checkAddrs.bind(addresses), addresses.multitxs.bind(addresses));
|
||||
app.post('/addrs/txs', addresses.checkAddrs.bind(addresses), addresses.multitxs.bind(addresses));
|
||||
app.get('/addr/:addr', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.show.bind(addresses));
|
||||
app.get('/addr/:addr/utxo', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.utxo.bind(addresses));
|
||||
app.get('/addrs/:addrs/utxo', this.cacheShort(), addresses.checkAddrs.bind(addresses), addresses.multiutxo.bind(addresses));
|
||||
app.post('/addrs/utxo', this.cacheShort(), addresses.checkAddrs.bind(addresses), addresses.multiutxo.bind(addresses));
|
||||
app.get('/addrs/:addrs/txs', this.cacheShort(), addresses.checkAddrs.bind(addresses), addresses.multitxs.bind(addresses));
|
||||
app.post('/addrs/txs', this.cacheShort(), addresses.checkAddrs.bind(addresses), addresses.multitxs.bind(addresses));
|
||||
|
||||
// Address property routes
|
||||
app.get('/addr/:addr/balance', addresses.checkAddr.bind(addresses), addresses.balance.bind(addresses));
|
||||
app.get('/addr/:addr/totalReceived', addresses.checkAddr.bind(addresses), addresses.totalReceived.bind(addresses));
|
||||
app.get('/addr/:addr/totalSent', addresses.checkAddr.bind(addresses), addresses.totalSent.bind(addresses));
|
||||
app.get('/addr/:addr/unconfirmedBalance', addresses.checkAddr.bind(addresses), addresses.unconfirmedBalance.bind(addresses));
|
||||
app.get('/addr/:addr/balance', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.balance.bind(addresses));
|
||||
app.get('/addr/:addr/totalReceived', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.totalReceived.bind(addresses));
|
||||
app.get('/addr/:addr/totalSent', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.totalSent.bind(addresses));
|
||||
app.get('/addr/:addr/unconfirmedBalance', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.unconfirmedBalance.bind(addresses));
|
||||
|
||||
// Status route
|
||||
var status = new StatusController(this.node);
|
||||
app.get('/status', status.show.bind(status));
|
||||
app.get('/sync', status.sync.bind(status));
|
||||
app.get('/peer', status.peer.bind(status));
|
||||
app.get('/version', status.version.bind(status));
|
||||
app.get('/status', this.cacheShort(), status.show.bind(status));
|
||||
app.get('/sync', this.cacheShort(), status.sync.bind(status));
|
||||
app.get('/peer', this.cacheShort(), status.peer.bind(status));
|
||||
app.get('/version', this.cacheShort(), status.version.bind(status));
|
||||
|
||||
// Address routes
|
||||
var messages = new MessagesController(this.node);
|
||||
|
||||
110
test/index.js
Normal file
110
test/index.js
Normal file
@ -0,0 +1,110 @@
|
||||
'use strict';
|
||||
|
||||
var should = require('should');
|
||||
var sinon = require('sinon');
|
||||
var InsightAPI = require('../lib/index');
|
||||
|
||||
describe('Index', function() {
|
||||
describe('#cache', function() {
|
||||
it('will set cache control header', function(done) {
|
||||
var index = new InsightAPI({
|
||||
enableCache: true
|
||||
});
|
||||
var req = {};
|
||||
var res = {
|
||||
header: sinon.stub()
|
||||
};
|
||||
var middle = index.cache(10);
|
||||
middle(req, res, function() {
|
||||
res.header.callCount.should.equal(1);
|
||||
res.header.args[0][0].should.equal('Cache-Control');
|
||||
res.header.args[0][1].should.equal('public, max-age=10');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('will NOT set cache control header', function(done) {
|
||||
var index = new InsightAPI({
|
||||
enableCache: false
|
||||
});
|
||||
var req = {};
|
||||
var res = {
|
||||
header: sinon.stub()
|
||||
};
|
||||
var middle = index.cache(10);
|
||||
middle(req, res, function() {
|
||||
res.header.callCount.should.equal(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#cacheShort', function() {
|
||||
it('will set SHORT cache control header', function(done) {
|
||||
var index = new InsightAPI({
|
||||
enableCache: true,
|
||||
cacheShortSeconds: 35
|
||||
});
|
||||
var req = {};
|
||||
var res = {
|
||||
header: sinon.stub()
|
||||
};
|
||||
var middle = index.cacheShort();
|
||||
middle(req, res, function() {
|
||||
res.header.callCount.should.equal(1);
|
||||
res.header.args[0][0].should.equal('Cache-Control');
|
||||
res.header.args[0][1].should.equal('public, max-age=35');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('will set SHORT DEFAULT cache control header', function(done) {
|
||||
var index = new InsightAPI({
|
||||
enableCache: true
|
||||
});
|
||||
var req = {};
|
||||
var res = {
|
||||
header: sinon.stub()
|
||||
};
|
||||
var middle = index.cacheShort();
|
||||
middle(req, res, function() {
|
||||
res.header.callCount.should.equal(1);
|
||||
res.header.args[0][0].should.equal('Cache-Control');
|
||||
res.header.args[0][1].should.equal('public, max-age=30');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#cacheLong', function() {
|
||||
it('will set LONG cache control header', function(done) {
|
||||
var index = new InsightAPI({
|
||||
enableCache: true,
|
||||
cacheLongSeconds: 86400000
|
||||
});
|
||||
var req = {};
|
||||
var res = {
|
||||
header: sinon.stub()
|
||||
};
|
||||
var middle = index.cacheLong();
|
||||
middle(req, res, function() {
|
||||
res.header.callCount.should.equal(1);
|
||||
res.header.args[0][0].should.equal('Cache-Control');
|
||||
res.header.args[0][1].should.equal('public, max-age=86400000');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('will set LONG DEFAULT cache control header', function(done) {
|
||||
var index = new InsightAPI({
|
||||
enableCache: true
|
||||
});
|
||||
var req = {};
|
||||
var res = {
|
||||
header: sinon.stub()
|
||||
};
|
||||
var middle = index.cacheLong();
|
||||
middle(req, res, function() {
|
||||
res.header.callCount.should.equal(1);
|
||||
res.header.args[0][0].should.equal('Cache-Control');
|
||||
res.header.args[0][1].should.equal('public, max-age=86400');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user