all files / modules/utils/ serveApp.js

16.67% Statements 7/42
0% Branches 0/26
0% Functions 0/4
16.67% Lines 7/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108                                                                                                                                                                                                          
const http = require("http");
const https = require("https");
const bindApp = require("./bindApp");
 
/**
 * The default port that node servers bind to.
 */
const DEFAULT_PORT = 5000;
 
/**
 * Creates and starts a node HTTP server that serves the given app.
 *
 * Options may be any of the following:
 *
 * - host     The host name to accept connections on. Defaults to INADDR_ANY
 * - port     The port to listen on. Defaults to 5000
 * - socket   Unix socket file to listen on (trumps host/port)
 * - quiet    Set true to prevent the server from writing startup/shutdown
 *            messages to the console. Defaults to false
 * - timeout  The timeout to use when gracefully shutting down servers when
 *            SIGINT or SIGTERM are received. If a server doesn't close within
 *            this time (probably because it has open persistent connections)
 *            it is forecefully stopped when the process exits. Defaults to 100,
 *            meaning that servers forcefully shutdown after 100ms
 * - key      Private key to use for SSL (HTTPS only)
 * - cert     Public X509 certificate to use (HTTPS only)
 *
 * Note: When setting the timeout, be careful not to exceed any hard timeouts
 * specified by your PaaS. For example, Heroku's dyno manager will not permit
 * a timeout longer than ten seconds. See
 * https://devcenter.heroku.com/articles/dynos#graceful-shutdown-with-sigterm
 *
 * Returns the node HTTP server instance.
 */
function serveApp(app, options) {
    options = options || {};
 
    if (typeof options === "number") {
        options = {port: options};
    } else if (typeof options === "string") {
        options = {socket: options};
    }
 
    let nodeServer;
    if (options.key && options.cert) {
        nodeServer = https.createServer({key: options.key, cert: options.cert});
    } else {
        nodeServer = http.createServer();
    }
 
    function shutdown() {
        if (!options.quiet) {
            console.log(">> Shutting down...");
        }
 
    // Force the process to exit if the server doesn't
    // close all connections within the given timeout.
        const timer = setTimeout(function () {
            if (!options.quiet) {
                console.log(">> Exiting");
            }
 
            process.exit(0);
        }, options.timeout || 100);
 
    // Don't let this timer keep the event loop running.
        timer.unref();
 
        nodeServer.close();
    }
 
    nodeServer.once("listening", function () {
        bindApp(app, nodeServer);
 
        process.once("SIGINT", shutdown);
        process.once("SIGTERM", shutdown);
 
        if (!options.quiet) {
            const address = nodeServer.address();
            let message = `>> mach web server started on node ${process.versions.node}\n"`;
 
            if (typeof address === "string") {
                message += `>> Listening on ${address}`;
            } else {
                message += `>> Listening on ${address.address}`;
 
                if (address.port) {
                    message += `:${address.port}`;
                }
            }
 
            message += ", use CTRL+C to stop";
 
            console.log(message);
        }
    });
 
    if (options.socket) {
        nodeServer.listen(options.socket);
    } else {
        nodeServer.listen(options.port || DEFAULT_PORT, options.host);
    }
 
    return nodeServer;
}
 
module.exports = serveApp;