implemented more dynamic HTTP proxying
This commit is contained in:
parent
b3b407d161
commit
ab31bae6ff
|
@ -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: { }
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue