Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
4,543 additions
and
230 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
#!/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 += '' | ||
+ '\n' | ||
+ '// 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' | ||
+ '\n' | ||
+ 'function isTrusted(pem) {\n' | ||
+ ' pem = pem + "";\n' | ||
+ ' pem = pem.replace(/\\s+/g, "");\n' | ||
+ ' return !!RootCerts[pem];\n' | ||
+ '}\n' | ||
+ '\n' | ||
+ 'exports = RootCerts;\n' | ||
+ 'exports.isTrusted = isTrusted;\n' | ||
+ 'module.exports = exports;\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', 'common', '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; | ||
} |
Oops, something went wrong.