all files / blackbird/modules/utils/ createConnection.js

20.93% Statements 9/43
0% Branches 0/27
0% Functions 0/4
20.93% Lines 9/43
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                                                                                                                                                                        
const Connection = require("../Connection");
const Location = require("../Location");
const R = require("ramda");
const config = require("../../config");
 
/**
 * Standard ports for HTTP protocols.
 */
const STANDARD_PORTS = {
    "http:": "80",
    "https:": "443"
};
 
function ensureTrailingColon(string) {
    return string[string.length - 1] === ":" ? string : `${string}:`;
}
 
/**
 * Creates a new Location object that is reverse-proxy aware.
 */
function createLocation(nodeRequest) {
    const headers = nodeRequest.headers;
 
    let protocol;
    if (config.https === "on" || headers["x-forwarded-ssl"] === "on" || headers["font-end-https"] === "on") {
        protocol = "https:";
    } else if (headers["x-url-scheme"]) {
        protocol = ensureTrailingColon(headers["x-url-scheme"]);
    } else if (headers["x-forwarded-protocol"]) {
        protocol = ensureTrailingColon(headers["x-forwarded-protocol"].split(",")[0]);
    } else if (headers["x-forwarded-proto"]) {
        protocol = ensureTrailingColon(headers["x-forwarded-proto"].split(",")[0]);
    } else {
        protocol = "http:";
    }
 
    let host;
    if (headers["x-forwarded-host"]) {
        const hosts = headers["x-forwarded-host"].split(/,\s?/);
        host = hosts[hosts.length - 1];
    } else if (headers.host) {
        host = headers.host;
    } else if (config.serverName) {
        host = config.serverName;
    }
 
    const hostParts = host.split(":", 2);
    const hostname = hostParts[0];
    let port = hostParts[1] || headers["x-forwarded-port"];
 
    if (R.isNil(port)) {
        if (headers["x-forwarded-host"]) {
            port = STANDARD_PORTS[protocol];
        } else if (headers["x-forwarded-proto"]) {
            port = STANDARD_PORTS[headers["x-forwarded-proto"].split(",")[0]];
        }
    }
 
    const path = nodeRequest.url;
 
    return new Location({
        protocol,
        hostname,
        port,
        path
    });
}
 
/**
 * Creates a mach.Connection from the given node.js HTTP request and
 * server (optional) objects. This is a low-level method that is not
 * generally needed by application-level code.
 */
function createConnection(nodeRequest) {
    const conn = new Connection({
        version: nodeRequest.httpVersion,
        method: nodeRequest.method,
        location: createLocation(nodeRequest),
        headers: nodeRequest.headers,
        content: nodeRequest,
        remoteHost: nodeRequest.connection.remoteAddress,
        remotePort: nodeRequest.connection.remotePort
    });
 
    nodeRequest.on("close", function () {
        conn.onClose();
    });
 
    return conn;
}
 
module.exports = createConnection;