Skip to main content

Misconfiguring Apache Rewrite directives

The mod_rewrite module is extremely powerful, but painful to debug. Here's some common pitfalls and useful resources.

The Holy .htaccess tester

There's a very useful tool here: https://htaccess.madewithlove.com/ . Make use of it; it can save you a lot of headaches.

Variables

THE_REQUEST vs REQUEST_URI

Note that these are often the same, but are separate values. THE_REQUEST is the original request as received from the client; REQUEST_URI is the request received from the client, including any rewrites by Apache!

If you have a lot of rewrite rules, this is an important distinction, as sometimes you specifically want to check the original request, and sometimes you want to check any requests your rules have rewritten as well. In particular, using REQUEST_URI when you didn't mean to can put your server into an infinite redirection loop.

Understanding the Redirect directive

The [R=301] and [R=302] directives in rewrite rules aren't just about changing the URL, but informing the client of the redirect (i.e. the user's browser will be redirected to the URL).

Without this, your rewrite rules will change the internal URL Apache uses to serve a request, but doesn't change the URL for the user themselves. E.g.:

# Redirects the user to /messages/all
RewriteRule ^(.*)$ /messages/all [R=302,L]

# Uses /messages/all to handle the request, but does NOT redirect the user
RewriteRule ^(.*)$ /messages/all [L]

You can use this to redirect users to pretty URLs using the R=301 or R=302 directives, and internally rewrite the pretty URL to the actual URL to handle the request by not using the R directive in the latter rule.