michael orlitzky

Avoiding RewriteBase with Apache mod_rewrite

posted 2012-02-08

What's RewriteBase?

RewriteBase is a configuration directive for Apache's mod_rewrite. I'm going to assume you know what mod_rewrite is, and at least kinda know why you want to use it.

Why would you use it?

Most blogs, CMS engines, bug trackers—basically all boxed PHP applications—allow “clean URLs.” They go by many names: SEO-friendly, fancy, clean, etc. But they all do the same thing: they turn https://www.example.com/index.php?page=pornography into https://www.example.com/pornography, and they use mod_rewrite to do it.

What does RewriteBase have to do with it?

Most applications will give you a set of Apache directives, and tell you to copy/paste them into an .htaccess file. They almost always tell you to use RewriteBase. Here's an example from Wordpress:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>

There are only a few important parts here. First, of course, is the RewriteBase line, because that's what we're talking about yo. Next are the two lines that look like this:

RewriteCond %{REQUEST_FILENAME} !-f

Those lines mean, if the requested path is a real file or directory, don't rewrite anything. This is important, because you want visitors to be able to access stylesheets, images, javascript, etc. without your rewrite rules screwing them up.

Here's where I explain RewriteBase, promise

In the rule, %{REQUEST_FILENAME} is relative to the DocumentRoot of the site. However, the “is it a file” and “is it a directory” checks are relative to the filesystem root! So, a request for style.css would cause mod_rewrite to check for /style.css at the root of your filesystem.

RewriteBase fixes that. If you stick a RewriteBase $path in a <Directory $dir>…</Directory> block, all rewrite rules within that block will be considered relative to $dir/$path. Thus, RewriteBase / makes everything relative to the <Directory> block in which you place it.

What is Problem?

RewriteBase only works within a <Directory> block, so you can't reuse your rewrite rules. If you have lots of Wordpress sites, it's nice to be able to stick the Wordpress-specific stuff in a file, wordpress.conf, and simply include that into each of your virtual host files.

A New Kind of Science

Rather than putting a RewriteBase in every one of your <Directory>…</Directory> blocks, you should use %{DOCUMENT_ROOT} in your rewrite rules. Then, you can reuse those rules on other sites.

Almost everybody sets RewriteBase / anyway, so this shouldn't be a problem. An example:

<IfModule rewrite_module>
  ...
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
  ...
</IfModule>