Case-insensitive mapping with mod_rewrite’s RewriteMap

Sometimes when you need to manage a massive pile of URL redirections — for instance, when you’re playing snatch-the-tablecloth with your web platform — it’s handy to mash them all together with mod_rewrite’s RewriteMap feature.

I hit a frustrating stumbling block with a recent project, however: What happens if you need your RewriteMap key to be case-insensitive? This is incredibly likely if you’re migrating away from an undisciplined Windows-based web platform.

It was immediately obvious that I’d have to match against consistent casing, but not at all obvious how this would work in the context of mod_rewrite. After some trial and error, here’s what I came up with:

RewriteMap lowercase int:tolower
RewriteMap urls dbm:/srv/www.example.com/urls.db
RewriteCond %{REQUEST_URI} ^(/.*\.html)$
RewriteCond ${lowercase:%1} ^(/.*\.html)$
RewriteCond ${urls:%1|NOT_FOUND} !NOT_FOUND
RewriteRule ^(/.*\.html)$ http://%{HTTP_HOST}${urls:%1}? [R=permanent,L]

Here’s how it works:

  1. First we set up the built in lowercase translation rewrite map… handy!
  2. Then we define our great big URL map, which is just a list of lowercase URLs (yes, they’re lowercased in the file) and their destinations.
  3. Make sure we’re only mucking around with html URLs, but also grab the REQUEST_URI for use further along (see the parentheses in the second parameter).
  4. We use Apache’s handy internal lowercase map to convert the previous line’s match to lowercase, and we grab the whole thing again… but this time, what we’re grabbing is the output of the lowercase map.
  5. Tricky little hack to make sure our URL is represented in the redirection map. If there’s no match, the default value returned is NOT_FOUND… but we only continue to the next line if the map does not return NOT_FOUND.
  6. Finally, permanently redirect to the destination URL, as matched against the lowercase original.

Rock and roll.

Devils and Penguins

Tux passes the baton to Tuz, the hastily-disguised Tasmanian Devil… at least for this release. Great to see one of the more high profile pledges of the madcap, ridiculous, wonderful and incredibly generous linux.conf.au 2009 auction being paid off. :-)

Tuz

linux.conf.au 2009: Tuz

Impact: help prevent extinction of species

The Tasmanian Devil is a shy iconic Australian creature named for its
spine-chilling screech.  It is threatened with extinction due to a
scientifically interesting but horrific transmissible facial cancer.

This one is standing in for Tux for one release using the far less-known
Devil Facial Tux Disguise.

Save The Tasmanian Devil http://tassiedevil.com.au

Signed-off-by: Linux.conf.au Hobart Team <contact@marchsouth.org>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>