Created
August 14, 2012 22:36
-
-
Save axefrog/3353609 to your computer and use it in GitHub Desktop.
Node.js HTTP/HTTPS double forward proxy with two-stage authorization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi id doesnt run anymore, can you update it