greenlock-express.js/index.js

148 lines
4.4 KiB
JavaScript
Raw Normal View History

2016-08-10 17:10:00 +00:00
'use strict';
2018-06-29 09:24:58 +00:00
var PromiseA;
try {
PromiseA = require('bluebird');
} catch(e) {
PromiseA = global.Promise;
}
2016-08-12 07:02:33 +00:00
// opts.approveDomains(options, certs, cb)
2016-08-10 17:10:00 +00:00
module.exports.create = function (opts) {
// accept all defaults for greenlock.challenges, greenlock.store, greenlock.middleware
2018-08-17 02:45:31 +00:00
if (!opts._communityPackage) {
opts._communityPackage = 'greenlock-express.js';
}
2016-08-16 01:15:16 +00:00
2018-08-17 02:45:31 +00:00
function explainError(e) {
console.error('Error:' + e.message);
if ('EACCES' === e.errno) {
console.error("You don't have prmission to access '" + e.address + ":" + e.port + "'.");
console.error("You probably need to use \"sudo\" or \"sudo setcap 'cap_net_bind_service=+ep' $(which node)\"");
return;
2016-08-10 17:10:00 +00:00
}
2018-08-17 02:45:31 +00:00
if ('EADDRINUSE' === e.errno) {
console.error("'" + e.address + ":" + e.port + "' is already being used by some other program.");
console.error("You probably need to stop that program or restart your computer.");
return;
2016-08-16 01:15:16 +00:00
}
2018-08-17 02:45:31 +00:00
console.error(e.code + ": '" + e.address + ":" + e.port + "'");
}
2016-08-10 17:10:00 +00:00
function _listenHttp(plainPort) {
2018-08-17 02:45:31 +00:00
if (!plainPort) { plainPort = 80; }
var p = plainPort;
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(
greenlock.middleware.sanitizeHost(greenlock.middleware(require('redirect-https')()))
);
var promise = new PromiseA(function (resolve) {
plainServer.listen(p, function () {
resolve(plainServer);
2018-08-17 02:45:31 +00:00
}).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);
}
2018-08-17 02:45:31 +00:00
});
2016-08-10 17:10:00 +00:00
});
2018-08-17 02:45:31 +00:00
promise.server = plainServer;
return promise;
}
function _listenHttps(port) {
2018-08-17 02:45:31 +00:00
if (!port) { port = 443; }
2016-08-10 17:10:00 +00:00
2018-08-17 02:45:31 +00:00
var p = port;
var validHttpsPort = (parseInt(p, 10) >= 0);
var httpType;
2018-08-17 02:45:31 +00:00
if (!validHttpsPort) { console.warn("'" + p + "' doesn't seem to be a valid port number for https"); }
var https;
try {
https = require('spdy');
greenlock.tlsOptions.spdy = { protocols: [ 'h2', 'http/1.1' ], plain: false };
httpType = 'http2 (spdy/h2)';
2018-08-17 02:45:31 +00:00
} catch(e) {
https = require('https');
httpType = 'https';
2018-08-17 02:45:31 +00:00
}
var server = https.createServer(
greenlock.tlsOptions
, greenlock.middleware.sanitizeHost(function (req, res) {
try {
2018-08-17 02:45:31 +00:00
greenlock.app(req, res);
} catch(e) {
2018-08-17 02:45:31 +00:00
console.error("[error] [greenlock.app] Your HTTP handler had an uncaught error:");
console.error(e);
}
2018-08-17 02:45:31 +00:00
})
);
server.type = httpType;
2018-08-17 02:45:31 +00:00
var promise = new PromiseA(function (resolve) {
server.listen(p, function () {
resolve(server);
}).on('error', function (e) {
if (server.listenerCount('error') < 2) {
console.warn("Did not successfully create https server and bind to port '" + p + "':");
explainError(e);
process.exit(43);
}
2018-08-17 02:45:31 +00:00
});
2016-08-16 01:15:16 +00:00
});
2018-08-17 02:45:31 +00:00
promise.server = server;
return promise;
}
2016-08-11 07:07:20 +00:00
2018-08-17 02:45:31 +00:00
var greenlock = require('greenlock').create(opts);
2016-08-10 17:10:00 +00:00
2018-08-17 02:45:31 +00:00
opts.app = opts.app || function (req, res) {
res.end("Hello, World!\nWith Love,\nGreenlock for Express.js");
};
opts.listen = function (plainPort, port, fn1, fn2) {
2018-08-17 02:45:31 +00:00
var promises = [];
var server;
var plainServer;
var fn;
var fnPlain;
if (fn2) {
fn = fn2;
fnPlain = fn1;
} else {
fn = fn1;
}
promises.push(_listenHttp(plainPort, !fnPlain));
promises.push(_listenHttps(port, !fn));
server = promises[1].server;
plainServer = promises[0].server;
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
if ('function' === typeof fnPlain) {
fnPlain.apply(plainServer);
} else if (!fn && plainServer.listenerCount('listening') < 2) {
console.info("Success! Bound to port '" + plainServer.address().port
+ "' to handle ACME challenges and redirect to " + server.type);
}
});
server.unencrypted = plainServer;
return server;
2016-08-10 17:10:00 +00:00
};
2016-08-16 01:15:16 +00:00
return greenlock;
2016-08-10 17:10:00 +00:00
};