Commits

Branko Vukelic  committed c2d25ad

Added support for multiple targets

  • Participants
  • Parent commits f6dae20

Comments (0)

Files changed (2)

File example/proxy.json

 {
-  "target": "https://example.com:4500/api/v1/",
   "port": 80,
   "baseDir": "www-built",
-  "rootPath": "api"
+  "target": [
+    "https://example.com:4500/api/v1/",
+    "http://example.com:4501/api/v1/"
+  ],
+  "rootPath": [
+    "api",
+    "api2"
+  ]
 }

File lib/proxy.js

   alias('h', 'help').
   describe('c', 'Use configuration file FILE').
   describe('p', 'Port at which proxy will listen').
-  describe('t', 'Full URL of the proxy target').
-  describe('r', 'Root URL at which the proxied target is accessible').
+  describe('t', 'Full URL of the proxy target. You can specify multiple ' +
+           'targets)').
+  describe('r', 'Root URL at which the proxied target is accessible. You can' +
+           'specify multiple root URLs for each target.').
   describe('s', 'Static content directory served by proxy').
   describe('n', 'Suppress Accept-Language header on broken servers').
   describe('h', 'Show usage documentation');
 
+var makeArr = function(v) {
+  if (Object.prototype.toString.call(v) === '[object Array]') {
+    return v; 
+  }
+  return [v];
+};
+
+// Parse arguments
+
 var opts = argv.argv;
 
 if (opts.h) {
   }
 };
 
+// Load and parse configuration file if any
+
 if (confFile) {
   conf = JSON.parse(fs.readFileSync(confFile, {encoding: 'utf-8'}));
 }
 
+// Set all defaults
+
 setDefault(conf, 'baseDir', opts.static);
 setDefault(conf, 'target', opts.target);
 setDefault(conf, 'rootPath', opts.url);
 setDefault(conf, 'port', opts.port);
 setDefault(conf, 'noLang', opts['no-lang']);
 
+// Normalize target and rootPath properties (they have to be arrays)
+conf.target = makeArr(conf.target);
+conf.rootPath = makeArr(conf.rootPath);
+
 var baseDir = conf.baseDir;
-var target = url.parse(conf.target); 
 var rootPath = conf.rootPath;
 var port = conf.port;
 
   return '/';
 };
 
-var service = {
-  target: {
-    host: target.hostname,
-    port: target.port || 80,
-    https: target.protocol === 'https:',
-    rejectUnauthorized: false,
-  },
-  rootPath: reSlash(rootPath || target.path),
-  baseUrl: reSlash(target.path)
+var mkService = function (target, root) {
+  target = url.parse(target); 
+  root = reSlash(root || target.path);
+  return {
+    target: {
+      host: target.hostname,
+      port: target.port || 80,
+      https: target.protocol === 'https:',
+      rejectUnauthorized: false,
+    },
+    rootPath: root,
+    baseUrl: reSlash(target.path),
+    pathRe: new RegExp('^' + root)
+  };
 };
 
+var services = conf.target.map(function(target, i) {
+  return mkService(target, conf.rootPath[i]);
+});
+
 // Target configuration for local static server
 var local = {
   target: {
   console.log(EMO_EMBARRASED + ' ~{ ' + err + ' }');
 });
 
-proxyPathRe = new RegExp('^' + service.rootPath);
-
 // Create proxy server with URL rewriting
 proxyServer = httpProxy.createServer(function(req, res, proxy) {
+  var matchingServices;
   var backend;
 
   console.log(req.method + ':' + req.url);
 
-  if (req.url.match(proxyPathRe)) {
+  matchingServices = services.filter(function(service) {
+    return req.url.match(service.pathRe);
+  });
+
+  if (matchingServices.length) {
     // If it's a request going for service:
-    req.url = req.url.replace(service.rootPath, service.baseUrl);
-    backend = service;
+    backend = matchingServices[0];
+    req.url = req.url.replace(backend.rootPath, backend.baseUrl);
   } else {
     // For all other requests go to internal static server:
     backend = local;
 // Enjoy!
 var proxyAddress = '0.0.0.0:' + port;
 console.log(EMO_SHINE + ' Proxy server listening on ' + proxyAddress);
-console.log(EMO_SHINE + ' ' + proxyAddress + service.rootPath + ' ~~> ' + 
-  service.target.host + ':' + service.target.port + service.baseUrl + 
-  (service.target.https ? ' with SSL' : ''));
+services.forEach(function(service) {
+  console.log(EMO_SHINE + ' ' + proxyAddress + service.rootPath + ' ~~> ' + 
+    service.target.host + ':' + service.target.port + service.baseUrl + 
+    (service.target.https ? ' with SSL' : ''));
+});
 console.log('Press Ctrl-C twice to stop.\n');