4

What is the best way to do this?

I'd like to redirect all requests from www.example.com to example.com

*.example.com to example.com would be ideal

I would think some type of middleware. I still hate this, because it seems so inelegant and slightly wasteful, but I think my only option is to do this server-side.

Chenmunka
  • 685
  • 4
  • 21
  • 25
EhevuTov
  • 20,205
  • 16
  • 66
  • 71
  • You can fix this in your server config. What are you running Node on? Nginx? Apache? – leemeichin Aug 24 '12 at 20:55
  • @leemachin like the tags say, I'm using Express(which uses Connect) – EhevuTov Aug 24 '12 at 20:57
  • Well then the source of your inelegance is not putting it behind a proxy (like Nginx or Apache). – leemeichin Aug 24 '12 at 20:59
  • I have no need of a proxy. Besides, a proxy would do the same thing and is just as inelegant. The inelegance is something I have to deal with, I just need to know how to go a global redirect in these. I'm not looking to debate with you on using a proxy or not. – EhevuTov Aug 24 '12 at 21:01

1 Answers1

9

Since Express 3 doesn't use its own HTTP server (instead you pass your app to http.createServer), it doesn't know what port it's running on unless you tell it. That said, you can do basically what you want to do with the following:

app.use(function(request, response, next) {
  var newHost = request.host.replace(/^www\./, '');
  if (request.host != newHost) {
    // 301 is a "Moved Permanently" redirect.
    response.redirect(301, request.protocol + "://" + newHost + request.url);
  } else {
    next();
  }
});

You could export this in a module and wrap it in a generator that takes a port:

// no_www.js

module.exports = function(port) {
  app.use(function(request, response, next) {
    var newHost = request.host.replace(/^www\./, '');
    if (request.host != newHost) {
      var portStr = '';
      if (request.protocol == 'http' && port != 80) portStr = ':' + port;
      if (request.protocol == 'https' && port != 443) portSt r= ':' + port;
      // 301 is a "Moved Permanently" redirect.
      response.redirect(301, request.protocol + "://" + newHost + portStr + request.url);
    } else {
      next();
    }
  });
}

// app.js

var noWww = require('./no_www');
var app = express();

app.configure("development", function() {
  app.set("port", 3000);
});

...

app.use(noWww(app.get('port')));
Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
  • That's awesome. That's just what I needed. .use() isn't in the Express documentation so I wasn't exactly sure what it did. I'm assuming it's a wrapper for functions that execute on each request? – EhevuTov Aug 24 '12 at 21:15
  • 1
    That's unfortunate, it seems documentation for `use` got lost when the new site went up for version 3. You are right, `use` exposes Connect's (Express is built on Connect) middleware system, so that no-www module I wrote above is middleware for Connect/Express. Check out http://www.senchalabs.org/connect/ for more information. – Michelle Tilley Aug 24 '12 at 21:25
  • This held the answer to my search for Express 4. The only piece I needed was response.redirect(statusCode, destination); Unfortunately it behaved in a pretty strange way. I gave it a complete url and instead of redirecting to the url, the url got appended to the end of the current path. I solved that by just redirecting to "/" which was my desired destination in this case, but if I ever have to redirect to another domain, I'll have to figure out what I did wrong. – SnowInferno Sep 25 '14 at 02:17