diff --git a/src/cli/index.js b/src/cli/index.js index 2538aa74..72a1ab58 100644 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -40,6 +40,11 @@ const addOptions = { default: false, boolean: true }, + 'forward-by-proxy': { + describe: 'Proxies requests to this server rather than forwarding', + default: false, + boolean: true + }, dir: { describe: 'Server directory', string: true diff --git a/src/cli/servers.js b/src/cli/servers.js index 48320457..9828eb18 100644 --- a/src/cli/servers.js +++ b/src/cli/servers.js @@ -59,6 +59,10 @@ function add(param, opts = {}) { conf.httpProxyEnv = opts.httpProxyEnv } + if (opts.forwardByProxy) { + conf.mechanism = 'proxy' + } + if (isUrl(param)) { conf = { target: param, diff --git a/src/conf.js b/src/conf.js index 717d150d..b9912b0f 100644 --- a/src/conf.js +++ b/src/conf.js @@ -11,6 +11,7 @@ const defaults = { host: '127.0.0.1', timeout: 5000, tld: 'localhost', + mechanism: 'redirect', // Replace with your network proxy IP (1.2.3.4:5000) if any // For example, if you're behind a corporate proxy proxy: false diff --git a/src/daemon/group.js b/src/daemon/group.js index d2d60d9d..45669587 100644 --- a/src/daemon/group.js +++ b/src/daemon/group.js @@ -87,6 +87,14 @@ class Group extends EventEmitter { } } + if (conf.mechanism) { + log(`adding env.mechanism:${conf.mechanism}`) + conf.env = { + mechanism: conf.mechanism, + ...conf.env + } + } + let logFile if (conf.out) { logFile = path.resolve(conf.cwd, conf.out) @@ -322,11 +330,25 @@ class Group extends EventEmitter { redirect(req, res) { const { id } = req.params const { item } = req.hotel + let path = req.params[0] || '' // Make sure to send only one response const send = once(() => { - log(`Redirect - ${id} → ${item.target}`) - res.redirect(item.target) + let target = item.target + (item.target.endsWith('/') ? '' : '/') + path + let parsedUrl = url.parse(req.url) + if (parsedUrl.search) { + target = target + parsedUrl.search + } + + if (item.env && item.env.mechanism === 'proxy') { + // Adjusting the request is the easiest way to proxy the correct url + req.url = target + log(`Proxy - ${id} → ${target}`) + this.proxyWeb(req, res, item.target) + } else { + log(`Redirect - ${id} → ${target}`) + res.redirect(307, target) + } }) if (item.start) { diff --git a/src/daemon/routers/index.js b/src/daemon/routers/index.js index 90753c76..cf6cbf6d 100644 --- a/src/daemon/routers/index.js +++ b/src/daemon/routers/index.js @@ -16,8 +16,8 @@ module.exports = function(group) { router .get('/proxy.pac', pac) - .get( - '/:id', + .all( + ['/:id', '/:id/*'], group.exists.bind(group), group.start.bind(group), group.redirect.bind(group) diff --git a/test/cli/servers.js b/test/cli/servers.js index 49cb17fe..05366e62 100644 --- a/test/cli/servers.js +++ b/test/cli/servers.js @@ -66,6 +66,7 @@ test('add should support options', t => { env[1], '-x', '--co', + '--forward-by-proxy', '--http-proxy-env' ]) @@ -82,6 +83,7 @@ test('add should support options', t => { }, xfwd: true, changeOrigin: true, + mechanism: 'proxy', httpProxyEnv: true } diff --git a/test/daemon/app.js b/test/daemon/app.js index 3ff8d1b5..ea7acf21 100644 --- a/test/daemon/app.js +++ b/test/daemon/app.js @@ -245,7 +245,7 @@ test.cb('GET http://localhost:2000/node should redirect to node server', t => { .get('/node') .set('Host', 'localhost') .expect('location', /http:\/\/localhost:51234/) - .expect(302, t.end) + .expect(307, t.end) }) test.cb( @@ -257,7 +257,7 @@ test.cb( request(app) .get('/node') .expect('location', /http:\/\/127.0.0.1:51234/) - .expect(302, t.end) + .expect(307, t.end) } ) @@ -267,9 +267,11 @@ test.cb('GET http://localhost:2000/proxy should redirect to target', t => { .get('/proxy') .set('Host', 'localhost') .expect('location', /http:\/\/localhost:4000/) - .expect(302, t.end) + .expect(307, t.end) }) +// TODO: Add tests for forward-by-proxy cases + // // Test daemon/app.js //