diff --git a/README.md b/README.md index d6c7201b..bb190642 100644 --- a/README.md +++ b/README.md @@ -172,8 +172,11 @@ E.g., ```js function coinToss() { return Math.random() > .5 } - function getHost() { return coinToss() ? 'http://yahoo.com' : 'http://google.com' } - + function getHost() { + var host = coinToss() ? 'http://yahoo.com' : 'http://google.com'; + return coinToss() ? Promise.resolve(host) : host; + } + app.use(proxy(getHost, { memoizeHost: false })) @@ -451,7 +454,7 @@ app.use('/', proxy('internalhost.example.com', { proxyReqOpts.ca = [caCert, intermediaryCert] return proxyReqOpts; } -}) +})) ``` diff --git a/app/steps/resolveProxyHost.js b/app/steps/resolveProxyHost.js index 181dda7a..4d64bdb8 100644 --- a/app/steps/resolveProxyHost.js +++ b/app/steps/resolveProxyHost.js @@ -2,18 +2,20 @@ var requestOptions = require('../../lib/requestOptions'); function resolveProxyHost(container) { - var parsedHost; + var promise; if (container.options.memoizeHost && container.options.memoizedHost) { - parsedHost = container.options.memoizedHost; + promise = Promise.resolve(container.options.memoizedHost); } else { - parsedHost = requestOptions.parseHost(container); + promise = Promise.resolve(requestOptions.parseHost(container)); } - container.proxy.reqBuilder.host = parsedHost.host; - container.proxy.reqBuilder.port = container.options.port || parsedHost.port; - container.proxy.requestModule = parsedHost.module; - return Promise.resolve(container); + return promise.then(function(parsedHost) { + container.proxy.reqBuilder.host = parsedHost.host; + container.proxy.reqBuilder.port = container.options.port || parsedHost.port; + container.proxy.requestModule = parsedHost.module; + return container; + }); } module.exports = resolveProxyHost; diff --git a/lib/requestOptions.js b/lib/requestOptions.js index 3f02a4e5..78b588e8 100644 --- a/lib/requestOptions.js +++ b/lib/requestOptions.js @@ -24,29 +24,34 @@ function parseHost(Container) { var host = Container.params.host; var req = Container.user.req; var options = Container.options; - host = (typeof host === 'function') ? host(req) : host.toString(); - - if (!host) { - return new Error('Empty host parameter'); - } - - if (!/http(s)?:\/\//.test(host)) { - host = 'http://' + host; - } - - var parsed = url.parse(host); - - if (!parsed.hostname) { - return new Error('Unable to parse hostname, possibly missing protocol://?'); - } - - var ishttps = options.https || parsed.protocol === 'https:'; - - return { - host: parsed.hostname, - port: parsed.port || (ishttps ? 443 : 80), - module: ishttps ? https : http, - }; + host = (typeof host === 'function') ? host(req) : host; + + return Promise + .resolve(host) + .then(function(host) { + if (!host) { + throw new Error('Empty host parameter'); + } + host = host.toString(); + + if (!/http(s)?:\/\//.test(host)) { + host = 'http://' + host; + } + + var parsed = url.parse(host); + + if (!parsed.hostname) { + return new Error('Unable to parse hostname, possibly missing protocol://?'); + } + + var ishttps = options.https || parsed.protocol === 'https:'; + + return { + host: parsed.hostname, + port: parsed.port || (ishttps ? 443 : 80), + module: ishttps ? https : http, + }; + }); } function reqHeaders(req, options) { diff --git a/test/host.js b/test/host.js index 73d3e3d0..caad69e7 100644 --- a/test/host.js +++ b/test/host.js @@ -45,3 +45,29 @@ describe('host can be a dynamic function', function() { }); }); }); + +describe('host is a promise', function() { + + this.timeout(10000); + + var app = express(); + var proxyApp = express(); + var port = Math.floor(Math.random() * 10000); + + var hostFn = function(req) { + return Promise.resolve('localhost:' + req.params.port); + }; + + app.use('/proxy-promise/:port', proxy(hostFn, { memoizeHost: false })); + + proxyApp + .get('/', function(req, res) { res.sendStatus(201); }) + .listen(port); + + it('host returns a promise that should be resolved and its value is the host URL.', function(done) { + request(app) + .get('/proxy-promise/' + port) + .expect(201) + .end(done); + }); +});