fix ssl bugs, account for proxyable apps

This commit is contained in:
AJ ONeal 2015-02-21 01:16:38 +00:00
parent 64e04ee5e3
commit e7d0769270
1 changed files with 47 additions and 33 deletions

View File

@ -150,7 +150,12 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
if (localApp.create) {
// TODO read local config.yml and pass it in
// TODO pass in websocket
localApp = localApp.create(/*config*/);
localApp = localApp.create(secureServer, {
dummyCerts: dummyCerts
, hostname: domaininfo.hostname
, port: securePort
, url: domaininfo.pathname
});
if (!localApp) {
return getDummyAppContext(null, "[ERROR] no app was returned by app.js for " + domaininfo.driname);
}
@ -174,7 +179,12 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
function loadDomainVhosts() {
domainMerged.forEach(function (domainApp) {
console.log('[log] loaded mounts for domain ' + domainApp.hostname);
if (domainApp._loaded) {
return;
}
console.log('[log] [once] Loading mounts for ' + domainApp.hostname);
domainApp._loaded = true;
app.use(vhost(domainApp.hostname, domainApp.apps));
app.use(vhost('www.' + domainApp.hostname, domainApp.apps));
});
@ -185,6 +195,7 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
var vhost = (req.headers.host || '').split(':')[0];
// the matching domain didn't catch it
console.log('[log] vhost:', vhost);
if (domainMergeMap[vhost]) {
next();
return;
@ -199,13 +210,15 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
return forEachAsync(domainMergeMap[vhost].apps, function (fn) {
return new PromiseA(function (resolve) {
function next(err) {
if (err) {
reject(err);
}
resolve();
}
try {
fn(req, res, function (err) {
if (err) {
reject(err);
}
resolve();
});
fn(req, res, next);
} catch(e) {
reject(e);
}
@ -229,7 +242,8 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
// return forEachAsync(rootDomains, loadCerts);
// TODO load these even more lazily
return forEachAsync(readNewVhosts(), loadDomainMounts).then(loadDomainVhosts).then(function () {
app.use(hotloadApp);
console.log('[log] TODO fix and use hotload');
//app.use(hotloadApp);
resolve(app);
return;
});
@ -269,55 +283,48 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
}
try {
secureContexts[domainname] = createSecureContext(secOpts).context;
secureContexts[domainname] = createSecureContext(secOpts);
} catch(err) {
console.error("[ERROR] Certificates in '" + certsPath + "' could not be used:");
console.error(err);
return null;
}
if (!secureContexts[domainname]) {
console.error("[ERROR] Sanity check fail, no cert for '" + domainname + "'");
return null;
}
return secureContexts[domainname];
}
function createSecureServer() {
var dummyCerts = loadDummyCerts();
var localDummyCerts = loadDummyCerts();
var secureOpts = {
// fallback / default dummy certs
key: dummyCerts.key
, cert: dummyCerts.cert
, ca: dummyCerts.ca
key: localDummyCerts.key
, cert: localDummyCerts.cert
, ca: localDummyCerts.ca
};
function addSniWorkaroundCallback() {
//SNICallback is passed the domain name, see NodeJS docs on TLS
secureOpts.SNICallback = function (domainname, cb) {
console.log('[log] SNI:', domainname);
if (!secureContexts.dummy) {
secureContexts.dummy = createSecureContext(dummyCerts);
console.log('[log] Loading dummy certs');
secureContexts.dummy = createSecureContext(localDummyCerts);
}
var secureContext = secureContexts[domainname]
|| loadCerts(domainname)
|| secureContexts.dummy
//|| createSecureContext(dummyCerts)
//|| createSecureContext(loadDummyCerts())
;
if (!secureContext) {
// testing with shared dummy
//secureContext = secureContexts.dummy;
// testing passing bad argument
//secureContext = createSecureContext(loadDummyCerts);
// testing with fresh dummy
secureContext = createSecureContext(loadDummyCerts());
if (!secureContexts[domainname]) {
console.log('[log] Loading certs for', domainname);
secureContexts[domainname] = loadCerts(domainname);
}
// workaround for v0.12 / v1.2 backwards compat bug
if ('function' === typeof cb) {
cb(null, secureContext);
cb(null, secureContexts[domainname] || secureContexts.dummy);
} else {
return secureContext;
return secureContexts[domainname] || secureContexts.dummy;
}
};
}
@ -346,6 +353,13 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
// Get up and listening as absolutely quickly as possible
secureServer.on('request', function (req, res) {
if (/(^|\.)_proxyable\./.test(req.headers.host)) {
// device-id-12345678._proxyable.myapp.mydomain.com => myapp.mydomain.com
// _proxyable.myapp.mydomain.com => myapp.mydomain.com
// TODO myapp.mydomain.com.proxyable.com => myapp.mydomain.com
req.headers.host = req.headers.host.replace(/.*\.?_proxyable\./, '');
}
loadPromise().then(function (app) {
app(req, res);
});