Skip to content

Commit

Permalink
feat(router): deprecate and rename proxyTable option to router
Browse files Browse the repository at this point in the history
  • Loading branch information
chimurai committed Jun 11, 2016
1 parent 2ae1e03 commit 009f90d
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 51 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## [develop](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.16.0)
- feat(router): deprecate and renamed `proxyTable` option to `router`

## [v0.15.2](https://github.com/chimurai/http-proxy-middleware/releases/tag/v0.15.2)
- fix(websocket): fixes websocket upgrade

Expand Down
19 changes: 19 additions & 0 deletions lib/config-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ function createConfig(context, opts) {
// Legacy option.proxyHost
config.options = mapLegacyProxyHostOption(config.options);

// Legacy option.proxyTable > option.router
config.options = mapLegacyProxyTableOption(config.options);

return config;
}

Expand Down Expand Up @@ -96,6 +99,22 @@ function mapLegacyProxyHostOption(options) {
return options;
}

// Warn deprecated proxyTable api usage
function mapLegacyProxyTableOption(options) {
if (options.proxyTable) {
logger.warn('*************************************');
logger.warn('[HPM] Deprecated "option.proxyTable"');
logger.warn(' Use "option.router" instead');
logger.warn(' "option.proxyTable" will be removed in future release.');
logger.warn('*************************************');

options.router = _.clone(options.proxyTable);
_.omit(options, 'proxyTable');
}

return options;
}

