diff --git a/lib/modules/admin.js b/lib/modules/admin.js index 7f5a81a..691fc4f 100644 --- a/lib/modules/admin.js +++ b/lib/modules/admin.js @@ -59,6 +59,6 @@ module.exports.create = function (deps, conf) { ] }); - /* device, addresses, cwd, http */ - return require('../app.js')(deps, conf, opts); + var app = require('../app.js')(deps, conf, opts); + return require('http').createServer(app); }; diff --git a/lib/modules/http.js b/lib/modules/http.js index 704f331..709bf28 100644 --- a/lib/modules/http.js +++ b/lib/modules/http.js @@ -4,7 +4,6 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { var PromiseA = require('bluebird'); var express = require('express'); var app = express(); - var adminApp = require('./admin').create(deps, conf); var domainMatches = require('../domain-utils').match; var separatePort = require('../domain-utils').separatePort; @@ -80,16 +79,28 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { }); } - function verifyHost(fullHost) { - var host = separatePort(fullHost).host; + // 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 = {}; + 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') { - return fullHost.replace(host, 'localhost.daplie.me'); + if (!redirecters[host.port]) { + 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, // 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) { (conf.http.modules || []).some(function (mod) { 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; - } - - // 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(); - } + redirecters[host.port](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) { if (mod.name === 'redirect') { app.use(createRedirectRoute(mod)); @@ -217,7 +188,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { else if (mod.name === 'static') { app.use(createStaticRoute(mod)); } - else { + else if (mod.name !== 'proxy') { console.warn('unknown HTTP module', mod); } }); @@ -226,7 +197,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { var server = require('http').createServer(app); - function handleHttp(conn, opts) { + function emitConnection(server, conn, opts) { server.emit('connection', conn); // 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; } + var acmeServer; function checkACME(conn, opts, headers) { if (headers.url.indexOf('/.well-known/acme-challenge/') !== 0) { 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) { return false; } @@ -256,16 +233,23 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { 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) { var admin = adminDomains.some(function (re) { return re.test(headers.host); }); if (admin) { - return handleHttp(conn, opts); + if (!adminServer) { + adminServer = require('./admin').create(deps, conf); + } + return emitConnection(adminServer, conn, opts); } return false; } @@ -315,9 +299,9 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { var opts = conn.__opts; parseHeaders(conn, opts) .then(function (headers) { - if (checkACME(conn, opts, headers)) { return; } - if (checkRedirect(conn, opts, headers)) { return; } - if (checkAdmin(conn, opts, headers)) { return; } + if (checkACME(conn, opts, headers)) { return; } + if (checkHttps(conn, opts, headers)) { return; } + if (checkAdmin(conn, opts, headers)) { return; } var handled = (conf.http.modules || []).some(function (mod) { if (mod.name === 'proxy') { @@ -328,10 +312,7 @@ module.exports.create = function (deps, conf, greenlockMiddleware) { return; } - server.emit('connection', conn); - process.nextTick(function () { - conn.unshift(opts.firstChunk); - }); + emitConnection(server, conn, opts); }) ; }