v2.4.2: .listen() simplified and now handles addresses and sockets

This commit is contained in:
AJ ONeal 2018-08-18 01:52:32 -06:00
parent 38de3e9d1c
commit 1dae4248c3
4 changed files with 96 additions and 75 deletions

View File

@ -410,7 +410,13 @@ The API is actually located at [greenlock.js options](https://git.coolaj86.com/c
The only "API" consists of two options, the rest is just a wrapper around `greenlock.js` to take LOC from 15 to 5: The only "API" consists of two options, the rest is just a wrapper around `greenlock.js` to take LOC from 15 to 5:
* `opts.app` An express app in the format `function (req, res) { ... }` (no `next`). * `opts.app` An express app in the format `function (req, res) { ... }` (no `next`).
* `server = glx.listen(plainPort, tlsPort)` Accepts port numbers (or arrays of port numbers) to listen on, returns secure server. * `server = glx.listen(plainAddr, tlsAddr, onListen)` Accepts port numbers (or arrays of port numbers) to listen on, returns secure server.
* `listen(80, 443)`
* `listen(80, 443, onListenSecure)`
* `listen(80, 443, onListenPlain, onListenSecure)`
* `listen('localhost:80', '0.0.0.0:443')`
* `listen('[::1]:80', '[::]:443')`
* `listen('/tmp/glx.plain.sock', '/tmp/glx.secure.sock')`
Brief overview of some simple options for `greenlock.js`: Brief overview of some simple options for `greenlock.js`:

View File

@ -29,36 +29,25 @@ module.exports.create = function (opts) {
console.error(e.code + ": '" + e.address + ":" + e.port + "'"); console.error(e.code + ": '" + e.address + ":" + e.port + "'");
} }
function _listenHttp(plainPort) { function _listen(plainPort, plain) {
if (!plainPort) { plainPort = 80; } if (!plainPort) { plainPort = 80; }
var p = plainPort;
var parts = String(plainPort).split(':');
var p = parts.pop();
var addr = parts.join(':').replace(/^\[/, '').replace(/\]$/, '');
var args = [];
var httpType;
var server;
var validHttpPort = (parseInt(p, 10) >= 0); var validHttpPort = (parseInt(p, 10) >= 0);
if (!validHttpPort) { console.warn("'" + p + "' doesn't seem to be a valid port number for http"); }
var plainServer = require('http').createServer( function tryPlain() {
server = require('http').createServer(
greenlock.middleware.sanitizeHost(greenlock.middleware(require('redirect-https')())) greenlock.middleware.sanitizeHost(greenlock.middleware(require('redirect-https')()))
); );
var promise = new PromiseA(function (resolve) { httpType = 'http';
plainServer.listen(p, function () {
resolve(plainServer);
}).on('error', function (e) {
if (plainServer.listenerCount('error') < 2) {
console.warn("Did not successfully create http server and bind to port '" + p + "':");
explainError(e);
process.exit(41);
}
});
});
promise.server = plainServer;
return promise;
} }
function _listenHttps(port) { function trySecure() {
if (!port) { port = 443; }
var p = port;
var validHttpsPort = (parseInt(p, 10) >= 0);
var httpType;
if (!validHttpsPort) { console.warn("'" + p + "' doesn't seem to be a valid port number for https"); }
var https; var https;
try { try {
https = require('spdy'); https = require('spdy');
@ -68,7 +57,7 @@ module.exports.create = function (opts) {
https = require('https'); https = require('https');
httpType = 'https'; httpType = 'https';
} }
var server = https.createServer( server = https.createServer(
greenlock.tlsOptions greenlock.tlsOptions
, greenlock.middleware.sanitizeHost(function (req, res) { , greenlock.middleware.sanitizeHost(function (req, res) {
try { try {
@ -80,17 +69,26 @@ module.exports.create = function (opts) {
}) })
); );
server.type = httpType; server.type = httpType;
}
if (addr) { args[1] = addr; }
if (!validHttpPort && !/(\/)|(\\\\)/.test(p)) {
console.warn("'" + p + "' doesn't seem to be a valid port number, socket path, or pipe");
}
if (plain) { tryPlain(); } else { trySecure(); }
var promise = new PromiseA(function (resolve) { var promise = new PromiseA(function (resolve) {
server.listen(p, function () { args[0] = p;
resolve(server); args.push(function () { resolve(server); });
}).on('error', function (e) { server.listen.apply(server, args).on('error', function (e) {
if (server.listenerCount('error') < 2) { if (server.listenerCount('error') < 2) {
console.warn("Did not successfully create https server and bind to port '" + p + "':"); console.warn("Did not successfully create http server and bind to port '" + p + "':");
explainError(e); explainError(e);
process.exit(43); process.exit(41);
} }
}); });
}); });
promise.server = server; promise.server = server;
return promise; return promise;
} }
@ -101,40 +99,36 @@ module.exports.create = function (opts) {
res.end("Hello, World!\nWith Love,\nGreenlock for Express.js"); res.end("Hello, World!\nWith Love,\nGreenlock for Express.js");
}; };
opts.listen = function (plainPort, port, fn1, fn2) { opts.listen = function (plainPort, port, fnPlain, fn) {
var promises = []; var promises = [];
var server; var server;
var plainServer; var plainServer;
var fn; if (!fn) {
var fnPlain; fn = fnPlain;
if (fn2) { fnPlain = null;
fn = fn2;
fnPlain = fn1;
} else {
fn = fn1;
} }
promises.push(_listenHttp(plainPort, !fnPlain)); promises.push(_listen(plainPort, true));
promises.push(_listenHttps(port, !fn)); promises.push(_listen(port, false));
server = promises[1].server; server = promises[1].server;
plainServer = promises[0].server; plainServer = promises[0].server;
PromiseA.all(promises).then(function () { PromiseA.all(promises).then(function () {
// Report h2/https status
if ('function' === typeof fn) {
fn.apply(server);
} else if (server.listenerCount('listening') < 2) {
console.info("Success! Serving " + server.type + " on port '" + server.address().port + "'");
}
// Report plain http status // Report plain http status
if ('function' === typeof fnPlain) { if ('function' === typeof fnPlain) {
fnPlain.apply(plainServer); fnPlain.apply(plainServer);
} else if (!fn && plainServer.listenerCount('listening') < 2) { } else if (!fn && plainServer.listenerCount('listening') < 2) {
console.info("Success! Bound to port '" + plainServer.address().port console.info('[:' + (plainServer.address().port || plainServer.address())
+ "' to handle ACME challenges and redirect to " + server.type); + "] Handling ACME challenges and redirecting to " + server.type);
}
// Report h2/https status
if ('function' === typeof fn) {
fn.apply(server);
} else if (server.listenerCount('listening') < 2) {
console.info('[:' + (server.address().port || server.address()) + "] Serving " + server.type);
} }
}); });

View File

@ -1,6 +1,6 @@
{ {
"name": "greenlock-express", "name": "greenlock-express",
"version": "2.4.1", "version": "2.4.2",
"description": "Free SSL and managed or automatic HTTPS for node.js with Express, Koa, Connect, Hapi, and all other middleware systems.", "description": "Free SSL and managed or automatic HTTPS for node.js with Express, Koa, Connect, Hapi, and all other middleware systems.",
"main": "index.js", "main": "index.js",
"homepage": "https://git.coolaj86.com/coolaj86/greenlock-express.js", "homepage": "https://git.coolaj86.com/coolaj86/greenlock-express.js",

View File

@ -18,6 +18,8 @@ server1.on('listening', function () {
console.log("### THREE 3333 - All is well server1", this.address()); console.log("### THREE 3333 - All is well server1", this.address());
setTimeout(function () { setTimeout(function () {
// so that the address() object doesn't disappear // so that the address() object doesn't disappear
server1.close();
server1.unencrypted.close();
}, 10); }, 10);
}); });
setTimeout(function () { setTimeout(function () {
@ -25,9 +27,16 @@ setTimeout(function () {
console.log("### FIVE 55555 - Started server 2!"); console.log("### FIVE 55555 - Started server 2!");
setTimeout(function () { setTimeout(function () {
server2.close(); server2.close();
server2.unencrypted.close();
server6.close();
server6.unencrypted.close();
server7.close();
server7.unencrypted.close();
setTimeout(function () {
// TODO greenlock needs a close event (and to listen to its server's close event) // TODO greenlock needs a close event (and to listen to its server's close event)
process.exit(0); process.exit(0);
}, 1000); }, 1000);
}, 1000);
}); });
server2.on('listening', function () { server2.on('listening', function () {
console.log("### FOUR 44444 - All is well server2", server2.address()); console.log("### FOUR 44444 - All is well server2", server2.address());
@ -49,6 +58,18 @@ server3.on('error', function () {
var server4 = greenlock.listen(7080, 7443, function () { var server4 = greenlock.listen(7080, 7443, function () {
console.log('Success: server4: plain'); console.log('Success: server4: plain');
server4.unencrypted.close();
}, function () { }, function () {
console.log('Success: server4: ' + server4.type); console.log('Success: server4: ' + server4.type);
server4.close();
}); });
var server5 = greenlock.listen(10080, 10443, function () {
console.log("Server 5 with one fn", this.address());
server5.close();
server5.unencrypted.close();
});
var server6 = greenlock.listen('[::]:11080', '[::1]:11443');
var server7 = greenlock.listen('/tmp/gl.plain.sock', '/tmp/gl.sec.sock');