Forum Moderators: phranque
redirect 301 /east-coast-festival/rules.php http://www.example.com/rugby/
Instead of redirecting to the /rugby/ directory it displays the following url and an error 404 not found.
http://www.example.com/rugby/rugby-festivals/east-coast-rugby-festival/rules.php
It appears to append rules.php to the end of filename of the redirect target.
Please can someone help?
[edited by: bill at 11:42 am (utc) on Sep. 28, 2009]
[edit reason] use example.com [/edit]
This is the code in my htaccess file
You'll need to use a RewriteRule instead of Redirect; then you can slice and dice which parts of the initial URL request go to build the target URL - or not.
Anyway, matched parts of a Redirect directive won't be appended, and that is the case here, too (new URL differs from input except rules.php).
> I'm wondering why always everybody switches directly to mod_rewrite.
Because the majority of people posting questions here are on shared hosting, and therefore cannot control their loadmodule list order. Therefore, if mod_rewrite is used for any redirect/rewrite, it should be used for all, rather than mixing mod_alias and mod_rewrite directives. Otherwise, as we've seen before, a server change or upgrade can result in an internal rewrite being invoked first, and then followed by an external redirect. The effect of this is to 'expose' the internally-rewritten filepath as a URL... Not good.
I'm as guilty as anyone of over-prescribing mod_rewrite for the reason above, and frankly, out of habit after dealing with the above-described problem on shared-hosting accounts for a decade.
So the answer is that it's a difference of perspective between those lucky enough to have server configuration access, and the vast majority of Webmasters who are on name-based virtual servers -- and many of them stuck with Apache 1.3.x for the foreseeable future...
Jim
I'm wondering why always everybody switches directly to mod_rewrite...
Personally, I'm not as experienced as jdMorgan with the headaches, possibly because I default to Mod_Rewrite since it's a much more powerful tool for manipulation of URLs and when I want to redirect / rewrite one URL I figure I'm probably going to want to (usually have to) do a bunch, and there's a regular expression for that... It also makes it so I can simply and easily switch from .html (unparsed server side) to PHP on the back-end without changing URLs on the front end and I do not have to parse all HTML as PHP.
Personally I think too many people default to 'Parse it all' when they need ten out of 100 pages ending in .html parsed as PHP, when all they really need to do is use a single line of Mod_Rewrite and parse only the ten... Why would I want to parse all HTML as PHP when I don't really need to?
Mod_Rewrite is a bit tougher to pick up, but is much more powerful and IMO can be used to save a great amount of server resources when used wisely...
One of my favorites in Mod_Rewrite is the S=N flag, because I can use a Negative Pattern match to Skip N Rules...
EG RewriteRule !^TheDirectoryIWantToManipulate/WithTheNext10Rules/ - [S=10]
It can also be used similarly in a positive match, where I know the number of rules between the rule matched and the ruleset I would like to use and if I'm really having fun I combine them:
EG
RewriteRule !^(TheDirectoryIWantToManipulate¦TheOtherDirectoryIWantToManipulate)/ - [S=22]
RewriteRule ^TheDirectoryIWantToManipulate/ - [S=1]
RewriteRule ^TheOtherDirectoryIWantToManipulate/ - [S=10]
# The Second Rule skips to here.
'Ten RewriteRules & Conditions for TheDirectoryIWantToManipulate Here'
# The Third one skips to here.
'Ten RewriteRules & Conditions for TheOtherDirectoryIWantToManipulate Here'
# The First one skips to here. (Probably just canonical and general rules)
Although our perspectives may differ because of our server-privilege expectations and Webmaster/Admin roles, it's always good to see concern for efficiency in threads here -- far too many Webmasters throw up code with no consideration of its efficiency and are forced into early server upgrades as a direct result -- witness my on-going battle against use of the ubiquitous but horribly-inefficient "(.*)/(.*)$ regex pattern and unnecessary file- and directory-exists checking.
Pretty much all Wordpress and Joomla installs have horribly-inefficient mod_rewrite code, because that bad code is supplied with the software! On a positive note, I've seen some signs that perhaps their developers are reading here, because the rules supplied with at least one major package have been improved recently, and some the tweaks resemble my coding style (but of course, I may be flattering myself).
My preference for mod_rewrite when doing both internal rewrites and external redirects is explained above, but for the other cases, it's perfectly-valid to ask, "Why not use this other module, which is simpler and therefore more-efficient?" -- especially if one has admin privileges and doesn't have to deal with the recursion problems often seen in the .htaccess context.
Jim
a server change or upgrade can result in an internal rewrite being invoked first, and then followed by an external redirect.
That can't change anything because Redirect from mod_alias operates with r->uri and mod_rewrite with r->filename. If r->uri matches the Redirect directive, the redirect will fire as it would w/o any RewriteRule present. You can't get the changed r->filename (by a previous RewriteRule) into r->uri in directory context. Since both modules are using different input you can't expose paths by running mod_rewrite prior mod_alias or vice versa. Rewrite first or not, you'll always get the redirect with the same result since all fixups will run prior mod_rewrite's content handler gets called to initiate the internal redirect.
Interactions with a path previously created/modified by a RewriteRule can only occur within the internal redirect processing when a Redirect directive matches against new->uri containing the URL-path of the result from mod_rewrite in r->prev. However, the order of the fixup hooks would be still not relevant. So there must have been something else but not just the fixup order.
Anyway I made my comment w/o the intention to discuss interactions but functionality regarding "slice and dice which parts of the initial URL request go to build the target URL - or not". And that - in an isolated view (just to be clear now) - can be done with RedirectMatch pretty well, too.
There are efforts going on to replace common mod_rewrite recipes with more efficient solutions but if people start to replace simple access controls with mod_rewrite [webmasterworld.com] (there are good reasons why access controls have their own hook) I wonder if that can be fruitful.
> So there must have been something else but not just the fixup order.
No idea what the problem could have been then, but we've had several cases here where filepath exposure problems were fixed by switching from mixed mod_alias and mod_rewrite code to all-mod_rewrite code.
Now this is going to bother me until I have time to research it thoroughly, because I cannot tolerate unsolved mysteries... Was it MultiViews, a [PT] flag on a rule 'hidden' somewhere and not discussed, what? :(
Thanks for the detailed analysis and description, though. Much appreciated.
Jim
Was it MultiViews, a [PT] flag on a rule 'hidden'
Those are other issues, of course. mod_negotiation's MultiViews runs always prior mod_rewrite's/mod_alias' directory context, because it doesn't use a fixup but a type checker hook (you can control the order with AddModule in 1.3.x only within a hook and not the order of the hooks itself, of course).
The PT flag has only an effect in per-server context, i.e. in mod_rewrite's translate_name hook. It is functionless in directory context (except the "break", i.e., the same the L flag does). But if it would have a function in per-dir context and would copy mod_rewrite's result directly to r->uri, the result would be the same for "expose paths".
A later coming mod_alias can't redirect the old uri anymore (since it was changed). It would look directly at the new r->uri, the same it'll do in the internal redirect processing. That means it could expose the new path one step earlier, not just in the internal redirect processing but in the same round of processing where mod_rewrite acted.