Originally published at
www.ikriv.com. Please leave any
comments there.
I have just spent a few fun hours fighting Apache rewrite rules in an .htaccess file. It turns out that temporary redirects just work, but permanent redirects require RewriteBase! Frankly, this is insane.
Suppose, I have my web site test.ikriv.com that lives in /var/www/html on the server disk. Let’s say I have the following contents in /var/www/html/.htaccess:
RewriteEngine on
RewriteRule ^(.*)\.temp$ $1.html
RewriteRule ^(.*)\.perm$ $1.html [R=permanent]
If type in the browser
https://test.ikriv.com/file.temp, I see the contents of /var/www/html/file.html, as expected. The server does not report the redirect back to the browser, but quietly serves file.html instead of file.temp.
If, however, I type
https://test.ikriv.com/file.perm I get redirected to
https://test.ikriv.com/var/www/html/file.html and then get error 404, telling me such file is not available.
The root cause seems to be that in both cases mod_rewrite converts the incoming URL into var/www/html/file.html. In the first case it just serves this file, which works great, but in the second case it returns the file path to the browser, who interprets that as a URL, and it all goes downhill from there. To fix the problem, I must add RewriteBase to the .htaccess file. To be fair,
Apache docs do say it is required, but they don’t say it is required only for permanent redirects. Most sane people would assume that if temporary redirects work, permanent redirects will work as well, but it is not the case.
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)\.temp$ $1.html
RewriteRule ^(.*)\.perm$ $1.html [R=permanent]
Note that I need to specify the base URL of the directory. I.e., if I have .htaccess file in some other directory, I must add RewriteBase /that/dir/url. This is quite inconvenient, because
a) as I move directories around, RewriteBase may become broken, and
b) if a directory can be reached via multiple URLs, I will have to pick one as RewriteBase, with possible security issues and other inconveniences.
Why can’t we just make things work without surprises? That’s obviously, a rhetoric question: one’s person surprise is another person completely obvious and logical behavior.