Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
HTTP/HTTPS forward proxy in node.js
// HTTP forward proxy server that can also proxy HTTPS requests
// using the CONNECT method
// requires https://github.com/nodejitsu/node-http-proxy
var httpProxy = require('http-proxy'),
url = require('url'),
net = require('net'),
http = require('http');
process.on('uncaughtException', logError);
function truncate(str) {
var maxLength = 64;
return (str.length >= maxLength ? str.substring(0,maxLength) + '...' : str);
}
function logRequest(req) {
console.log(req.method + ' ' + truncate(req.url));
for (var i in req.headers)
console.log(' * ' + i + ': ' + truncate(req.headers[i]));
}
function logError(e) {
console.warn('*** ' + e);
}
// this proxy will handle regular HTTP requests
var regularProxy = new httpProxy.RoutingProxy();
// standard HTTP server that will pass requests
// to the proxy
var server = http.createServer(function (req, res) {
logRequest(req);
uri = url.parse(req.url);
regularProxy.proxyRequest(req, res, {
host: uri.hostname,
port: uri.port || 80
});
});
// when a CONNECT request comes in, the 'upgrade'
// event is emitted
server.on('upgrade', function(req, socket, head) {
logRequest(req);
// URL is in the form 'hostname:port'
var parts = req.url.split(':', 2);
// open a TCP connection to the remote host
var conn = net.connect(parts[1], parts[0], function() {
// respond to the client that the connection was made
socket.write("HTTP/1.1 200 OK\r\n\r\n");
// create a tunnel between the two hosts
socket.pipe(conn);
conn.pipe(socket);
});
});
server.listen(3333);
@NeoTech
NeoTech commented Oct 29, 2013

server.on('upgrade' doesnt work.. changing upgrade to well "connect" does seem to work.. Dont know why - trying to figure out this crap myself.. ;)

@ChinaXing

this not works with common tcp proxy, how to make it possible.

@ChinaXing

CONNECT proxy.exmpale.com:80 HTTP/1.1

not works !

@chishunkwonggenesys

Thank you so much. Like an earlier comment I changed 'upgrade' to 'connect'. Also, since http-proxy has changed since, I had to modify the definition of regularProxy and changed the call of regularProxy.proxyRequest(...) to regularProxy.web(req, res, { target: 'http://' + req.headers.host }). Otherwise pretty much verbatim!

@corwin-of-amber
corwin-of-amber commented Mar 5, 2017 edited

httpProxy.RoutingProxy does not exist anymore. See this StackOverflow answer (notice the edit); new httpProxy.RoutingProxy() has to be changed to httpProxy.createProxyServer({}). Following the previous comment, I changed regularProxy.proxyRequest(req, res, { ... }) to

regularProxy.web(req, res, {target: "http://" + req.headers.host});

and it seems to work well (also for https somehow.)

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