started splitting http handling into multiple servers
This commit is contained in:
parent
47bcdcf2a6
commit
27e818f41a
|
@ -59,6 +59,6 @@ module.exports.create = function (deps, conf) {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
/* device, addresses, cwd, http */
|
var app = require('../app.js')(deps, conf, opts);
|
||||||
return require('../app.js')(deps, conf, opts);
|
return require('http').createServer(app);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
var PromiseA = require('bluebird');
|
var PromiseA = require('bluebird');
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var app = express();
|
var app = express();
|
||||||
var adminApp = require('./admin').create(deps, conf);
|
|
||||||
var domainMatches = require('../domain-utils').match;
|
var domainMatches = require('../domain-utils').match;
|
||||||
var separatePort = require('../domain-utils').separatePort;
|
var separatePort = require('../domain-utils').separatePort;
|
||||||
|
|
||||||
|
@ -80,16 +79,28 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyHost(fullHost) {
|
// We handle both HTTPS and HTTP traffic on the same ports, and we want to redirect
|
||||||
var host = separatePort(fullHost).host;
|
// any unencrypted requests to the same port they came from unless it came in on
|
||||||
|
// the default HTTP port, in which case there wont be a port specified in the host.
|
||||||
|
var redirecters = {};
|
||||||
|
var ipv4Re = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
||||||
|
var ipv6Re = /^\[[0-9a-fA-F:]+\]$/;
|
||||||
|
function redirectHttps(req, res) {
|
||||||
|
var host = separatePort(req.headers.host);
|
||||||
|
|
||||||
if (host === 'localhost') {
|
if (!redirecters[host.port]) {
|
||||||
return fullHost.replace(host, 'localhost.daplie.me');
|
redirecters[host.port] = require('redirect-https')({ port: host.port });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// localhost and IP addresses cannot have real SSL certs (and don't contain any useful
|
||||||
|
// info for redirection either), so we direct some hosts to either localhost.daplie.me
|
||||||
|
// or the "primary domain" ie the first manually specified domain.
|
||||||
|
if (host.host === 'localhost') {
|
||||||
|
req.headers.host = 'localhost.daplie.me' + (host.port ? ':'+host.port : '');
|
||||||
|
}
|
||||||
// Test for IPv4 and IPv6 addresses. These patterns will match some invalid addresses,
|
// Test for IPv4 and IPv6 addresses. These patterns will match some invalid addresses,
|
||||||
// but since those still won't be valid domains that won't really be a problem.
|
// but since those still won't be valid domains that won't really be a problem.
|
||||||
if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host) || /^\[[0-9a-fA-F:]+\]$/.test(host)) {
|
if (ipv4Re.test(host.host) || ipv6Re.test(host.host)) {
|
||||||
if (!conf.http.primaryDomain) {
|
if (!conf.http.primaryDomain) {
|
||||||
(conf.http.modules || []).some(function (mod) {
|
(conf.http.modules || []).some(function (mod) {
|
||||||
return mod.domains.some(function (domain) {
|
return mod.domains.some(function (domain) {
|
||||||
|
@ -100,48 +111,12 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return fullHost.replace(host, conf.http.primaryDomain || host);
|
if (conf.http.primaryDomain) {
|
||||||
|
req.headers.host = conf.http.primaryDomain + (host.port ? ':'+host.port : '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullHost;
|
redirecters[host.port](req, res);
|
||||||
}
|
|
||||||
|
|
||||||
// We handle both HTTPS and HTTP traffic on the same ports, and we want to redirect
|
|
||||||
// any unencrypted requests to the same port they came from unless it came in on
|
|
||||||
// the default HTTP port, in which case there wont be a port specified in the host.
|
|
||||||
var redirecters = {};
|
|
||||||
function redirectHttps(req, res, next) {
|
|
||||||
if (conf.http.allowInsecure) {
|
|
||||||
next();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var port = separatePort(req.headers.host).port;
|
|
||||||
if (!redirecters[port]) {
|
|
||||||
redirecters[port] = require('redirect-https')({
|
|
||||||
port: port
|
|
||||||
, trustProxy: conf.http.trustProxy
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// localhost and IP addresses cannot have real SSL certs (and don't contain any useful
|
|
||||||
// info for redirection either), so we direct some hosts to either localhost.daplie.me
|
|
||||||
// or the "primary domain" ie the first manually specified domain.
|
|
||||||
req.headers.host = verifyHost(req.headers.host);
|
|
||||||
|
|
||||||
redirecters[port](req, res, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleAdmin(req, res, next) {
|
|
||||||
var admin = adminDomains.some(function (re) {
|
|
||||||
return re.test(req.headers.host);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (admin) {
|
|
||||||
adminApp(req, res);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function respond404(req, res) {
|
function respond404(req, res) {
|
||||||
|
@ -206,10 +181,6 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
app.use(greenlockMiddleware);
|
|
||||||
app.use(redirectHttps);
|
|
||||||
app.use(handleAdmin);
|
|
||||||
|
|
||||||
(conf.http.modules || []).forEach(function (mod) {
|
(conf.http.modules || []).forEach(function (mod) {
|
||||||
if (mod.name === 'redirect') {
|
if (mod.name === 'redirect') {
|
||||||
app.use(createRedirectRoute(mod));
|
app.use(createRedirectRoute(mod));
|
||||||
|
@ -217,7 +188,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
else if (mod.name === 'static') {
|
else if (mod.name === 'static') {
|
||||||
app.use(createStaticRoute(mod));
|
app.use(createStaticRoute(mod));
|
||||||
}
|
}
|
||||||
else {
|
else if (mod.name !== 'proxy') {
|
||||||
console.warn('unknown HTTP module', mod);
|
console.warn('unknown HTTP module', mod);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -226,7 +197,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
|
|
||||||
var server = require('http').createServer(app);
|
var server = require('http').createServer(app);
|
||||||
|
|
||||||
function handleHttp(conn, opts) {
|
function emitConnection(server, conn, opts) {
|
||||||
server.emit('connection', conn);
|
server.emit('connection', conn);
|
||||||
|
|
||||||
// We need to put back whatever data we read off to determine the connection was HTTP
|
// We need to put back whatever data we read off to determine the connection was HTTP
|
||||||
|
@ -240,15 +211,21 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var acmeServer;
|
||||||
function checkACME(conn, opts, headers) {
|
function checkACME(conn, opts, headers) {
|
||||||
if (headers.url.indexOf('/.well-known/acme-challenge/') !== 0) {
|
if (headers.url.indexOf('/.well-known/acme-challenge/') !== 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleHttp(conn, opts);
|
if (!acmeServer) {
|
||||||
|
acmeServer = require('http').createServer(greenlockMiddleware);
|
||||||
|
}
|
||||||
|
return emitConnection(acmeServer, conn, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRedirect(conn, opts, headers) {
|
|
||||||
|
var httpsRedirectServer;
|
||||||
|
function checkHttps(conn, opts, headers) {
|
||||||
if (conf.http.allowInsecure || conn.encrypted) {
|
if (conf.http.allowInsecure || conn.encrypted) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -256,16 +233,23 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleHttp(conn, opts);
|
if (!httpsRedirectServer) {
|
||||||
|
httpsRedirectServer = require('http').createServer(redirectHttps);
|
||||||
|
}
|
||||||
|
return emitConnection(httpsRedirectServer, conn, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var adminServer;
|
||||||
function checkAdmin(conn, opts, headers) {
|
function checkAdmin(conn, opts, headers) {
|
||||||
var admin = adminDomains.some(function (re) {
|
var admin = adminDomains.some(function (re) {
|
||||||
return re.test(headers.host);
|
return re.test(headers.host);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (admin) {
|
if (admin) {
|
||||||
return handleHttp(conn, opts);
|
if (!adminServer) {
|
||||||
|
adminServer = require('./admin').create(deps, conf);
|
||||||
|
}
|
||||||
|
return emitConnection(adminServer, conn, opts);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -316,7 +300,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
parseHeaders(conn, opts)
|
parseHeaders(conn, opts)
|
||||||
.then(function (headers) {
|
.then(function (headers) {
|
||||||
if (checkACME(conn, opts, headers)) { return; }
|
if (checkACME(conn, opts, headers)) { return; }
|
||||||
if (checkRedirect(conn, opts, headers)) { return; }
|
if (checkHttps(conn, opts, headers)) { return; }
|
||||||
if (checkAdmin(conn, opts, headers)) { return; }
|
if (checkAdmin(conn, opts, headers)) { return; }
|
||||||
|
|
||||||
var handled = (conf.http.modules || []).some(function (mod) {
|
var handled = (conf.http.modules || []).some(function (mod) {
|
||||||
|
@ -328,10 +312,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
server.emit('connection', conn);
|
emitConnection(server, conn, opts);
|
||||||
process.nextTick(function () {
|
|
||||||
conn.unshift(opts.firstChunk);
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue