Instantly share code, notes, and snippets.

Embed
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

This comment has been minimized.

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 comment has been minimized.

ChinaXing commented Jun 5, 2014

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

@ChinaXing

This comment has been minimized.

ChinaXing commented Jun 5, 2014

CONNECT proxy.exmpale.com:80 HTTP/1.1

not works !

@chishunkwonggenesys

This comment has been minimized.

chishunkwonggenesys commented Dec 23, 2015

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

imhazige commented Jun 22, 2018

@flarn2006

This comment has been minimized.

flarn2006 commented Sep 18, 2018

What's the license on this?

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