diff --git a/browser/root-certs b/browser/root-certs new file mode 100755 index 000000000..c8bbc7752 --- /dev/null +++ b/browser/root-certs @@ -0,0 +1,188 @@ +#!/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(/,$/, ''); + body = 'var RootCerts = [\n' + body + '\n];\n'; + body = body.replace(/^"/gm, '+ "'); + body = body.replace(/^\+ "-----B/gm, '"-----B'); + body += '' + + '// Use hash table for efficiency:\n' + + 'RootCerts = RootCerts.reduce(function(trusted, cert) {\n' + + ' cert = cert.replace(/\\s+/g, "");\n' + + ' trusted[cert] = true;\n' + + ' return trusted;\n' + + '}, {});\n' + + 'module.exports = RootCerts;\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; + } + return getRootCerts(function(err, certs) { + var file = path.resolve(__dirname, '..', 'lib', 'RootCerts.js'); + return fs.writeFile(file, certs, 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; +} diff --git a/lib/RootCerts.js b/lib/RootCerts.js index b5512bce9..e3526dad4 100644 --- a/lib/RootCerts.js +++ b/lib/RootCerts.js @@ -3557,11 +3557,12 @@ var RootCerts = [ + "EYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU3j2L\n" + "rTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM\n" + "dcGWxZ0=\n" -+ "-----END CERTIFICATE-----\n" ++ "-----END CERTIFICATE-----\n", + ]; // Use hash table for efficiency: RootCerts = RootCerts.reduce(function(trusted, cert) { - cert = cert.replace(/\s+/g, ''); + cert = cert.replace(/\s+/g, ""); trusted[cert] = true; return trusted; }, {});