0

I know that too much questions exist for htaccess redirection, but I couldn't find the exact solution. I'm sorry if there exist a matching question.

In my public html (webroot) folder there was following htaccess file:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

Then to redirect URLs with "www" to "non-www" I added two lines. And file became like this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]

    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

</IfModule>

So the problem is, www.example.com redirects to example.com but www.example.com/mycontroller/ weren't redirected to example.com/mycontroller/

How can I solve this?

trante
  • 33,518
  • 47
  • 192
  • 272

1 Answers1

6

The first RewriteRule will rewrite every URL that doesn't have an actual physical file/folder to the index.php page but if there is a match, it will treat this as the last rule and stop processing all further rules (the [L] flag). So when you call with just the root path, it doesn't get triggered and continues to your www rewrite rule but any other logical URL triggers the first rewrite and stops.

Simply change the order of the rules, put your RewriteCond/RewriteRule pair before the default ones.

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]


</IfModule>

If you run this as virtual host and have access to Apache's config files , consider putting your rules in Apache's virtual host conf file to avoid this being overridden when you update Cake versions, or make sure to otherwise protect your changes.

danielv
  • 3,039
  • 25
  • 40
  • Thank you very much. I Didn't knot about "L" parameters. Also thanks for recommendation about Apache config files. – trante Jun 28 '12 at 10:06
  • RedirectMatch http://www\.(.*)\.(.*) http://(.*)\.(.*) seems to work fine too. Can you tell me the conceptual difference? – Eduardo Russo Oct 17 '13 at 09:28
  • 1
    RedirectMatch comes with a different Apache module (mod_alias). It achieves similar thing but is less flexible and powerful than RewriteCond/RewriteRule. You can only match against URL-path (therefore, your example won't work since it includes www subdomain, which is not part of URL-path. Also your redirect URL is a regex). With RewriteCond/RewriteRule you can match against various parts of the request and have multiple conditions. – danielv Oct 17 '13 at 10:36