Search code examples
apache.htaccesshttp-redirectmod-rewritehttps

Which option is correct to redirect the index page: HTTP or HTTPS version of the website?


I don't know much about .htaccess files or web server configuration, and I've been trying to figure out why my website's index.php file is being redirected to the HTTP version instead of HTTPS. I've been searching for answers for days, but I can't find anything that explains it.

Here's the problem. I have the following rules in my .htaccess file:

# Do not remove this line, otherwise mod_rewrite rules will stop working
RewriteBase /
RewriteCond %{HTTP_HOST} ^mywebsite\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.mywebsite\.com$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/cpanel-dcv/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^index\.php$ "http\:\/\/www\.mywebsite\.com\/" [R=301,L] 

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/cpanel-dcv/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

My question is about this line: RewriteRule ^index\.php$ "http\:\/\/www\.mywebsite\.com\/" [R=301,L].

Considering that my website works with HTTPS, is it correct to redirect index.php to the HTTP version, as written in the last line?

I'm concerned if this rule may cause issues, if it's the intended behavior. I want to make sure I'm properly redirecting to the appropriate protocol. I'm getting lots of 302 status code in my logs and I thought maybe that's because the redirect is wrong and should be to the https version of the site.

I'm really struggling with this one and I can't find an answer. I can't do much because I'm afraid a wrong change will cause harm to the website. I would really appreciate it if someone could help me understand what's going on.


Solution

  • I've been trying to figure out why my website's index.php file is being redirected to the HTTP version instead of HTTPS.

    You identify "why" later in the question...

    Considering that my website works with HTTPS, is it correct to redirect index.php to the HTTP version, as written in the last line?

    But no, it's not "correct", you should be redirecting to HTTPS, if anything. (Back at ya... why would you redirect to HTTP when your site works on HTTPS? That makes no sense and is clearly an error. UPDATE: Particularly since you are redirecting to HTTPS in the next rule!)

    I'm getting lots of 302 status code in my logs

    UPDATE: From your updated question, your second rule (an HTTP to HTTPS redirect) is a 302 (temporary) redirect. If you are redirecting to HTTP in the first rule then the second rule will "correct" this with a 2nd redirect!

    However, you shouldn't be getting "lots" of 302s in your logs, since you should not be linking to /index.php in the first place. (?)

    A closer look at your directives...

    # Do not remove this line, otherwise mod_rewrite rules will stop working
    RewriteBase /
    

    That comment is probably referring to the RewriteEngine On line that occurs later in the file? The RewriteBase directive is not required here (it is not being used) and should be removed.

    RewriteCond %{HTTP_HOST} ^mywebsite\.com$ [OR]
    RewriteCond %{HTTP_HOST} ^www\.mywebsite\.com$
    

    Since you stated (in comments) you only have one domain then these two conditions are not required.

    RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
    RewriteCond %{REQUEST_URI} !^/\.well-known/cpanel-dcv/[0-9a-zA-Z_-]+$
    RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
    

    These conditions are added automatically by cPanel. However, in the first rule they are not required and can be removed. (If the requested URL is /index.php then the URL is obviously not going to be one of those URLs - so the conditions are nonsense. But like I say, those conditions are blindly added before every rule - bit of a mess really.)

    RewriteCond %{HTTPS} off
    RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
    RewriteCond %{REQUEST_URI} !^/\.well-known/cpanel-dcv/[0-9a-zA-Z_-]+$
    RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    

    You are missing the R=301 and L flags on the last rule. Consequently this defaults to a 302 (temporary) redirect instead. It should be a 301 (permanent) redirect.


    In summary, your rules could be written more simply like this:

    RewriteEngine On
    
    # Redirect "/index.php" to "/" (and HTTPS)
    RewriteRule ^index\.php$ https://%{HTTP_HOST}/ [R=301,L] 
    
    # Redirect HTTP to HTTPS (except for the ".well-known" directory)
    RewriteCond %{HTTPS} off
    RewriteRule !^\.well-known/ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    

    I've used a more broad-brush approach in the HTTP to HTTPS (second) rule and excluded all URLs that point to the /.well-known subdirectory. (Although cPanel might re-add those conditions when SSL certs are auto-renewed!)

    No need for all those backslash-escapes in the substitution string (that's typical cPanel).

    Note that this does not canonicalise www vs non-www. That is left as an exercise for the reader.