Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Ensuring www is in the URL

I have my app hosted on Heroku, and have a cert for www.mysite.com

I'm trying to solve for

  • Ensuring www is in the URL, and that the URL is HTTPS

Here's what I have so far:

class ApplicationController < ActionController::Base
before_filter :check_uri

  def check_uri
    redirect_to request.protocol + "www." + request.host_with_port + request.request_uri if !/^www/.match(request.host) if Rails.env == 'production'
  end

But this doesn't seem to being working. Any suggestions or maybe different approaches to solve for ensuring HTTPs and www. is in the URL?

Thanks

like image 789
AnApprentice Avatar asked Dec 07 '10 02:12

AnApprentice


3 Answers

For the SSL, use rack-ssl.

# config/environments/production.rb
MyApp::Application.configure do
  require 'rack/ssl'
  config.middleware.use Rack::SSL
  # the rest of the production config....
end

For the WWW, create a Rack middleware of your own.

# lib/rack/www.rb
class Rack::Www
  def initialize(app)
    @app = app
  end
  def call(env)
    if env['SERVER_NAME'] =~ /^www\./
      @app.call(env)
    else
      [ 307, { 'Location' => 'https://www.my-domain-name.com/' }, '' ]
    end
  end
end

# config/environments/production.rb
MyApp::Application.configure do
  config.middleware.use Rack::Www
  # the rest of the production config....
end

To test this in the browser, you can edit your /etc/hosts file on your local development computer

# /etc/hosts
# ...
127.0.0.1 my-domain-name.com
127.0.0.1 www.my-domain-name.com

run the application in production mode on your local development computer

$ RAILS_ENV=production rails s -p 80

and browse to http://my-domain-name.com/ and see what happens.

For the duration of the test, you may want to comment out the line redirecting you to the HTTPS site.

There may also be ways to test this with the standard unit-testing and integration-testing tools that many Rails projects use, such as Test::Unit and RSpec.

like image 119
yfeldblum Avatar answered Nov 07 '22 13:11

yfeldblum


Pivotal Labs has some middleware called Refraction that is a mod_rewrite replacement, except it lives in your source code instead of your Apache config.

It may be a little overkill for what you need, but it handles this stuff pretty easily.

like image 27
Jeff Wigal Avatar answered Nov 07 '22 11:11

Jeff Wigal


In Rails 3

#config/routes.rb
Example::Application.routes.draw do
  redirect_proc = Proc.new { redirect { |params, request|
    URI.parse(request.url).tap { |x| x.host = "www.example.net"; x.scheme = "https" }.to_s
  } }
  constraints(:host => "example.net") do
    match "(*x)" => redirect_proc.call
  end
  constraints(:scheme => "http") do
    match "(*x)" => redirect_proc.call
  end
  # .... 
  # .. more routes ..
  # ....
end
like image 42
Vikrant Chaudhary Avatar answered Nov 07 '22 11:11

Vikrant Chaudhary