|Problem using mod_rewrite / .htaccess in the root directory|
I'm having a problem with using mod_rewrite on a per-directory basis when the directory is the site's root directory. I want all requests for files in the site's root directory to be rewritten (redirected) to my script, which is in the root directory.
I've put the .htaccess file in the root directory and included RewriteBase / in it (although I don't think that line is necessary). I've tried it with and without that line.
If a requested file actually exists in the root directory, then the request is rewritten (redirected) to my script file. But when the requested file does not exist, a 403 (forbidden) message is returned.
If the whole thing is done in a sub-directory, then everything works ok, and the requested files need not exist.
I've been looking at the difference between the physical and URL paths, but I don't think the answer lies there, or it wouldn't work in a sub-directory.
Does anyone know how to rewrite (redirect) all file requests for files in the site's root directory to my script using mod_rewrite (per-directory) with the .htaccess file?
Note: I'm aiming at creating the site so that no static pages exist.
It would be very helpful if you could check your server error log, and find out where these root directory requests are being redirected to. That may clarify why you're getting a 403 response, and give a clue as to what steps you need to take to get it to work.
Also, typing one of your root directory URLs into the Server Headers Checker [webmasterworld.com] might provide some info as well.
Hi Jim. Thank you for your response.
I've used the header tool and it produced:-
HTTP/1.1 403 Forbidden
Date: Tue, 17 Feb 2004 20:43:42 GMT
Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) mod_ssl/2.8.12 OpenSSL/0.9.6b DAV/1.0.3 PHP/4.1.2 mod_perl/1.26
Content-Type: text/html; charset=iso-8859-1
I've checked the site's error log (not the server error logs), and the 403s produce:-
[Tue Feb 17 20:01:50 2004] [error] [client 18.104.22.168] (13)Permission denied: cannot read directory for multi: /home/bradford/example.org.uk/html/
That's the correct physical directory for the site's root directory.
I think you want me to look at the server's error logs, yes? It's not my server but I can get to them if necessary.
[edited by: jdMorgan at 9:21 pm (utc) on Feb. 17, 2004]
[edit reason] Examplified domain name [/edit]
OK, well that narrows things down a bit.
First, there is no "unexpected" redirect happening that is causing the 403, since the header check showed the 403 response immediately (I presume) in response to your request for the page, and not a 301 or 302 redirect.
Then the error log (that's the one I meant) shows an error reading the directory. That is "the" problem, although I can't say I know what it means, since I haven't seen that one before.
Do you have multiviews (content-negotiation) enabled, and if so, do you really use/need it? If not, you could turn them off and see if that either fixes or changes the problem. The directive would be
Options -MultiViews in either .htaccess or httpd.conf.
That is a guess, and only a guess, based on the word "Multi" in the logged error message.
<added> This search [google.com] resulted in a lot of pages on this subject </added>
Dammit, that worked Jim! - in the .htaccess file.
I've no idea what MultiViews are. Would you give me a brief overview or point me to where I can read about it, so that I know what I've turned off, and if it's likely to be needed for anything?
Many many thanks, Jim. Yer a gem! :)
<added> I've found an Apache document about it, which I'm reading now, so forget my request - and thanks again! </added>
<added> You beat me to it :) </added>
It's a means for the server to return a 'matching' file when an exact filename hasn't been given in the request URL - or something along those lines. Anyway, it doesn't affect the operation of the site, and I am very pleased with your help, Jim.
One more thing, if I may.
I'm using the following RewriteRules to divert all .html and requests for the domain to the rewrite.php script.
#cover for a request for the domain
RewriteRule ^$ rewrite.php [T=application/x-httpd-php] [L]
#send requests for all html files, in this directory only, to rewrite.php
RewriteRule ^(.*)\.html$ rewrite.php [T=application/x-httpd-php]
I'm not well up on regular expressions but I'm thinking that it should be possible to combine the 2 rules into one with an OR operator. I've looked around but I haven't found any example of a regex OR. Can it be done?
This should do it, plus bring your regex in line with the objective you posted -- to redirect requests for .html resources in the root directory only. "^.*\.html$" would redirect for any .html file in any directory, while "^[^/.]*\.html$" redirects only if the filename is not preceded by a slash (which would indicate a subdirectory request) or another period (this just makes the regex processing for this case faster).
If you *do* want to redirect .html requests in subdirectories, then you could use "^[^.]*\.html$" or your original "^.*\.html$" shortened to "\.html$". In either case, the parentheses are not needed, since you are not creating a back-reference or a complex nested OR pattern.
RewriteRule ^$¦^[^/.]*\.html$ rewrite.php [T=application/x-httpd-php]
Note that you must replace the broken pipe "¦" character with a solid pipe character from your keyboard before use.
Many thanks again Jim. I can't say that I understand all that you wrote but I'm copying it and keeping it in a file (until tommorrow) when I'll study it, do what you suggest, and hopefully understand why :)
I do recognize the pipe OR from Perl (where it's a double pipe), but I didn't want to do too much experimenting because mod_rewrite is too powerful and too much messing about can crash the server - I've done it the past :(
Thanks again Jim :)
> I didn't want to do too much experimenting because mod_rewrite is too powerful and too much messing about can crash the server - I've done it the past.
Wisdom comes from adversity.
And mod_rewrite can make you wise very quickly. ;)
RewriteRule ^$¦^[^/.]*\.html$ rewrite.php [T=application/x-httpd-php]
From the link you posted, I think I now understand the [^/.] part. I understand it to mean 'except any character in the sqaure brackets' (not including the ^ unless it's escaped), so the regex doesn't match any sub-directories. I think I understand why the dot is in there - it's to ensure that at least one character follows the slash, yes/no?
Actually, I now think that is probably not the reason...hmmm...
That "[^/.]*" subpattern matches any number of any characters except for a dot or a slash. Inside square brackets "^" means "not" and you don't need to escape characters except for "]" (and also "-" under special circumstances).
Gotcha. Thank, Jim, for all your help :)
Hi Jim & everybody,
I'd ilke catch up on this thread. I'm having the same problem as PhilC (getting 403 on a MultiViews directory with Redirect set), but I need to use the MultiViews.
I tried a small tweak, which did not help anyway, to do the redirect as Redirect permanent /archiv/ [my.website.org...] instead of the preferred Redirect permanent /archiv [my.website.org...] (hostname changed in example).
Would you have any helpful ideas, please?