From 6f960b1a2a1c2045e3fa099af49056519f0498e8 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 17 Aug 2018 19:58:50 -0600 Subject: [PATCH] v2.4.0: listen() now returns secure server instance --- README.md | 6 +++++- examples/normal.js | 1 - examples/production.js | 8 +++++--- examples/simple.js | 1 - index.js | 46 ++++++++++++++++++++++++++++++------------ package.json | 6 +++--- test/greenlock.js | 41 +++++++++++++++++++++++++++++++++++++ 7 files changed, 87 insertions(+), 22 deletions(-) delete mode 120000 examples/normal.js delete mode 120000 examples/simple.js create mode 100644 test/greenlock.js diff --git a/README.md b/README.md index 630e180..9d7e6b4 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,10 @@ var glx = require('greenlock-express').create({ , approveDomains: approveDomains }); + +var server = glx.listen(80, 443, function () { + console.log("Listening on port 80 for ACME challenges and 443 for express app."); +}); ``` The Automatic Certificate Issuance is initiated via SNI (`httpsOptions.SNICallback`). @@ -397,7 +401,7 @@ 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: * `opts.app` An express app in the format `function (req, res) { ... }` (no `next`). -* `glx.listen(plainPort, tlsPort)` Accepts port numbers (or arrays of port numbers) to listen on. +* `server = glx.listen(plainPort, tlsPort)` Accepts port numbers (or arrays of port numbers) to listen on, returns secure server. Brief overview of some simple options for `greenlock.js`: diff --git a/examples/normal.js b/examples/normal.js deleted file mode 120000 index ff7f8cb..0000000 --- a/examples/normal.js +++ /dev/null @@ -1 +0,0 @@ -production.js \ No newline at end of file diff --git a/examples/production.js b/examples/production.js index c9e1da3..e25a2d3 100644 --- a/examples/production.js +++ b/examples/production.js @@ -3,8 +3,8 @@ // // My Secure Server // -//require('greenlock-express') -require('../').create({ +//var greenlock = require('greenlock-express') +var greenlock = require('../').create({ // Let's Encrypt v2 is ACME draft 11 // Note: If at first you don't succeed, stop and switch to staging @@ -30,7 +30,9 @@ require('../').create({ //, debug: true -}).listen(80, 443); +}); + +var server = greenlock.listen(80, 443); // diff --git a/examples/simple.js b/examples/simple.js deleted file mode 120000 index 25cd5e6..0000000 --- a/examples/simple.js +++ /dev/null @@ -1 +0,0 @@ -quickstart.js \ No newline at end of file diff --git a/index.js b/index.js index 1b6f0d0..41ece89 100644 --- a/index.js +++ b/index.js @@ -29,7 +29,7 @@ module.exports.create = function (opts) { console.error(e.code + ": '" + e.address + ":" + e.port + "'"); } - function _listenHttp(plainPort) { + function _listenHttp(plainPort, sayAnything) { if (!plainPort) { plainPort = 80; } var p = plainPort; var validHttpPort = (parseInt(p, 10) >= 0); @@ -39,19 +39,23 @@ module.exports.create = function (opts) { ); var promise = new PromiseA(function (resolve) { plainServer.listen(p, function () { - console.log("Success! Bound to port '" + p + "' to handle ACME challenges and redirect to https"); + if (sayAnything) { + console.info("Success! Bound to port '" + p + "' to handle ACME challenges and redirect to https"); + } resolve(); }).on('error', function (e) { - console.log("Did not successfully create http server and bind to port '" + p + "':"); - explainError(e); - process.exit(0); + 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 _listenHttps(port, sayAnything) { if (!port) { port = 443; } var p = port; @@ -77,12 +81,16 @@ module.exports.create = function (opts) { ); var promise = new PromiseA(function (resolve) { server.listen(p, function () { - console.log("Success! Serving https on port '" + p + "'"); + if (sayAnything) { + console.info("Success! Serving https on port '" + p + "'"); + } resolve(server); }).on('error', function (e) { - console.log("Did not successfully create https server and bind to port '" + p + "':"); - explainError(e); - process.exit(0); + if (server.listenerCount('error') < 2) { + console.warn("Did not successfully create https server and bind to port '" + p + "':"); + explainError(e); + process.exit(43); + } }); }); promise.server = server; @@ -95,10 +103,22 @@ module.exports.create = function (opts) { res.end("Hello, World!\nWith Love,\nGreenlock for Express.js"); }; - opts.listen = function (plainPort, port) { + opts.listen = function (plainPort, port, fn) { var promises = []; - promises.push(_listenHttp(plainPort)); - promises.push(_listenHttps(port)); + var server; + + promises.push(_listenHttp(plainPort, !fn)); + promises.push(_listenHttps(port, !fn)); + + server = promises[1].server; + PromiseA.all(promises).then(function () { + if ('function' === typeof fn) { + fn.apply(server); + } + return server; + }); + + return server; }; diff --git a/package.json b/package.json index 188e79d..7135200 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "greenlock-express", - "version": "2.3.4", + "version": "2.4.0", "description": "Free SSL and managed or automatic HTTPS for node.js with Express, Koa, Connect, Hapi, and all other middleware systems.", "main": "index.js", "homepage": "https://git.coolaj86.com/coolaj86/greenlock-express.js", @@ -8,7 +8,7 @@ "example": "examples" }, "dependencies": { - "greenlock": "^2.3.10", + "greenlock": "^2.3.11", "le-challenge-fs": "^2.0.8", "le-sni-auto": "^2.1.4", "le-store-certbot": "^2.1.0", @@ -29,7 +29,7 @@ "ws": "^5.2.1" }, "scripts": { - "test": "node examples/simple.js" + "test": "node test/greenlock.js" }, "repository": { "type": "git", diff --git a/test/greenlock.js b/test/greenlock.js new file mode 100644 index 0000000..f552ae3 --- /dev/null +++ b/test/greenlock.js @@ -0,0 +1,41 @@ +#!/usr/bin/env node +var Greenlock = require('../'); +var greenlock = Greenlock.create({ + version: 'draft-11' +, server: 'https://acme-staging-v02.api.letsencrypt.org/directory' +, agreeTos: true +, approveDomains: [ 'example.com', 'www.example.com' ] +, configDir: require('path').join(require('os').tmpdir(), 'acme') + +, app: require('express')().use('/', function (req, res) { + res.setHeader('Content-Type', 'text/html; charset=utf-8'); + res.end('Hello, World!\n\nšŸ’š šŸ”’.js'); + }) +}); + +var server1 = greenlock.listen(5080, 5443); +server1.on('listening', function () { + console.log("### THREE 3333 - All is well server1", this.address()); + server1.close(); +}); +setTimeout(function () { + var server2 = greenlock.listen(6080, 6443, function () { + console.log("### FIVE 55555 - Started server 2!"); + setTimeout(function () { + server2.close(); + // TODO greenlock needs a close event (and to listen to its server's close event) + process.exit(0); + }, 1000); + }); + server2.on('listening', function () { + console.log("### FOUR 44444 - All is well server2", server2.address()); + }); +}, 1000); + +var server3 = greenlock.listen(7080, 22, function () { + // ignore +}); +server3.on('error', function () { + console.log("Success: caught expected error"); + server3.close(); +});