diff --git a/lib/node-http-proxy/proxy-table.js b/lib/node-http-proxy/proxy-table.js index b12b577..87184e8 100644 --- a/lib/node-http-proxy/proxy-table.js +++ b/lib/node-http-proxy/proxy-table.js @@ -34,6 +34,7 @@ var util = require('util'), // #### @router {Object} Object containing the host based routes // #### @silent {Boolean} Value indicating whether we should suppress logs // #### @hostnameOnly {Boolean} Value indicating if we should route based on __hostname string only__ +// #### @pathnameOnly {Boolean} Value indicating if we should route based on only the pathname. __This causes hostnames to be ignored.__. Using this along with hostnameOnly wont work at all. // Constructor function for the ProxyTable responsible for getting // locations of proxy targets based on ServerRequest headers; specifically // the HTTP host header. @@ -43,6 +44,7 @@ var ProxyTable = exports.ProxyTable = function (options) { this.silent = options.silent || options.silent !== true; this.target = options.target || {}; + this.pathnameOnly = options.pathnameOnly === true; this.hostnameOnly = options.hostnameOnly === true; if (typeof options.router === 'object') { @@ -164,8 +166,9 @@ ProxyTable.prototype.getProxyLocation = function (req) { return null; } - var target = req.headers.host.split(':')[0]; + var targetHost = req.headers.host.split(':')[0]; if (this.hostnameOnly === true) { + var target = targetHost; if (this.router.hasOwnProperty(target)) { var location = this.router[target].split(':'), host = location[0], @@ -177,8 +180,24 @@ ProxyTable.prototype.getProxyLocation = function (req) { }; } } + else if (this.pathnameOnly === true) { + var target = req.url; + for (var i in this.routes) { + var route = this.routes[i]; + if (target.match(route.source.regexp)) { + req.url = url.format(target.replace(route.source.regexp, '')); + return { + protocol: route.target.url.protocol.replace(':', ''), + host: route.target.url.hostname, + port: route.target.url.port + || (this.target.https ? 443 : 80) + }; + } + } + + } else { - target += req.url; + var target = targetHost + req.url; for (var i in this.routes) { var route = this.routes[i]; if (target.match(route.source.regexp)) { diff --git a/test/http/routing-table-test.js b/test/http/routing-table-test.js index f758bba..679c286 100644 --- a/test/http/routing-table-test.js +++ b/test/http/routing-table-test.js @@ -43,6 +43,14 @@ vows.describe(helpers.describe('routing-table')).addBatch({ "bar.com": "127.0.0.1:{PORT}" } }), + "using pathnameOnly": macros.http.assertProxiedToRoutes({ + pathnameOnly: true, + routes: { + "/foo": "127.0.0.1:{PORT}", + "/bar": "127.0.0.1:{PORT}", + "/pizza": "127.0.0.1:{PORT}" + } + }), "using a routing file": macros.http.assertProxiedToRoutes({ filename: routeFile, routes: { diff --git a/test/macros/http.js b/test/macros/http.js index 61c9cd1..108fa98 100644 --- a/test/macros/http.js +++ b/test/macros/http.js @@ -262,6 +262,7 @@ exports.assertProxiedToRoutes = function (options, nested) { // proxy = { hostnameOnly: options.hostnameOnly, + pathnameOnly: options.pathnameOnly, router: options.routes }; }