Skip to content

Instantly share code, notes, and snippets.

@axefrog
Created August 14, 2012 22:36
Show Gist options
  • Save axefrog/3353609 to your computer and use it in GitHub Desktop.
Save axefrog/3353609 to your computer and use it in GitHub Desktop.
Node.js HTTP/HTTPS double forward proxy with two-stage authorization
/*
HTTP/HTTPS Forward Proxy
------------------------
The purpose of this proxy is to manage a set of third party proxies
internally, routing incoming requests through those proxies and
rotating which remote proxies are in use periodically as requests come
through, and without exposing the proxy credentials to the originating
client. Rate limiting will later be implemented internally so that if
the remote proxies have all been utilised too heavily, a "rate limit
exceeded" message will be returned to the client.
The plain HTTP proxy works fine. The HTTPS side doesn't unless I send
it directly to the requested host. How do I forward the HTTPS request
through the remote proxy with authorization credentials?
*/
var httpProxy = require('http-proxy'),
net = require('net'),
http = require('http');
var remoteProxyInfo = {
host: 'x.x.x.x',
port: 1234,
username: 'foo',
password: 'bar'
}
var server = httpProxy.createServer(function(req, res, proxy) {
// plain old http proxy
var buffer = httpProxy.buffer(req);
req.path = req.url;
req.headers['Proxy-Authorization'] = 'Basic ' + new Buffer(remoteProxyInfo.username + ':' + remoteProxyInfo.password).toString('base64');
var options = {
host: remoteProxyInfo.host,
port: remoteProxyInfo.port,
buffer: buffer
}
proxy.proxyRequest(req, res, options);
}).on('connect', function(req, socket, head) {
// tricky https proxy that doesn't work properly
var buffer = httpProxy.buffer(req);
if(!req.headers['proxy-authorization']) {
socket.end('HTTP/1.0 407 Proxy authentication required\nProxy-authenticate: Basic realm="remotehost"\n\n');
return;
}
// (to do: verify credentials)
// build a new set of headers to send to/through the remote proxy
var headers = 'CONNECT ' + req.url + ' HTTP/1.1\r\n';
for(var key in req.headers)
if(key != 'proxy-authorization')
headers += key + ': ' + req.headers[key] + '\r\n';
headers += 'Proxy-Authorization: ' + 'Basic ' + new Buffer(remoteProxyInfo.username + ':' + remoteProxyInfo.password).toString('base64') + '\r\n';
headers += '\r\n';
// open a connection, send the headers, then the encrypted stream
var conn = net.connect(remoteProxyInfo.port, remoteProxyInfo.host, function() {
conn.write(headers);
socket.write('HTTP/1.1 200 OK\r\n\r\n');
socket.pipe(conn);
conn.pipe(socket);
});
})
.listen(3333);
@congthang1
Copy link

Hi id doesnt run anymore, can you update it

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