pad.libre-service.eu-etherpad/src/node/hooks/express.js
Richard Hansen a000a93dc6 Refactor startup/shutdown for tests
* `src/node/server.js` can now be run as a script (for normal
    operation) or imported as a module (for tests).
  * Move shutdown actions to `src/node/server.js` to be close to the
    startup actions.
  * Put startup and shutdown in functions so that tests can call them.
  * Use `await` instead of callbacks.
  * Block until the HTTP server is listening to avoid races during
    test startup.
  * Add a new `shutdown` hook.
  * Use the `shutdown` hook to:
      * close the HTTP server
      * call `end()` on the stats collection to cancel its timers
      * call `terminate()` on the Threads.Pool to stop the workers
  * Exit with exit code 0 (instead of 1) on SIGTERM.
  * Export the HTTP server so that tests can get the HTTP server's
    port via `server.address().port` when `settings.port` is 0.
2020-09-22 11:07:21 +01:00

123 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var express = require('express');
var settings = require('../utils/Settings');
var fs = require('fs');
var path = require('path');
var npm = require("npm/lib/npm.js");
var _ = require("underscore");
const util = require('util');
var serverName;
exports.server = null;
exports.createServer = async () => {
console.log("Report bugs at https://github.com/ether/etherpad-lite/issues")
serverName = `Etherpad ${settings.getGitCommit()} (https://etherpad.org)`;
console.log(`Your Etherpad version is ${settings.getEpVersion()} (${settings.getGitCommit()})`);
await exports.restartServer();
if (settings.ip === "") {
// using Unix socket for connectivity
console.log(`You can access your Etherpad instance using the Unix socket at ${settings.port}`);
} else {
console.log(`You can access your Etherpad instance at http://${settings.ip}:${settings.port}/`);
}
if (!_.isEmpty(settings.users)) {
console.log(`The plugin admin page is at http://${settings.ip}:${settings.port}/admin/plugins`);
} else {
console.warn("Admin username and password not set in settings.json. To access admin please uncomment and edit 'users' in settings.json");
}
var env = process.env.NODE_ENV || 'development';
if (env !== 'production') {
console.warn("Etherpad is running in Development mode. This mode is slower for users and less secure than production mode. You should set the NODE_ENV environment variable to production by using: export NODE_ENV=production");
}
}
exports.restartServer = async () => {
if (exports.server) {
console.log("Restarting express server");
await util.promisify(exports.server.close).bind(exports.server)();
}
var app = express(); // New syntax for express v3
if (settings.ssl) {
console.log("SSL -- enabled");
console.log(`SSL -- server key file: ${settings.ssl.key}`);
console.log(`SSL -- Certificate Authority's certificate file: ${settings.ssl.cert}`);
var options = {
key: fs.readFileSync( settings.ssl.key ),
cert: fs.readFileSync( settings.ssl.cert )
};
if (settings.ssl.ca) {
options.ca = [];
for (var i = 0; i < settings.ssl.ca.length; i++) {
var caFileName = settings.ssl.ca[i];
options.ca.push(fs.readFileSync(caFileName));
}
}
var https = require('https');
exports.server = https.createServer(options, app);
} else {
var http = require('http');
exports.server = http.createServer(app);
}
app.use(function(req, res, next) {
// res.header("X-Frame-Options", "deny"); // breaks embedded pads
if (settings.ssl) {
// we use SSL
res.header("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
}
// Stop IE going into compatability mode
// https://github.com/ether/etherpad-lite/issues/2547
res.header("X-UA-Compatible", "IE=Edge,chrome=1");
// Enable a strong referrer policy. Same-origin won't drop Referers when
// loading local resources, but it will drop them when loading foreign resources.
// It's still a last bastion of referrer security. External URLs should be
// already marked with rel="noreferer" and user-generated content pages are already
// marked with <meta name="referrer" content="no-referrer">
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
// https://github.com/ether/etherpad-lite/pull/3636
res.header("Referrer-Policy", "same-origin");
// send git version in the Server response header if exposeVersion is true.
if (settings.exposeVersion) {
res.header("Server", serverName);
}
next();
});
if (settings.trustProxy) {
/*
* If 'trust proxy' === true, the clients IP address in req.ip will be the
* left-most entry in the X-Forwarded-* header.
*
* Source: https://expressjs.com/en/guide/behind-proxies.html
*/
app.enable('trust proxy');
}
hooks.callAll("expressConfigure", {"app": app});
hooks.callAll('expressCreateServer', {app, server: exports.server});
await util.promisify(exports.server.listen).bind(exports.server)(settings.port, settings.ip);
};
exports.shutdown = async (hookName, context) => {
if (!exports.server) return;
await util.promisify(exports.server.close).bind(exports.server)();
};