Skip to content

Instantly share code, notes, and snippets.

@TKasperczyk
Last active March 2, 2020 17:30
Show Gist options
  • Select an option

  • Save TKasperczyk/3d5029d9bedcdcfddf3a174d9bd8f794 to your computer and use it in GitHub Desktop.

Select an option

Save TKasperczyk/3d5029d9bedcdcfddf3a174d9bd8f794 to your computer and use it in GitHub Desktop.
Proxy server
//Requires http-proxy
//Usage: node server.js <port>
const httpProxy = require('http-proxy');
const http = require('http');
const url = require('url');
const net = require('net');
//Check if the port was supplied
const port = process.argv[2];
if (port === undefined) {
console.error('You need to specify the TCP listen port');
process.exit();
}
//Handles HTTP traffic
const server = http.createServer((req, res) => {
const urlObj = url.parse(req.url);
const target = `${urlObj.protocol}//${urlObj.host}`;
console.log(`Proxy HTTP request for: ${target}`);
const proxy = httpProxy.createProxyServer({});
proxy.on('error', (err, req, res) => {
console.error('Proxy error: ', err);
res.end();
});
proxy.web(req, res, {
target
});
}).listen(port);
console.log(`Listening on ${port}`);
//Extract host information from the request url. If the port was included in the url, it will overwrite the default port
const getHostPortFromString = (hostString, defaultPort) => {
let host = hostString;
let port = defaultPort;
const rgxResult = /^([^:]+)(:([0-9]+))?$/.exec(hostString);
if (rgxResult != null) {
host = rgxResult[1];
if (rgxResult[2] != null) {
port = rgxResult[3];
}
}
return {host, port};
};
//Handles HTTPS traffic
server.addListener('connect', (req, socket, bodyhead) => {
const hostPort = getHostPortFromString(req.url, 443);
console.log(`Proxying an HTTPS request for: ${hostPort.host}:${hostPort.port}`);
//Create a proxy connection and pass HTTP 200 to the socket
const proxySocket = new net.Socket();
proxySocket.connect(hostPort.port, hostPort.host, () => {
proxySocket.write(bodyhead);
socket.write('HTTP/' + req.httpVersion + ' 200 Connection established\r\n\r\n');
});
//Forward traffic coming from the outside
proxySocket.on('data', (chunk) => { socket.write(chunk); });
proxySocket.on('end', () => { socket.end(); });
//Forward traffic coming from the inside
socket.on('data', (chunk) => { proxySocket.write(chunk); });
socket.on('end', () => { proxySocket.end(); });
//Handle errors from both sides
socket.on('error', () => {
proxySocket.end(); //No need to write anything because it's just a middleman
});
proxySocket.on('error', () => {
socket.write('HTTP/' + req.httpVersion + ' 500 Connection error\r\n\r\n'); //Inform the user that there was an error on the proxy's side
socket.end();
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment