Rack::Rewrite

Added by jtrupiano at October 13, 2009 02:44 Star_small_grayStar_small_grayStar_small_grayStar_small_grayStar_small_gray
GitHub stats:
Magnifier watcher(s)
Arrow_branch fork(s)
Wrench

About

A rack middleware for defining and applying rewrite rules. In many cases you can get away with rack-rewrite instead of writing Apache mod_rewrite rules.

Details

rack-rewrite

A rack middleware for defining and applying rewrite rules. In many cases you can get away with rack-rewrite instead of writing Apache mod_rewrite rules.

Rack::Rewrite is available as a gem: gem install rack-rewrite
Full source code is at github: http://github.com/jtrupiano/rack-rewrite

Use Cases

Rebuild of existing site in a new technology

It’s very common for sites built in older technologies to be rebuilt with the latest and greatest. Let’s consider a site that has already established quite a bit of “google juice.” When we launch the new site, we don’t want to lose that hard-earned reputation. By writing rewrite rules that issue 301’s for old URL’s, we can transfer that google ranking to the new site. An example rule might look like:

  r301 '/contact-us.php', '/contact-us'
  r301 '/wiki/John_Trupiano', '/john'

Retiring old routes

As a web application evolves you will sometimes have to make changes to routes. The danger here is that any URL’s previously generated (in a transactional email for instance) will have the URL hard-coded. In order for your rails app to continue to serve this URL, you’ll need to add an extra entry to your routes file. Alternatively, you could use Rack::Rewrite to redirect or pass through requests to these routes and keep your routes.rb clean.

  rewrite %r{/features(.*)}, '/facial_features$1'

Site maintenance

This common capistrano + apache ruleset

  RewriteCond %{REQUEST_URI} !\.(css|jpg|png)$
  RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
  RewriteCond %{SCRIPT_FILENAME} !maintenance.html
  RewriteRule ^.*$ /system/maintenance.html [L]

can be replaced by Rack::Rewrite with the following rule

  maintenance_file = File.join(RAILS_ROOT, 'public', 'system', 'maintenance.html')

  # Ruby 1.9.x (w/ regexp negative lookahead)
  send_file /(.*)$(?<!css|png|jpg)/, maintenance_file, :if => Proc.new { |rack_env|
    File.exists?(maintenance_file)
  }

  # Vanilla Ruby 1.8.x
  send_file /.*/, maintenance_file, :if => Proc.new { |rack_env|
    File.exists?(maintenance_file) && rack_env['REQUEST_URI'] !~ /\.(css|jpg|png)/
  }

Usage

Sample usage in a rackup file

  gem 'rack-rewrite', '~> 0.2.0'
  require 'rack-rewrite
  use Rack::Rewrite do
    rewrite '/wiki/John_Trupiano', '/john'
    r301 '/wiki/Yair_Flicker', '/yair'
    r302 '/wiki/Greg_Jastrab', '/greg'
    r301 %r{/wiki/(\w+)_\w+}, '/$1'
  end

Sample usage in a rails app

  config.gem 'rack-rewrite', '~> 0.2.0'
  require 'rack-rewrite
  config.middleware.insert_before(Rack::Lock, Rack::Rewrite) do
    rewrite '/wiki/John_Trupiano', '/john'
    r301 '/wiki/Yair_Flicker', '/yair'
    r302 '/wiki/Greg_Jastrab', '/greg'
    r301 %r{/wiki/(\w+)_\w+}, '/$1'
  end
blog comments powered by Disqus