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.
Permalink
Why do you define redirect rules in a separate files instead of defining all redirect logic in web application code (C#)?
Permalink
Why don’t they eat cake?
These are static files. There is no web application. And most definitely no C#: it’s a LAMP machine.
Permalink
Why bother with permanent redirect if they are just static files?
Permalink
> The server does not report the redirect back to the browser, but quietly serves file.html instead of file.temp.
Is that what you call “temporary redirect”? Usually what you described is called “URL routing”.
Usually under “temporary redirect” we understand “HTTP 302 redirect” which is distinct from “HTTP 301 redirect” (AKA “Permanent Redirect”).
> It turns out that temporary redirects just work
Now it is not clear what exactly works in your case: “URL routing” or “HTTP 302 redirect”.
Permalink
Sorry for the long delay. Temporary redirect is not visible to the client, it is done quietly on the server side. Permanent redirect results in code 301 by default.
I bother about static files, because they are in Google results and what-not, and I want to keep the old URLs functional.
Permalink
You insist on non-standard definition of “temporary redirect”.
See what, usually, “temporary redirect” means:
https://www.google.com/search?q=temporary+redirect
Permalink
I guess, the correct terms are internal and external redirect, as per description of the [R] flag here: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule
In any case, the behavior should not be that drastically different.
Permalink
Your quoted article calls it “Rewrite” (not “internal redirect”).