Question

I'm currently using NodeJS/Express as a simple domain router running on my VPS on port 80. My routes.coffee looks something like this:

request = require("request")

module.exports = (app) ->

    #404, 503, error
    app.get "/404", (req, res, next) ->
        res.send "404. Sowway. :("

    app.get "/error", (req, res, next) ->
        res.send "STOP SENDING ERRORS! It ain't cool, yo."

    #Domain Redirects
    app.all '/*', (req, res, next) ->
        hostname = req.headers.host.split(":")[0]

        #Website1.com
        if hostname == 'website1.com'
            res.status 301
            res.redirect 'http://facebook.com/website1'

        #Example2.com
        else if hostname == 'example2.com'
            pathToGo = (req.url).replace('www.','').replace('http://example2.com','')
            request('http://localhost:8020'+pathToGo).pipe(res)

        #Other
        else
            res.redirect '/404'

As you can see in Example2.com, I'm attempting to reverse proxy to another node instance on a different port. Overall it works perfectly, except for one issue. If the route on the other node instance changes (Redirects from example2.com/page1.html to example2.com/post5), the URL in the address bar doesn't change. Would anyone happen to have a nice workaround for this? Or maybe a better way to reverse proxy? Thanks!

Was it helpful?

Solution

In order to redirect the client, you should set the to 3xx and send a location header.

I'm not familiar with request module but I believe it follows redirects by default. On the other hand, you're piping the proxy-request's response to client's response object, discarding the headers and the status code. That's why the clients don't get redirected.

Here is a simple reverse HTTP proxy using the built-in HTTP client. It's written in but you can easily translate it to and use request module if you want.

var http = require('http');
var url = require('url');

var server = http.createServer(function (req, res) {
  parsedUrl = url.parse(req.url);

  var headersCopy = {};
  // create a copy of request headers
  for (attr in req.headers) {
    if (!req.headers.hasOwnProperty(attr)) continue;
    headersCopy[attr] = req.headers[attr];
  }

  // set request host header
  if (headersCopy.host) headersCopy.host = 'localhost:8020';

  var options = {
    host: 'localhost:8020',
    method: req.method,
    path: parsedUrl.path,
    headers: headersCopy
  };

  var clientRequest = http.request(options);

  clientRequest.on('response', function (clientResponse) {
    res.statusCode = clientResponse.statusCode;
    for (header in clientResponse.headers) {
      if (!clientResponse.headers.hasOwnProperty(header)) continue;
      res.setHeader(header, clientResponse.headers[header]);
    }
    clientResponse.pipe(res);
  });

  req.pipe(clientRequest);
});

server.listen(80);

// drop root privileges
server.on('listening', function () {
  process.setgid && process.setgid('nobody');
  process.setuid && process.setuid('nobody');
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top