bitcore-lib-zcash/browser/root-certs

222 lines
5.4 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* Modules
*/
var fs = require('fs');
var url = require('url');
var http = require('http');
var path = require('path');
var Stream = require('stream').Stream;
var StringDecoder = require('string_decoder').StringDecoder;
/**
* Mozilla Root Cert URL
*/
var certUrl = 'https://raw.githubusercontent.com/joyent/node/master/src/node_root_certs.h';
/**
* Get Root Certs
*/
function getRootCerts(callback) {
return request(certUrl, function(err, res, body) {
if (err) return callback(err);
body = body.replace(/,\s*$/, '');
body = 'var certs = {\n' + body + '\n};\n';
body = body.replace(/^"/gm, '+ "');
body = body.replace(/^\+ "-----B/gm, '"-----B');
body = body.replace(/\/\*([^*]+)\*\/\n(?=")/g, function(_, name) {
var key = name.trim();
return '// ' + key + '\n'
+ '"' + key + '":\n';
});
body += ''
+ '\n'
+ '// Use hash table for efficiency:\n'
+ 'var trusted = Object.keys(certs).reduce(function(trusted, key) {\n'
+ ' var pem = certs[key];\n'
+ ' pem = pem.replace(/-----BEGIN CERTIFICATE-----/g, "");\n'
+ ' pem = pem.replace(/-----END CERTIFICATE-----/g, "");\n'
+ ' pem = pem.replace(/\\s+/g, "");\n'
+ ' trusted[pem] = key;\n'
+ ' return trusted;\n'
+ '}, {});\n'
+ '\n'
+ 'function getTrusted(pem) {\n'
+ ' pem = pem + "";\n'
+ ' pem = pem.replace(/-----BEGIN CERTIFICATE-----/g, "");\n'
+ ' pem = pem.replace(/-----END CERTIFICATE-----/g, "");\n'
+ ' pem = pem.replace(/\\s+/g, "");\n'
+ ' if (!Object.prototype.hasOwnProperty.call(trusted, pem)) return;\n'
+ ' return trusted[pem];\n'
+ '}\n'
+ '\n'
+ 'function getCert(name) {\n'
+ ' name = name.replace(/^\s+|\s+$/g, "");\n'
+ ' if (!Object.prototype.hasOwnProperty.call(certs, name)) return;\n'
+ ' return certs[name];\n'
+ '}\n'
+ '\n'
+ 'exports.certs = certs;\n'
+ 'exports.trusted = trusted;\n'
+ 'exports.getCert = getCert;\n'
+ 'exports.getTrusted = getTrusted;\n';
return callback(null, body);
});
}
/**
* Helpers
*/
function request(options, callback) {
if (typeof options === 'string' || options.hostname) {
options = { uri: options };
}
var uri = options.uri || options.url
, body = options.json
? JSON.stringify(options.json)
: options.body || '';
if (typeof uri !== 'object') {
uri = url.parse(uri);
}
if (options.qs) {
var query = uri.query ? qs.parse(uri.query) : {};
Object.keys(options.qs).forEach(function(key) {
query[key] = options.qs[key];
});
uri.path = uri.pathname + '?' + qs.stringify(query);
}
var protocol = uri.protocol === 'https:'
? require('https')
: http;
options.method = options.method || (body ? 'POST' : 'GET');
options.method = options.method.toUpperCase();
options.headers = options.headers || {};
options.headers['Accept'] = options.headers['Accept'] || 'text/plain; charset=utf-8';
if (options.json) {
options.headers['Content-Type'] = 'application/json; charset=utf-8';
options.headers['Accept'] = 'application/json';
}
if (options.method !== 'GET' && options.method !== 'HEAD') {
options.headers['Content-Length'] = Buffer.byteLength(body);
}
var opt = {
auth: uri.auth,
host: uri.hostname,
port: uri.port || (protocol === http ? 80 : 443),
path: uri.path,
method: options.method,
headers: options.headers
};
var req = protocol.request(opt)
, response = new Stream;
req.on('error', function(err) {
if (callback) {
callback(err);
} else {
response.emit('error', err);
}
});
req.on('response', function(res) {
var decoder = new StringDecoder('utf8')
, done = false
, body = '';
function end() {
if (done) return;
done = true;
if (callback) {
res.body = body;
if (options.json) {
try {
body = JSON.parse(body);
} catch (e) {
;
}
}
callback(null, res, body);
} else {
response.emit('end');
}
res.socket.removeListener('error', error);
res.socket.removeListener('end', end);
}
function error(err) {
res.destroy();
if (callback) {
callback(err);
} else {
response.emit('error', err);
}
}
res.on('data', function(data) {
if (callback) {
body += decoder.write(data);
} else {
response.emit('data', data);
}
});
res.on('error', error);
res.socket.on('error', error);
res.on('end', end);
// An agent socket's `end` sometimes
// wont be emitted on the response.
res.socket.on('end', end);
});
req.end(body);
return response;
}
/**
* Execute
*/
function main(argv, callback) {
if (!callback) {
callback = argv;
argv = null;
}
console.log('Retrieving root certs from: %s', certUrl);
return getRootCerts(function(err, certs) {
var file = path.resolve(__dirname, '..', 'lib', 'common', 'RootCerts.js');
return fs.writeFile(file, certs, function(err) {
if (err) return callback(err);
console.log('Root cert code generated at: %s.', file);
return callback();
});
});
}
if (!module.parent) {
process.title = 'root-certs';
main(process.argv.slice(), function(err, code) {
if (err) throw err;
return process.exit(code || 0);
});
} else {
module.exports = main;
}