Skip to content

Instantly share code, notes, and snippets.

@risacher
Last active October 4, 2017 12:38
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save risacher/8302220 to your computer and use it in GitHub Desktop.
Save risacher/8302220 to your computer and use it in GitHub Desktop.
An example of a reverse proxy server written using the caronte branch of node-http-proxy. I dumped node-http-proxy for nginx when it stopped supporting websockets under node 0.10.x.This version seems adequate to replace nginx again.
"use strict";
var fs = require('fs'),
http = require('http'),
https = require('https'),
util = require('util'),
httpProxy = require('http-proxy'),
proxyTable = require('./proxy-table.js'); // proxy-table from the pre-caronte node-http-proxy
var routes_path = "routes.json";
/* example routes.json file:
{
"servername/term/": "127.0.0.1:8001",
"servername/blog/": "127.0.0.1:3000",
"servername/app/": "127.0.0.1:3001",
"servername": "127.0.0.1:81",
"www.domain.com/term/": "127.0.0.1:8001",
"www.domain.com/blog/": "127.0.0.1:3000",
"www.domain.com/app/": "127.0.0.1:3001",
"www.domain.com": "127.0.0.1:81"
}
*/
var table;
var read_routes = function(event, filename) {
var routes_file = fs.readFileSync(routes_path);
var routes_json;
try {
routes_json = JSON.parse(routes_file);
} catch (err) {
console.log("error parsing json file");
console.log("routes_file: ", routes_file);
console.log("routes_json: ", routes_json);
console.log("error was "+ err.message);
}
if (typeof(routes_json) == 'object') {
table = new proxyTable.ProxyTable({router: routes_json});
console.log("routes: ", routes_json);
} else {
console.log("routes_json not an object: ", typeof(routes_json));
}
}
read_routes();
fs.watch(routes_path, {persistent: false}, read_routes);
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({
// turn on x-forwarded-for headers
xfwd : true
});
var listener = function(req, res) {
console.log( req.headers.host, req.url, req.method );
var target = table.getProxyLocation(req);
console.log( 'target: ', target );
if (null != target) {
proxy.web(req, res, { target: target });
}
};
var https_options = {
key: fs.readFileSync('mykey.pem', 'utf8'),
cert: fs.readFileSync('mycert.pem', 'utf8'),
// ca: fs.readFileSync('/etc/apache2/ssl/gd_bundle.crt', 'utf8'),
ciphers: 'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM',
honorCipherOrder: true
};
var server = http.createServer(listener).listen(80);
var httpsServer = https.createServer(https_options, listener).listen(443);
// Simpleminded TLS session store
// This leaks memory I think, in that it never forgets old sessions
var tlsSessionStore = {};
httpsServer.on('newSession', function(id, data) {
console.log('NEW HTTPS session - %s', id.toString('hex'));
tlsSessionStore[id] = data;
});
httpsServer.on('resumeSession', function(id, cb) {
console.log('RESUME HTTPS session - %s', id.toString('hex'));
cb(null, tlsSessionStore[id] || null);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
var upgrade = function (req, socket, head) {
console.log("UPGRADE - %s", ('object' === typeof(socket.encrypted))?'https':'http') ;
var target = table.getProxyLocation(req);
if (null != target) {
proxy.ws(req, socket, head, {target: target});
}
}
server.on('upgrade', upgrade);
httpsServer.on('upgrade', upgrade);
@cheesepencil
Copy link

Wonderful, exactly what I'm looking for! I'll be poking at this tomorrow morning. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment