Skip to content

Instantly share code, notes, and snippets.

@tonygambone
Created April 19, 2012 17:02
Show Gist options
  • Save tonygambone/2422322 to your computer and use it in GitHub Desktop.
Save tonygambone/2422322 to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link

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

@ChinaXing
Copy link

CONNECT proxy.exmpale.com:80 HTTP/1.1

not works !

@chishunkwonggenesys
Copy link

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
Copy link

corwin-of-amber commented Mar 5, 2017

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.)

@mocheng
Copy link

mocheng commented Mar 5, 2018

Nice work! With the help of above comments, I made it work.

I'm wondering if it is possible to log https request & response content by node-http-proxy. It looks connect event handler cannot have access to https content.

@mocheng
Copy link

mocheng commented Mar 5, 2018

The parameter function of http.createServer is never called. It still works with var server = http.createServer(); . As a result, no way to intercept https request/response.

@imhazige
Copy link

@flarn2006
Copy link

What's the license on this?

@tole22
Copy link

tole22 commented Jun 10, 2020

working project https://github.com/imhazige/node-http-connect-proxy

this works for me! Thanks

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