function configureLogger(options) {
if (options.logLevel) {
logger.setLevel(options.logLevel);
Expand Down
20 changes: 10 additions & 10 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var configFactory = require('./config-factory');
var handlers = require('./handlers');
var contextMatcher = require('./context-matcher');
var PathRewriter = require('./path-rewriter');
var ProxyTable = require('./proxy-table');
var Router = require('./router');
var logger = require('./logger').getInstance();
var getArrow = require('./logger').getArrow;

Expand All @@ -17,7 +17,7 @@ function HttpProxyMiddleware(context, opts) {
var proxyOptions = config.options;

// create proxy
var proxy = httpProxy.createProxyServer(proxyOptions);
var proxy = httpProxy.createProxyServer({});
logger.info('[HPM] Proxy created:', config.context, ' -> ', proxyOptions.target);

var pathRewriter = PathRewriter.create(proxyOptions.pathRewrite); // returns undefined when "pathRewrite" is not provided
Expand Down Expand Up @@ -63,19 +63,19 @@ function HttpProxyMiddleware(context, opts) {
}

/**
* Apply option.proxyTable and option.pathRewrite
* Apply option.router and option.pathRewrite
* Order matters:
ProxyTable uses original path for routing;
Router uses original path for routing;
NOT the modified path, after it has been rewritten by pathRewrite
*/
function prepareProxyRequest(req) {
// store uri before it gets rewritten for logging
var originalPath = req.url;

// Apply in order:
// 1. option.proxyTable
// 1. option.router
// 2. option.pathRewrite
var alteredProxyOptions = __applyProxyTableOption(req, proxyOptions);
var alteredProxyOptions = __applyRouterOption(req, proxyOptions);
__applyPathRewrite(pathRewriter, req);

// debug logging for both http(s) and websockets
Expand All @@ -87,13 +87,13 @@ function HttpProxyMiddleware(context, opts) {
return alteredProxyOptions;
}

// Modify option.target when proxyTable present.
// Modify option.target when router present.
// return altered options
function __applyProxyTableOption(req) {
function __applyRouterOption(req) {
var result = proxyOptions;

if (proxyOptions.proxyTable) {
result = ProxyTable.createProxyOptions(req, proxyOptions);
if (proxyOptions.router) {
result = Router.createProxyOptions(req, proxyOptions);
}

return result;
Expand Down
2 changes: 1 addition & 1 deletion lib/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function Logger() {
*/
function getArrow(originalPath, newPath, originalTarget, newTarget) {
var arrow = ['>'];
var isNewTarget = (originalTarget !== newTarget); // proxyTable
var isNewTarget = (originalTarget !== newTarget); // router
var isNewPath = (originalPath !== newPath); // pathRewrite

if (isNewPath && !isNewTarget) {arrow.unshift('~');} else if (!isNewPath && isNewTarget) {arrow.unshift('=');} else if (isNewPath && isNewTarget) {arrow.unshift('≈');} else {arrow.unshift('-');}
Expand Down
20 changes: 10 additions & 10 deletions lib/proxy-table.js → lib/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,40 @@ module.exports = {
};

function createProxyOptions(req, config) {
var proxyTable = config.proxyTable;
var router = config.router;
var result = _.clone(config);

if (proxyTable) {
var newTarget = getTargetFromProxyTable(req, proxyTable);
if (router) {
var newTarget = getTargetFromProxyTable(req, router);
if (newTarget) {
logger.debug('[HPM] proxyTable new target: %s -> "%s"', config.target, newTarget);
logger.debug('[HPM] router new target: %s -> "%s"', config.target, newTarget);
result = _.assign(result, {target: newTarget}); // override option.target
}
}

return result;
}

function getTargetFromProxyTable(req, proxyTable) {
function getTargetFromProxyTable(req, router) {
var result;
var host = req.headers.host;
var path = req.url;

var hostAndPath = host + path;

_.forIn(proxyTable, function(value, key) {
_.forIn(router, function(value, key) {
if (containsPath(key)) {

if (hostAndPath.indexOf(key) > -1) { // match 'localhost:3000/api'
result = proxyTable[key];
logger.debug('[HPM] proxyTable match: %s -> "%s"', hostAndPath, result);
result = router[key];
logger.debug('[HPM] router match: %s -> "%s"', hostAndPath, result);
return false;
}
} else {

if (key === host) { // match 'localhost:3000'
result = proxyTable[key];
logger.debug('[HPM] proxyTable match: %s -> "%s"', host, result);
result = router[key];
logger.debug('[HPM] router match: %s -> "%s"', host, result);
return false;
}

Expand Down
10 changes: 5 additions & 5 deletions test/e2e/proxy-table.spec.js → test/e2e/router.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var utils = require('./_utils');
var expect = require('chai').expect;
var http = require('http');

describe('E2E proxyTable', function() {
describe('E2E router', function() {
var createServer;
var proxyMiddleware;

Expand Down Expand Up @@ -33,7 +33,7 @@ describe('E2E proxyTable', function() {

proxyServer = createServer(6000, proxyMiddleware('/', {
target: 'http://localhost:6001',
proxyTable: {
router: {
'alpha.localhost:6000': 'http://localhost:6001',
'beta.localhost:6000': 'http://localhost:6002',
'localhost:6000/api': 'http://localhost:6003'
Expand All @@ -59,7 +59,7 @@ describe('E2E proxyTable', function() {
});
});

it('should proxy to proxyTable: "alpha.localhost"', function(done) {
it('should proxy when host is "alpha.localhost"', function(done) {
var options = {hostname: 'localhost', port: 6000, path: '/'};
options.headers = {host: 'alpha.localhost:6000'};
http.get(options, function(res) {
Expand All @@ -71,7 +71,7 @@ describe('E2E proxyTable', function() {
});
});

it('should proxy to proxyTable: "beta.localhost"', function(done) {
it('should proxy when host is "beta.localhost"', function(done) {
var options = {hostname: 'localhost', port: 6000, path: '/'};
options.headers = {host: 'beta.localhost:6000'};
http.get(options, function(res) {
Expand All @@ -83,7 +83,7 @@ describe('E2E proxyTable', function() {
});
});

it('should proxy to proxyTable with path config: "localhost:6000/api"', function(done) {
it('should proxy with host & path config: "localhost:6000/api"', function(done) {
var options = {hostname: 'localhost', port: 6000, path: '/api'};
http.get(options, function(res) {
res.on('data', function(chunk) {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/_libs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ module.exports = {
handlers: require('../../lib/handlers'),
Logger: require('../../lib/logger'),
pathRewriter: require('../../lib/path-rewriter'),
proxyTable: require('../../lib/proxy-table')
router: require('../../lib/router')
};
48 changes: 24 additions & 24 deletions test/unit/proxy-table.spec.js → test/unit/router.spec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
var expect = require('chai').expect;
var proxyTable = require('./_libs').proxyTable;
var expect = require('chai').expect;
var router = require('./_libs').router;

describe('proxyTable unit test', function() {
describe('router unit test', function() {

describe('proxyTable.createProxyOptions', function() {
describe('router.createProxyOptions', function() {
var req, config, result;

beforeEach(function() {
Expand All @@ -22,7 +22,7 @@ describe('proxyTable unit test', function() {
configProxyTable = {
target: 'http://localhost:6000',
changeOrigin: true, // other options should be returned, such as changeOrigin
proxyTable: {
router: {
'alpha.localhost': 'http://localhost:6001',
'beta.localhost': 'http://localhost:6002',
'gamma.localhost/api': 'http://localhost:6003',
Expand All @@ -34,27 +34,27 @@ describe('proxyTable unit test', function() {
};
});

describe('without proxyTable config', function() {
it('should return the normal target when proxyTable not present in config', function() {
result = proxyTable.createProxyOptions(req, config);
describe('without router config', function() {
it('should return the normal target when router not present in config', function() {
result = router.createProxyOptions(req, config);
expect(result.target).to.equal('http://localhost:6000');
expect(result).not.to.equal(config); // should return cloned object
expect(result).to.deep.equal(config); // clone content should match
expect(result.changeOrigin).to.be.true;
});
});

describe('with just the host in proxyTable config', function() {
it('should target http://localhost:6001 when for proxyTable:"alpha.localhost"', function() {
describe('with just the host in router config', function() {
it('should target http://localhost:6001 when for router:"alpha.localhost"', function() {
req.headers.host = 'alpha.localhost';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6001');
expect(result.changeOrigin).to.be.true;
});

it('should target http://localhost:6002 when for proxyTable:"beta.localhost"', function() {
it('should target http://localhost:6002 when for router:"beta.localhost"', function() {
req.headers.host = 'beta.localhost';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6002');
expect(result.changeOrigin).to.be.true;
});
Expand All @@ -63,55 +63,55 @@ describe('proxyTable unit test', function() {
describe('with host and host + path config', function() {
it('should target http://localhost:6004 without path', function() {
req.headers.host = 'gamma.localhost';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6004');
expect(result.changeOrigin).to.be.true;
});

it('should target http://localhost:6003 exact path match', function() {
req.headers.host = 'gamma.localhost';
req.url = '/api';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6003');
expect(result.changeOrigin).to.be.true;
});

it('should target http://localhost:6004 when contains path', function() {
req.headers.host = 'gamma.localhost';
req.url = '/api/books/123';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6003');
expect(result.changeOrigin).to.be.true;
});
});

describe('with just the path', function() {
it('should target http://localhost:6005 with just a path as proxyTable config', function() {
it('should target http://localhost:6005 with just a path as router config', function() {
req.url = '/rest';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6005');
expect(result.changeOrigin).to.be.true;
});

it('should target http://localhost:6005 with just a path as proxyTable config', function() {
it('should target http://localhost:6005 with just a path as router config', function() {
req.url = '/rest/deep/path';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6005');
expect(result.changeOrigin).to.be.true;
});

it('should target http://localhost:6000 path in not present in proxyTable config', function() {
it('should target http://localhost:6000 path in not present in router config', function() {
req.url = '/unknow-path';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6000');
expect(result.changeOrigin).to.be.true;
});
});

describe('matching order of proxyTable config', function() {
describe('matching order of router config', function() {
it('should return first matching target when similar paths are configured', function() {
req.url = '/some/specific/path';
result = proxyTable.createProxyOptions(req, configProxyTable);
result = router.createProxyOptions(req, configProxyTable);
expect(result.target).to.equal('http://localhost:6006');
expect(result.changeOrigin).to.be.true;
});
Expand Down

0 comments on commit 009f90d

Please sign in to comment.