implemented more dynamic HTTP proxying

This commit is contained in:
tigerbot 2017-05-09 14:16:21 -06:00
parent b3b407d161
commit ab31bae6ff
4 changed files with 77 additions and 42 deletions

View File

@ -19,22 +19,7 @@ module.exports.create = function (deps, config) {
var secureContexts = {}; var secureContexts = {};
var tunnelAdminTlsOpts = {}; var tunnelAdminTlsOpts = {};
var tls = require('tls'); var tls = require('tls');
var domainMatches = require('./match-domain').match;
function domainMatches(pattern, servername) {
// Everything matches '*'
if (pattern === '*') {
return true;
}
if (/^\*./.test(pattern)) {
// get rid of the leading "*." to more easily check the servername against it
pattern = pattern.slice(2);
return pattern === servername.slice(-pattern.length);
}
// pattern doesn't contains any wildcards, so exact match is required
return pattern === servername;
}
var tcpRouter = { var tcpRouter = {
_map: { } _map: { }

17
lib/match-domain.js Normal file
View File

@ -0,0 +1,17 @@
'use strict';
module.exports.match = function (pattern, servername) {
// Everything matches '*'
if (pattern === '*') {
return true;
}
if (/^\*./.test(pattern)) {
// get rid of the leading "*." to more easily check the servername against it
pattern = pattern.slice(2);
return pattern === servername.slice(-pattern.length);
}
// pattern doesn't contains any wildcards, so exact match is required
return pattern === servername;
};

View File

@ -1,34 +1,66 @@
'use strict'; 'use strict';
module.exports.create = function (deps, conf) { module.exports.create = function (deps, conf) {
// This should be able to handle things like default web path (i.e. /srv/www/hostname), var app = require('express')();
// no-www redirect, and transpilation of static assets (i.e. cached versions of raw html) var domainMatches = require('../match-domain').match;
// but right now it's a very dumb proxy
function createConnection(conn) { // We handle both HTTPS and HTTP traffic on the same ports, and we want to redirect
var opts = conn.__opts; // any unencrypted requests to the same port they came from unless it came in on
var newConn = deps.net.createConnection({ // the default HTTP port, in which case there wont be a port specified in the host.
port: conf.http.proxy.port var redirecters = {};
, host: '127.0.0.1' function redirectHttps(req, res, next) {
var port = req.headers.host.split(':')[1];
, servername: opts.servername var redirecter = redirecters[port];
, data: opts.data if (!redirecter) {
, remoteFamily: opts.family || conn.remoteFamily redirecter = redirecters[port] = require('redirect-https')({port: port});
, remoteAddress: opts.address || conn.remoteAddress }
, remotePort: opts.port || conn.remotePort redirecter(req, res, next);
}, function () {
//console.log("[=>] first packet from tunneler to '" + cid + "' as '" + opts.service + "'", opts.data.byteLength);
// this will happen before 'data' is triggered
//newConn.write(opts.data);
});
newConn.pipe(conn);
conn.pipe(newConn);
} }
return { function respond404(req, res) {
emit: function (type, conn) { res.writeHead(404);
createConnection(conn); 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
});
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();
}
};
}
app.use(redirectHttps);
(conf.http.modules || []).forEach(function (mod) {
if (mod.name === 'proxy') {
app.use(createProxyRoute(mod));
} }
}; else {
console.warn('unknown HTTP module', mod);
}
});
app.use(respond404);
return require('http').createServer(app);
}; };

View File

@ -47,6 +47,7 @@
"finalhandler": "^0.4.0", "finalhandler": "^0.4.0",
"greenlock": "git+https://git.daplie.com/Daplie/node-greenlock.git#master", "greenlock": "git+https://git.daplie.com/Daplie/node-greenlock.git#master",
"greenlock-express": "git+https://git.daplie.com/Daplie/greenlock-express.git#master", "greenlock-express": "git+https://git.daplie.com/Daplie/greenlock-express.git#master",
"http-proxy": "^1.16.2",
"httpolyglot": "^0.1.1", "httpolyglot": "^0.1.1",
"ipaddr.js": "git+https://github.com/whitequark/ipaddr.js.git#v1.3.0", "ipaddr.js": "git+https://github.com/whitequark/ipaddr.js.git#v1.3.0",
"ipify": "^1.1.0", "ipify": "^1.1.0",