2 changed files with 191 additions and 2 deletions
@ -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; |
|||
} |
Loading…
Reference in new issue