Skip to content

Instantly share code, notes, and snippets.

@bertho-zero
Last active February 10, 2016 23:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bertho-zero/723306762fd67a1ec7ec to your computer and use it in GitHub Desktop.
Save bertho-zero/723306762fd67a1ec7ec to your computer and use it in GitHub Desktop.
'use strict';
var http = require('http');
var net = require('net');
/*
* Usage : node node-proxy.js [-d] [-p 5555]
*/
var debugging = 0;
function parseHostPort(hostString, defaultPort) {
var host = hostString;
var port = defaultPort;
var result = /^([^:]+)(?::([0-9]+))?$/.exec(hostString);
if (result != null) {
host = result[1];
port = result[2] || port;
}
return {host: host, port: port};
}
// handle a HTTP proxy request
function httpUserRequest(userRequest, userResponse) {
if (debugging) console.log(' > request: %s', userRequest.url);
var httpVersion = userRequest.httpVersion;
var hostport = parseHostPort(userRequest.headers.host, 80);
// have to extract the path from the requested URL
var path = userRequest.url;
var result = /^[a-zA-Z]+:\/\/[^\/]+(\/.*)?$/.exec(userRequest.url);
if (result != null) {
path = (result[1].length > 0) ? result[1] : "/";
}
var options = {
'host': hostport.host,
'port': hostport.port,
'method': userRequest.method,
'path': path,
'agent': userRequest.agent,
'auth': userRequest.auth,
'headers': userRequest.headers
};
if (debugging) console.log(' > options: ' + JSON.stringify(options, null, 2));
var proxyRequest = http.request(options,
function (proxyResponse) {
if (debugging) console.log(' > request headers: ' + JSON.stringify(options['headers'], null, 2));
if (debugging) console.log(' < response ' + proxyResponse.statusCode + ' headers: ' + JSON.stringify(proxyResponse.headers, null, 2));
userResponse.writeHead(
proxyResponse.statusCode,
proxyResponse.headers
);
proxyResponse.pipe(userResponse);
}
);
proxyRequest.on('error',
function (error) {
userResponse.writeHead(500);
userResponse.write(error);
userResponse.end();
}
);
userRequest.pipe(proxyRequest);
}
function main() {
var port = 5555; // default port if none on command line
// check for any command line arguments
for (var argn = 2; argn < process.argv.length; argn++) {
if (process.argv[argn] === '-p') {
port = parseInt(process.argv[argn + 1]);
argn++;
continue;
}
if (process.argv[argn] === '-d') {
debugging = 1;
continue;
}
}
if (debugging) console.log('server listening on port ' + port);
// start HTTP server with custom request handler callback function
var server = http.createServer(httpUserRequest).listen(port);
// add handler for HTTPS (which issues a CONNECT to the proxy)
server.on('connect',
function (request, socketRequest, headers) {
var url = request['url'];
var httpVersion = request['httpVersion'];
var hostport = parseHostPort(url, 443);
if (debugging) console.log(' = will connect to ' + hostport.host + ':' + hostport.port);
// set up TCP connection
var proxySocket = new net.Socket();
proxySocket.connect(
parseInt(hostport.port), hostport.host,
function () {
if (debugging) console.log(' < connected to ' + hostport.host + ':' + hostport.port);
if (debugging) console.log(' > writing head of length ' + headers.length);
proxySocket.write(headers);
socketRequest.write("HTTP/" + httpVersion + " 200 Connection established\r\n\r\n");
}
);
proxySocket.pipe(socketRequest);
socketRequest.pipe(proxySocket);
proxySocket.on('error',
function (err) {
socketRequest.write("HTTP/" + httpVersion + " 500 Connection error\r\n\r\n");
if (debugging) console.log(' < ERR: ' + err);
socketRequest.end();
}
);
socketRequest.on('error',
function (err) {
if (debugging) console.log(' > ERR: ' + err);
proxySocket.end();
}
);
}
); // HTTPS connect listener
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment