LarakBell
LarakBell

Reputation: 618

rewrite www to non www doesn't work using two htaccess file

I have two .htaccess file.

in root:(this file redirect to public folder)

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^$ /public/index.php/home/index [L]
RewriteRule ^(.*)/$ $1
RewriteRule ^(.*)$ /public/$1 [L]
</IfModule>

and in public folder I have:

# Disable directory browsing
Options All -Indexes

# ----------------------------------------------------------------------
# Rewrite engine
# ----------------------------------------------------------------------

# Turning on the rewrite engine is necessary for the following rules and features.
# FollowSymLinks must be enabled for this to work.
<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On

    # If you installed CodeIgniter in a subfolder, you will need to
    # change the following line to match the subfolder you need.
    # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
    # RewriteBase /

    # Redirect Trailing Slashes...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Rewrite "www.example.com -> example.com"
    RewriteCond %{HTTPS} !=on
    RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
    RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

    # Checks to see if the user is attempting to access a valid file,
    # such as an image or css document, if this isn't true it sends the
    # request to the front controller, index.php
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]

    # Ensure Authorization header is passed along
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

<IfModule !mod_rewrite.c>
    # If we don't have mod_rewrite installed, all 404's
    # can be sent to index.php, and everything works as normal.
    ErrorDocument 404 index.php
</IfModule>
# X-XSS-Protection
<IfModule mod_headers.c>
    Header set X-XSS-Protection "1; mode=block"
</IfModule>
# X-Frame-Options
<IfModule mod_headers.c>
    Header always append X-Frame-Options SAMEORIGIN
</IfModule>
# X-Content-Type nosniff
<IfModule mod_headers.c>
    Header set X-Content-Type-Options nosniff
</IfModule>
# Disable server signature start
    ServerSignature Off
# Disable server signature end

I add this code for redirect www to none www in public folder .htaccess file:

# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

but in action, my www not redirect to none www. how do can I fix this problem?

Upvotes: 3

Views: 1113

Answers (1)

MrWhite
MrWhite

Reputation: 45978

# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

The issue here is that the REQUEST_URI server variable contains the full URL-path, including the /public subdirectory, so this will expose the /public subdirectory in the redirect.

Aside: Also, as mentioned in comments, unless you only want to perform the www to non-www redirect for HTTP-only requests then you should remove the first RewriteCond directive that checks the HTTPS server variable. I would also think you should be redirecting to https:// here, not http://?

You need to either...

Capture the URL-path in the RewriteRule pattern and use this instead of the REQUEST_URI server variable (which is actually what you are doing in the preceding rule). For example:

# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule (.*) https://%1/$1 [R=301,L]

The captured URL-path (ie. $1) is relative to the current directory, so excludes the /public subdirectory. This also excludes the slash prefix.

However, without additional directives, the above will expose the /index.php/home/index URL (in the case of requests to the root).

OR, move this redirect to the root .htaccess file, which is preferable since it will naturally prevent the /index.php/home/index URL from being exposed. For example:

RewriteEngine On

# Redirect "www.example.com -> example.com"
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

# Rewrite to /public subdirectory
RewriteRule ^$ public/index.php/home/index [L]
RewriteRule ^(.+?)/?$ public/$1 [L]

(The <IfModule> wrapper is not required.)

Note that you should first test with 302 (temporary) redirects to avoid potential caching issues. Only change to 301 (permanent) when you are sure it's working as intended.

You will need to clear your browser cache before testing.

Upvotes: 4

Related Questions