inherit https options from node

This commit is contained in:
Patrick Nagurny 2015-09-10 11:06:37 -04:00
parent 5677964651
commit 8b0b401d52
7 changed files with 73 additions and 102 deletions

View File

@ -32,6 +32,8 @@ function Node(config) {
$.checkState(config.datadir, 'Node config expects "datadir"'); $.checkState(config.datadir, 'Node config expects "datadir"');
this.datadir = config.datadir; this.datadir = config.datadir;
this.port = config.port; this.port = config.port;
this.https = config.https;
this.httpsOptions = config.httpsOptions;
this._setNetwork(config); this._setNetwork(config);

View File

@ -25,8 +25,6 @@ var BASE_PACKAGE = {
} }
}; };
var BASE_BITCOIN_CONFIG = 'whitelist=127.0.0.1\n' + 'txindex=1\n';
/** /**
* Will create a directory and bitcoin.conf file for Bitcoin. * Will create a directory and bitcoin.conf file for Bitcoin.
* @param {String} dataDir - The absolute path * @param {String} dataDir - The absolute path
@ -38,12 +36,9 @@ function createBitcoinDirectory(datadir, done) {
throw err; throw err;
} }
try {
fs.writeFileSync(datadir + '/bitcoin.conf', BASE_BITCOIN_CONFIG);
} catch(e) {
done(e);
}
done(); done();
// Don't create the configuration yet
}); });
} }

View File

@ -46,7 +46,13 @@ Bitcoin.prototype._loadConfiguration = function() {
} }
if (!fs.existsSync(configPath)) { if (!fs.existsSync(configPath)) {
fs.writeFileSync(configPath, Bitcoin.DEFAULT_CONFIG); var defaultConfig = Bitcoin.DEFAULT_CONFIG;
if(this.node.https && this.node.httpsOptions) {
defaultConfig += 'rpcssl=1\n';
defaultConfig += 'rpcsslprivatekeyfile=' + this.node.httpsOptions.key + '\n';
defaultConfig += 'rpcsslcertificatechainfile=' + this.node.httpsOptions.cert + '\n';
}
fs.writeFileSync(configPath, defaultConfig);
} }
var file = fs.readFileSync(configPath); var file = fs.readFileSync(configPath);

View File

@ -14,8 +14,8 @@ var fs = require('fs');
var WebService = function(options) { var WebService = function(options) {
var self = this; var self = this;
this.node = options.node; this.node = options.node;
this.https = options.https; this.https = options.https || this.node.https;
this.httpsOptions = options.httpsOptions; this.httpsOptions = options.httpsOptions || this.node.httpsOptions;
this.port = options.port || this.node.port || 3456; this.port = options.port || this.node.port || 3456;
this.node.on('ready', function() { this.node.on('ready', function() {
@ -28,20 +28,15 @@ var WebService = function(options) {
inherits(WebService, BaseService); inherits(WebService, BaseService);
WebService.dependencies = ['bitcoind']; WebService.dependencies = [];
WebService.prototype.start = function(callback) { WebService.prototype.start = function(callback) {
var self = this; var self = this;
this.app = express(); this.app = express();
this.app.use(bodyParser.json()); this.app.use(bodyParser.json());
// If https options are not specified, default to https if bitcoind is using https
if(this.https === undefined && this.node.services.bitcoind.configuration.rpcssl) {
this.https = true;
}
if(this.https) { if(this.https) {
this.deriveHttpsOptions(); this.transformHttpsOptions();
this.server = https.createServer(this.httpsOptions, this.app); this.server = https.createServer(this.httpsOptions, this.app);
} else { } else {
this.server = http.createServer(this.app); this.server = http.createServer(this.app);
@ -200,28 +195,15 @@ WebService.prototype.socketMessageHandler = function(message, socketCallback) {
} }
}; };
WebService.prototype.deriveHttpsOptions = function() { WebService.prototype.transformHttpsOptions = function() {
var options = {}; if(!this.httpsOptions || !this.httpsOptions.key || !this.httpsOptions.cert) {
var keyFile;
var certFile;
if(this.httpsOptions) {
keyFile = this.httpsOptions.key;
certFile = this.httpsOptions.cert;
} else {
keyFile = this.node.services.bitcoind.configuration.rpcsslprivatekeyfile;
certFile = this.node.services.bitcoind.configuration.rpcsslcertificatechainfile;
}
if(!keyFile || !certFile) {
throw new Error('Missing https options'); throw new Error('Missing https options');
} }
options.key = fs.readFileSync(keyFile); this.httpsOptions = {
options.cert = fs.readFileSync(certFile); key: fs.readFileSync(this.httpsOptions.key),
cert: fs.readFileSync(this.httpsOptions.cert)
this.httpsOptions = options; };
}; };
module.exports = WebService; module.exports = WebService;

View File

@ -70,11 +70,9 @@ describe('#create', function() {
var configPath = testDir + '/mynode/bitcore-node.json'; var configPath = testDir + '/mynode/bitcore-node.json';
var packagePath = testDir + '/mynode/package.json'; var packagePath = testDir + '/mynode/package.json';
var bitcoinConfig = testDir + '/mynode/data/bitcoin.conf';
should.equal(fs.existsSync(configPath), true); should.equal(fs.existsSync(configPath), true);
should.equal(fs.existsSync(packagePath), true); should.equal(fs.existsSync(packagePath), true);
should.equal(fs.existsSync(bitcoinConfig), true);
var config = JSON.parse(fs.readFileSync(configPath)); var config = JSON.parse(fs.readFileSync(configPath));
config.services.should.deep.equal(['bitcoind', 'db', 'address', 'web']); config.services.should.deep.equal(['bitcoind', 'db', 'address', 'web']);
@ -103,26 +101,6 @@ describe('#create', function() {
}); });
it('will not create bitcoin.conf if it already exists', function() {
create({
cwd: testDir,
dirname: 'mynode2',
name: 'My Node 2',
isGlobal: false,
datadir: '../.bitcoin'
}, function(err) {
if (err) {
throw err;
}
var bitcoinConfig = testDir + '/.bitcoin/bitcoin.conf';
should.equal(fs.existsSync(bitcoinConfig), false);
});
});
it('will not create a package.json if globally installed', function() { it('will not create a package.json if globally installed', function() {
create({ create({

View File

@ -75,6 +75,36 @@ describe('Bitcoin Service', function() {
bitcoind._loadConfiguration({datadir: './test'}); bitcoind._loadConfiguration({datadir: './test'});
}).should.throw('Txindex option'); }).should.throw('Txindex option');
}); });
it('should set https options if node https options are set', function() {
var writeFileSync = function(path, config) {
config.should.equal('whitelist=127.0.0.1\ntxindex=1\nrpcssl=1\nrpcsslprivatekeyfile=key.pem\nrpcsslcertificatechainfile=cert.pem\n');
};
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
writeFileSync: writeFileSync,
readFileSync: readFileSync,
existsSync: sinon.stub().returns(false)
},
mkdirp: {
sync: sinon.stub()
}
});
var config = {
node: {
datadir: 'testdir',
network: {
name: 'regtest'
},
https: true,
httpsOptions: {
key: 'key.pem',
cert: 'cert.pem'
}
}
};
var bitcoind = new TestBitcoin(config);
bitcoind._loadConfiguration({datadir: process.env.HOME + '/.bitcoin'});
});
describe('reindex', function() { describe('reindex', function() {
var log = require('../../lib/').log; var log = require('../../lib/').log;
var stub; var stub;

View File

@ -17,6 +17,20 @@ var fsStub = {
} }
}; };
var fakeSocketListener = new EventEmitter();
var fakeSocket = new EventEmitter();
fakeSocket.on('test/event1', function(data) {
data.should.equal('testdata');
done();
});
fakeSocketListener.emit('connection', fakeSocket);
fakeSocket.emit('subscribe', 'test/event1');
var WebService = proxyquire('../../lib/services/web', {http: httpStub, https: httpsStub, fs: fsStub}); var WebService = proxyquire('../../lib/services/web', {http: httpStub, https: httpsStub, fs: fsStub});
describe('WebService', function() { describe('WebService', function() {
@ -27,17 +41,8 @@ describe('WebService', function() {
httpStub.createServer.reset(); httpStub.createServer.reset();
httpsStub.createServer.reset(); httpsStub.createServer.reset();
}); });
it('should create an http server if no options are specified and bitcoind is not configured for https', function(done) { it('should create an http server if no options are specified and node is not configured for https', function(done) {
var node = new EventEmitter(); var web = new WebService({node: defaultNode});
node.services = {
bitcoind: {
configuration: {
rpcssl: 0
}
}
};
var web = new WebService({node: node});
web.deriveHttpsOptions = sinon.spy(); web.deriveHttpsOptions = sinon.spy();
web.start(function(err) { web.start(function(err) {
should.not.exist(err); should.not.exist(err);
@ -46,18 +51,12 @@ describe('WebService', function() {
}); });
}); });
it('should create an https server if no options are specified and bitcoind is configured for https', function(done) { it('should create an https server if no options are specified and node is configured for https', function(done) {
var node = new EventEmitter(); var node = new EventEmitter();
node.services = { node.https = true;
bitcoind: {
configuration: {
rpcssl: 1
}
}
};
var web = new WebService({node: node}); var web = new WebService({node: node});
web.deriveHttpsOptions = sinon.spy(); web.transformHttpsOptions = sinon.spy();
web.start(function(err) { web.start(function(err) {
should.not.exist(err); should.not.exist(err);
httpsStub.createServer.called.should.equal(true); httpsStub.createServer.called.should.equal(true);
@ -340,7 +339,7 @@ describe('WebService', function() {
}); });
describe('#deriveHttpsOptions', function() { describe('#deriveHttpsOptions', function() {
it('should use the httpsOptions from the config if specified', function() { it('should read key and cert from files specified', function() {
var web = new WebService({ var web = new WebService({
node: defaultNode, node: defaultNode,
https: true, https: true,
@ -350,31 +349,10 @@ describe('WebService', function() {
} }
}); });
web.deriveHttpsOptions(); web.transformHttpsOptions();
web.httpsOptions.key.should.equal('key-buffer'); web.httpsOptions.key.should.equal('key-buffer');
web.httpsOptions.cert.should.equal('cert-buffer'); web.httpsOptions.cert.should.equal('cert-buffer');
}); });
it('should use bitcoind\'s https options if there is no config', function() {
var node = new EventEmitter();
node.services = {
bitcoind: {
configuration: {
rpcssl: 1,
rpcsslprivatekeyfile: 'rpckey',
rpcsslcertificatechainfile: 'rpccert'
}
}
};
var web = new WebService({
node: node
});
web.deriveHttpsOptions();
web.httpsOptions.key.should.equal('rpckey-buffer');
web.httpsOptions.cert.should.equal('rpccert-buffer');
});
it('should throw an error if https is specified but key or cert is not specified', function() { it('should throw an error if https is specified but key or cert is not specified', function() {
var web = new WebService({ var web = new WebService({
node: defaultNode, node: defaultNode,
@ -385,7 +363,7 @@ describe('WebService', function() {
}); });
(function() { (function() {
web.deriveHttpsOptions(); web.transformHttpsOptions();
}).should.throw('Missing https options'); }).should.throw('Missing https options');
}); });
}); });