goldilocks.js/lib/modules/http.js

96 lines
2.7 KiB
JavaScript
Raw Normal View History

2017-04-27 22:05:34 +00:00
'use strict';
module.exports.create = function (deps, conf) {
2017-05-09 20:16:21 +00:00
var app = require('express')();
var adminApp = require('./admin').create(deps, conf);
2017-05-09 20:16:21 +00:00
var domainMatches = require('../match-domain').match;
var adminDomains = [
/\blocalhost\.admin\./
, /\blocalhost\.alpha\./
, /\badmin\.localhost\./
, /\balpha\.localhost\./
];
2017-05-09 20:16:21 +00:00
// We handle both HTTPS and HTTP traffic on the same ports, and we want to redirect
// any unencrypted requests to the same port they came from unless it came in on
// the default HTTP port, in which case there wont be a port specified in the host.
var redirecters = {};
function redirectHttps(req, res, next) {
var port = req.headers.host.split(':')[1];
var redirecter = redirecters[port];
if (!redirecter) {
redirecter = redirecters[port] = require('redirect-https')({port: port});
}
redirecter(req, res, next);
}
function handleAdmin(req, res, next) {
var admin = adminDomains.some(function (re) {
return re.test(req.headers.host);
});
if (admin) {
adminApp(req, res);
} else {
next();
}
}
2017-05-09 20:16:21 +00:00
function respond404(req, res) {
res.writeHead(404);
res.end('Not Found');
}
function createProxyRoute(mod) {
// This is the easiest way to override the createConnections function the proxy
// module uses, but take note the since we don't have control over where this is
// called the extra options availabled will be different.
var agent = new require('http').Agent({});
agent.createConnection = deps.net.createConnection;
var proxy = require('http-proxy').createProxyServer({
agent: agent
, target: 'http://' + mod.address
, xfwd: true
, toProxy: true
});
2017-04-27 22:05:34 +00:00
// We want to override the default value for some headers with the extra information we
// have available to us in the opts object attached to the connection.
proxy.on('proxyReq', function (proxyReq, req) {
var conn = req.connection;
var opts = conn.__opts;
proxyReq.setHeader('X-Forwarded-For', opts.remoteAddress || conn.remoteAddress);
});
2017-05-09 20:16:21 +00:00
return function (req, res, next) {
var hostname = req.headers.host.split(':')[0];
var relevant = mod.domains.some(function (pattern) {
return domainMatches(pattern, hostname);
});
if (relevant) {
proxy.web(req, res);
} else {
next();
}
};
}
2017-04-27 22:05:34 +00:00
2017-05-09 20:16:21 +00:00
app.use(redirectHttps);
app.use(handleAdmin);
2017-05-09 20:16:21 +00:00
(conf.http.modules || []).forEach(function (mod) {
if (mod.name === 'proxy') {
app.use(createProxyRoute(mod));
}
2017-05-09 20:16:21 +00:00
else {
console.warn('unknown HTTP module', mod);
}
});
app.use(respond404);
return require('http').createServer(app);
2017-04-27 22:05:34 +00:00
};