views:

81

answers:

2

I understand there are a lot of questions that answer this. I'm familiar with .htaccess and nginx.conf methods, but I do not have access to such traditional configuration methods on heroku.

Simone Carletti gave this answer that leverages Rails 2.x Metals, but I'm using Rails 3 and this isn't compatible. http://stackoverflow.com/questions/1706247/redirect-non-www-requests-to-www-urls-in-rails/1706312#1706312

Please note:

I'm not looking for a simple before_filter in my ApplicationController. I'd like to accomplish a rewrite similar to Simone's. I believe this is job for the webserver or middleware like Rack at the very least, so I'd like to leave this bit out of the actual app code.

Goal

redirect                to                  status
----------------------------------------------------
www.foo.com             foo.com             301
www.foo.com/whatever    foo.com/whatever    301

Only hosts matching /^www\./ should be redirect. All other requests should be ignored.


Adapted answer

lib/no_www.rb

class NoWww

  def initialize(app)
    @app = app
  end

  def call(env)

    request = Rack::Request.new(env)

    if request.host.starts_with?("www.")
      [301, {"Location" => request.url.sub("//www.", "//")}, self]
    else
      @app.call(env)
    end
  end

  def each(&block)
  end

end

config/application.rb

config.autoload_paths += %W(#{config.root}/lib)

config.middleware.use "NoWww"
+2  A: 

Hey,

Take a look at this middleware, it should do precisely what you want:

http://github.com/iSabanin/www_ditcher

Let me know if that worked for you.

Ilya Sabanin
Ilya, I'm marking this as accepted but I came up with a slightly more elegant/robust solution. According to the [Rack Spec](http://rack.rubyforge.org/doc/SPEC.html), "The Body itself should not be an instance of String, as this will break in Ruby 1.9." So, I made an adjustment here. Also, I'm using Rack::Request object for handling the URL and making the code a little cleaner.
macek
A: 

There's a better approach if you're using Rails 3. Just take advantage of the routing awesomeness.

Foo::Application.routes.draw do
  constraints(:host => /^example.com/) do
    root :to => redirect("http://www.example.com")
    match '/*path', :to => redirect {|params| "http://www.example.com/#{params[:path]}"}
  end
end
schof