Silas2
asked on
Rewrite Rule head scratcher
I've got the default Wordpress/Magento htaccess rules:
e (so no index.php in URL), I get (a very desired) "REDIRECT_REDIRECT_HTTP_AU THORIZATIO N: OAuth etc. " in the $_SERVER variables, but if I leave the line in, the value disappears.
Can anyone help explain this?
DirectoryIndex index.php
...
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
If I comment out the line RewriteRule ^index\.php$ - [L] and fire mydomain.com/oauth/initiatCan anyone help explain this?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
i'd assume you are looping multiple times : the first pass transforms your url into /index.php, and you then loop a second time over the whole ruleset and hit the rule.
this is the design of mod_rewrite : loop until the input and output are identical. even using [L] probably only terminates the current iteration (though the doc says otherwise). using [END] rather than [L] probably would make a difference.
you can easily debug that by activating the rewritelog. loglevel 2 should be enough. be VERY careful on busy servers, this really produces LOTS of debug.
---
regarding the disappearance of the header, i'd assume either
- a bug in mod rewrite ( unlikely )
- or a limitation in the number of times REDIRECTED_ can be prepended to headers, ( dunno of such a limitation )
- or possibly the header name's length becomes too big for either apache or php to handle ( more likely )
kicks in.
---
also note that @gheist's replacement suggestion would probably solve your initial issue in a more elegant way without toying with $_SERVER. i'd give it a shot.
this is the design of mod_rewrite : loop until the input and output are identical. even using [L] probably only terminates the current iteration (though the doc says otherwise). using [END] rather than [L] probably would make a difference.
you can easily debug that by activating the rewritelog. loglevel 2 should be enough. be VERY careful on busy servers, this really produces LOTS of debug.
---
regarding the disappearance of the header, i'd assume either
- a bug in mod rewrite ( unlikely )
- or a limitation in the number of times REDIRECTED_ can be prepended to headers, ( dunno of such a limitation )
- or possibly the header name's length becomes too big for either apache or php to handle ( more likely )
kicks in.
---
also note that @gheist's replacement suggestion would probably solve your initial issue in a more elegant way without toying with $_SERVER. i'd give it a shot.
ASKER
These rewrite rules are the first in the htaccess file, I was wondering then if DirectoryIndex index.php - does that perform a rewrite?
no relation between rewrite rules and directoryindex.
afaik rewrite rules are processed before directives such as directoryindex but you may want to doublecheck.
but anyway in your case they apply to different paths : calling / as the url will trigger directoryindex ( which in turns would be processed by mod_rewrite if i'm wrong about the order ), calling /whatever will trigger the rewrite.
--
do you understand what i mean by looping ?
afaik rewrite rules are processed before directives such as directoryindex but you may want to doublecheck.
but anyway in your case they apply to different paths : calling / as the url will trigger directoryindex ( which in turns would be processed by mod_rewrite if i'm wrong about the order ), calling /whatever will trigger the rewrite.
--
do you understand what i mean by looping ?
ASKER
I'm guessing looping means that if a test/condition fails, then if the url gets altered in a subsequent rewrite, it gets tested again so it may pass a second time...?
ASKER
Ahhh....maybe the penny is dropping a bit.....if my looping guess is right....the last rewrite in the htaccess is RewriteRule .* index.php [L], so everything gets rewritten to append index.php, and then the url mydomain.com/oauth/initiat e qualifies for RewriteRule ^index\.php$ - [L]
so maybe, as you say, the depths get too much..
so maybe, as you say, the depths get too much..
not sure we mean the same thing...
mod_rewrite works by applying the whole ruleset multiple times :
RewriteRule /y /z
RewriteRule /x /y
actually rewrites x to z whatever the specified order for redirections
the looping goes on until a pass through the ruleset produces no change. ( a hit that makes no difference doesn't count ? not sure )
so whenever you get redirected, you loop at least twice ( 3 times in the above example )
i'm unsure of the [L] flag behavior : it may end the iteration or the whole process.
given the fact apache ends up prefixing REDIRECTED_ multiple times it would seem it is the iteration
[END] would actually definitely end the whole thing. you can test if replacing the flags makes a difference
in your case, it seems possible that adding redirected_ a 3rd time hits a limit : the header name's length would reach 48 chars. i have no idea if that is the issue but it seems possible either apache or php would ignore/discard the header. the length for the whole header can't be the issue as it is MUCH bigger than the header
mod_rewrite works by applying the whole ruleset multiple times :
RewriteRule /y /z
RewriteRule /x /y
actually rewrites x to z whatever the specified order for redirections
the looping goes on until a pass through the ruleset produces no change. ( a hit that makes no difference doesn't count ? not sure )
so whenever you get redirected, you loop at least twice ( 3 times in the above example )
i'm unsure of the [L] flag behavior : it may end the iteration or the whole process.
given the fact apache ends up prefixing REDIRECTED_ multiple times it would seem it is the iteration
[END] would actually definitely end the whole thing. you can test if replacing the flags makes a difference
in your case, it seems possible that adding redirected_ a 3rd time hits a limit : the header name's length would reach 48 chars. i have no idea if that is the issue but it seems possible either apache or php would ignore/discard the header. the length for the whole header can't be the issue as it is MUCH bigger than the header
ASKER
That is what I meant about looping, so now I get how removing RewriteRule .* index.php [L], could affect mydomain.com/oauth/initiat e (no index.php), but I'm still completely in the dark over how gheist's remark ErrorDocument 404 /index.php could affect it unless it hits a 404?
i'm unsure. replacing the rewrites with this would produce non existent urls to be redirected to index without passing through the rewriting process so without adding the redirected_ prefixes.
if magento uses dummy urls and there is no actual files, that would work : you'll be hitting 404 all the time. it does not look like 'initiate' would be a file name and @gheist probably would not post this info at random so it might be worth a shot. if it does not work out-of-the-box, maybe combinations can.
have you tried to use [END] instead of [L] ?
if magento uses dummy urls and there is no actual files, that would work : you'll be hitting 404 all the time. it does not look like 'initiate' would be a file name and @gheist probably would not post this info at random so it might be worth a shot. if it does not work out-of-the-box, maybe combinations can.
have you tried to use [END] instead of [L] ?
ASKER
Errr.....they both worked with /oauth/intiate ([END] instead of [L] and ErrorDocument 404 /index.php) , but with a big proviso, they both broke the site with just domain name http://chamberspetsupplies.co.uk/!!
ASKER
Somehow index.php wasn't getting called (although I can't quite work out how oauth authentication happened without index.php with its all important Mage::run() call.
just domain name should be handled by the DirectoryIndex directive, i think.
if for some reason that does not work, you probably handle the bare domain with a dedicated
rewriterule ^/$ /index.php [R]
if for some reason that does not work, you probably handle the bare domain with a dedicated
rewriterule ^/$ /index.php [R]
ASKER
Does it matter where that rule goes?
not really, but if you're using 404, it should probably be the only rule.
if you replace L with END, i'd put it on top of the ruleset.
given how fast mod_rewrite is compared to the site's weight, it matters that it works but trying to make it more efficient is useless.
if you have other things to discuss, please post the current config so we know what we're talking about
if you replace L with END, i'd put it on top of the ruleset.
given how fast mod_rewrite is compared to the site's weight, it matters that it works but trying to make it more efficient is useless.
if you have other things to discuss, please post the current config so we know what we're talking about
ASKER
Thanks for all your help, I really appreciate it.
I'm thinking that with :
I'm thinking that with :
#RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
i.e. taking out the RewriteRule ^index\.php$ - [L], I'm only losing the rewrite if someone explicitly types domain.com/index.php - which doesn't matter - and even then will still route ok?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks
ASKER
How would removing RewriteRule ^index\.php$ - [L] have any affect if there's no 'index.php' in the URL?