How to create a simple http proxy in node.js?

Nasser Torabzade picture Nasser Torabzade · Dec 3, 2013 · Viewed 153k times · Source

I'm trying to create a proxy server to pass HTTP GET requests from a client to a third party website (say google). My proxy just needs to mirror incoming requests to their corresponding path on the target site, so if my client's requested url is:

127.0.0.1/images/srpr/logo11w.png

The following resource should be served:

http://www.google.com/images/srpr/logo11w.png

Here is what I came up with:

http.createServer(onRequest).listen(80);

function onRequest (client_req, client_res) {
    client_req.addListener("end", function() {
        var options = {
            hostname: 'www.google.com',
            port: 80,
            path: client_req.url,
            method: client_req.method
            headers: client_req.headers
        };
        var req=http.request(options, function(res) {
            var body;
            res.on('data', function (chunk) {
                body += chunk;
            });
            res.on('end', function () {
                 client_res.writeHead(res.statusCode, res.headers);
                 client_res.end(body);
            });
        });
        req.end();
    });
}

It works well with html pages, but for other types of files, it just returns a blank page or some error message from target site (which varies in different sites).

Answer

vmx picture vmx · Dec 3, 2013

I don't think it's a good idea to process response received from the 3rd party server. This will only increase your proxy server's memory footprint. Further, it's the reason why your code is not working.

Instead try passing the response through to the client. Consider following snippet:

var http = require('http');

http.createServer(onRequest).listen(3000);

function onRequest(client_req, client_res) {
  console.log('serve: ' + client_req.url);

  var options = {
    hostname: 'www.google.com',
    port: 80,
    path: client_req.url,
    method: client_req.method,
    headers: client_req.headers
  };

  var proxy = http.request(options, function (res) {
    client_res.writeHead(res.statusCode, res.headers)
    res.pipe(client_res, {
      end: true
    });
  });

  client_req.pipe(proxy, {
    end: true
  });
}