Mod_Rewrite Voodoo Problem - not just your average magic... [solved - but interesting!] |
[eluser]Narkboy[/eluser]
I'm having a night mare with 3 rewrite requirements for a site. Each works on it's own, but I cannot make them work together! The site is a little odd: DNS points several domains to the same CI installation - each for it's own country. foo.it, foo.es, foo.co.uk, foo.ca, foo.nl etc. etc. CI grabs the relevant language / localisation and then displays pages. This adds a level of complexity to the rewrite because they must deal with several different domains. There are 3 rewrite requirements (ordered correctly, I believe, but then it's not working so maybe not): 1) If no subdomain exosts, redirect to www.foo.<ext>. This is mainly for search engines. Everything on the main site should be served from www.foo.<ext> 2) Apart from www, there are any number of possible subdomains that need to be handled by requesting data from index.php/site/<sub-domain> 3) The usual removal of index.php needs to happen. Examples: Req 1) http://foo.es -> should REDIRECT to http://www.foo.es http://foo.it -> should REDIRECT to http://www.foo.it Req 2) http://bar.foo.ie -> should appear the same but load from http://www.foo.ie/site/bar http://bar.foo.ie/this/topic -> should appear the same but should load from http://www.foo.ie/site/bar/this/topic Req 3) Pretty obvious. Req 1 - Rewrite: Code: RewriteCond %{HTTP_HOST} ^foo\.([a-z\.]{2,5})$ [NC] This works (on it's own): if HTTP_HOST starts with 'foo', there is no subdomain, so redirect to www.foo. I've not tackled what happens if you enter "foo.foo.co.uk" for example. Req 2- Rewrite: Code: RewriteCond %{HTTP_HOST} !^(www\.foo.*)$ [NC] This works (on it's own): if the HTTP_HOST is not "www.foo<anything>" AND if the HOST has a subdomain, then request from index.php/site/<subdomain>. I've not tackled appending the rest of the URI as yet. Req 3 - Rewrite: Code: RewriteCond $1 !^(index\.php|img|style|license\.txt|robots\.txt|script) [NC] This also works (on all my CI apps) to resolve anything except the words listed as index.php/blah. Running each one on it's own is fine. Adding them together puts me into a loop. The loop is part of req 2 - effectively, entering http://bar.foo.ie (and hoping for http://www.foo.ie/site/bar to be displayed) gives me an infinate loop whereby "site/bar" is requested over and over. I'm going round in circles and getting really dizzy with this. Please please please - a fresh pair of eyes and maybe some insight? Thoughts anyone? Thanks in advance! Ben
[eluser]mddd[/eluser]
I think you could just check in routine #2 if the requested uriis not already /site/... That way, the loop is broken. If someone goes to bar.foo.com, the redirection goes to /site/bar and at that time it will no longer match the condition so it will not redirect again. Code: RewriteCond %{HTTP_HOST} !^(www\.foo.*)$ [NC]
[eluser]Volder[/eluser]
Code: RewriteCond %{HTTP_HOST} !^(www\.foo.*)$ [NC] it looks like the rule 2 as it is, has an infinite loop by itslef - so strange that it is working fine by itself (maybe apache or whatever server you use automatically detects a loop and stops it). So if you give as an input right now: http://bar.foo.ie/this/topic 1 iteration: http://bar.foo.ie/site/bar 2 iteration: http://bar.foo.ie/site/bar/site/bar so 2 mistakes I see: you don't specify fully the domain and subdomain here + you loose everything in your parameters. So try the following fix: Code: RewriteCond %{HTTP_HOST} !^(www\.foo.*)$ [NC] I use %2, %3 because %1 should relate to first RewriteCond (which we don't want), right? I don't remember for sure. I have not tried it (just thoughts), so probably it is not a working soluition, but could be of some help for you.
[eluser]Narkboy[/eluser]
Ok - thanks to mddd and Voldor, I have something of an improved version: Code: # Check that 'foo.xx' is the host: This works with pretty much everything, except: http://bar.ie Gives me a 302 - Found, with a link to the url we're on. Useless. The Apache error log tells me - Code: (38)Filename too long: Cannot map GET / HTTP/1.1 to file Which is just weird. Commenting out the last cond + rule means http://bar.ie redirects to http://www.bar.ie, but that means www.foo.ie/welcome does not. Reqs 1 & 3 are killing each other Thanks for the help guys - I'm going to fiddle some more.. Ben
[eluser]mddd[/eluser]
Are you sure this rule is working: RewriteCond %{REQUEST_URI} !^\/index\.php\/site/ [NC] Should the first / be in there or should it just be !^index\.php Or you could even just check for !index.php -- that way the redirect will never happen if there is index.php anywhere in the uri. If that rule doesn't 'catch', the system will turn bar.foo.ie into bar.foo.ie/index.php/site/bar and then into bar.foo.ie/index.php/site/bar/index.php/site/bar etc.
[eluser]Narkboy[/eluser]
I've tried changing it to !index.php but it dosen't seem to make a difference. I see your logic - but Apache is not reporting a loop. Unless it is iterating enough to create a filename that's too long for windows (error 38) BUT not reaching the limit of 10 internal redirects, then I don't see how it could fail but not kick an error in the log. That said, the log reports nothing of use! Thanks!
[eluser]Narkboy[/eluser]
This is driving me nuts: See Apache access.log details: http://www.docvad.es gives: 127.0.0.1 - - [13/Apr/2010:15:34:56 +0100] "GET / HTTP/1.1" 200 1069 BUT http://docvad.es gives: 127.0.0.1 - - [13/Apr/2010:15:35:06 +0100] "GET / HTTP/1.1" 403 - How does that make sense????
[eluser]Narkboy[/eluser]
Ok, it makes perfect sense. I bumped the RewriteLogLevel up a bit. Seems that the current script is generating request URIs which run to several thousand chars within 4-5 iterations. Oops.
[eluser]Narkboy[/eluser]
I have fixed it. The final loop was down to an incorrect backreference in req 3, disguised by some excellent work from the caching on Firefox. Code: RewriteEngine on So - this is what you want if you need to serve multiple tlds on the same site, want to require the use of 'www' and have a variable list of subdomains which need serving by a CI controller. http://foo.fr/bar becomes http://www.foo.fr/bar http://bar.foo.ca/foobar reads from http://www.foo.ca/site/bar/foobar http://www.foo.nl/welcome reads from http://www.foo.nl/index.php/welcome ^seemples^ *phew* An _entire_ day wasted on this, and I'm not 100% I'm getting the contract yet. Thanks for everyones help! Ben
|
Welcome Guest, Not a member yet? Register Sign In |