Link to home
Start Free TrialLog in
Avatar of Ivan Garcete
Ivan Garcete

asked on

Help with .htaccess rules working together

Hello, I have a website hosted at InMotion hosting an I'm having trouble making the .htaccess rules work properly. I need rules for:

1. Force https on every page
2. Force www. when not entered
3. Hide index.php, so a page looks like this https://www.gastronegocios.com/contacto instead of https://www.gastronegocios.com/index.php/contacto

I currently have this rules, but their not working properly:

RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$

RewriteEngine On

RewriteBase /
RewriteCond %{HTTPS} off

RewriteCond %{HTTP_HOST} ^gastronegocios.com [NC]
RewriteRule (.*) https://www.gastronegocios.com/$1 [R=301,L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?/$0 [PT,L]

Open in new window

Avatar of Dr. Klahn
Dr. Klahn

Lines 1 and 2 will never be executed as they occur before the RewriteEngine On.

Debugging this problem will be simpler if you handle each condition separately.  As it stands, all the conditionals are piled together and this won't work unless each one is satisfied.  Then let Apache loop through again and process the next condition.  Use of the [L] should be rare, only in circumstances where it is absolutely certain that there are no other rules that might need to be applied.  As such it is normally used only in error or refusal rules.

First, do the www rewrite as this one is easy.  Let Apache fall through to succeeding conditions.

Then do the HTTPS rewrite as this is not difficult either. Let Apache fall through to succeeding conditions.

This should really be in httpd.conf and not in an .htaccess because it occurs across all URLs.


At this point the URL will be rewritten to HTTPS with a prefixing www.

Now do the last rewrite, the one that has the most chance of giving you trouble.  I would note that as you have presented it, it can't work as the "index.php" is not the last thing in the URI.  What would happen as it is presented in the problem statement is that Apache would look in directory "https://www.gastronegocios.com/index.php/contacto" for a file named index.html.  So reconsider that rewrite carefully.
Don't use 301 redirects until you've got everything working. The client browser will cache the redirect, and for client browsers other than your own, you've got no easy way of fixing that problem sometimes. For your own browser, it's also a right pain to have to clear the cache to prevent it redirecting (if you haven't done it before).

Use a 302 redirect instead, and change it to a 301 when you've got it all working as intended.
Avatar of Ivan Garcete

ASKER

Hello, I changed it to you recomendations guys, but now nothing is working. I forgot to tell you that I have no experience with .htaccess rules. I was basically finding code in StackOverflow and trying it out in my website.

This is the current code:

RewriteEngine On

RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$

RewriteBase /
RewriteCond %{HTTPS} off

RewriteCond %{HTTP_HOST} ^gastronegocios.com [NC]
RewriteRule (.*) https://www.gastronegocios.com/$1 [R=302,NC]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?/$0 [PT]

Open in new window


Right now it doesn't force the www nor the https. The index.php is well hidden though.

Thanks!
Do this one thing at a time.

1.  Insert the rewrite rules in httpd.conf, not in an .htaccess file.  The format is different for some things.

2.  Comment this stuff out while debugging:
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt ...

Open in new window


Start with the simple issue, a potential missing "www".

#
# Enable mod_rewrite
#
RewriteEngine On

#
# Rewrite URLs missing a leading WWW, preserving HTTP/HTTPS
#
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* %{REQUEST_SCHEME}://www.%{HTTP_HOST}/$1 [R=302]

Open in new window


The "R=302" redirect indicates to the browser "I did not like the format of your URL, but I am redirecting you to where I think it might be."

Confirm that this works to your satisfaction.  Then comment out that code and move on to the next one.

RewriteEngine On

#
# Rewrite URLs missing a leading WWW, preserving HTTP/HTTPS
#
#RewriteCond %{HTTP_HOST} !^www\. [NC]
#RewriteRule .* %{REQUEST_SCHEME}://www.%{HTTP_HOST}/$1 [R=302]

#
# Rewrite URLs that are not secure to HTTPS
#
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=302]

Open in new window


And so on.

Work on only one rewrite rule at a time and comment out all others.

When a rewrite rule does not work as expected, enable rewrite logging at level 4 and chase through the log to see what is going on.  This should be done only on a testbed system, because (a) the logs grow enormous very quickly on a system where actual user requests are coming in, and (b) it's impossible to tell which request you're looking at in the debug log unless there is only one request there.

#
# RewriteLogLevel: Controls verbosity of mod_rewrite log.  Normally 0.
#
RewriteLogLevel 4

#
# Enable mod_rewrite
#
RewriteEngine On

#
# Rewrite URLs missing a leading WWW, preserving HTTP/HTTPS
#
RewriteCond %{HTTP_HOST} !^www\. [NC]
... 

Open in new window


I can't emphasize these enough:

a.  Work on only one rule at a time.
b.  Disable all other rules you're not working on.
c.  Work on a testbed where you have control of incoming requests, not a live server.

Rewrite rules are hard enough to debug in clear context.  Don't make it any harder than necessary.
Rewrite your file as...

RewriteEngine On

RewriteBase /
RewriteCond %{HTTPS} off

RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$

RewriteCond %{HTTP_HOST} ^gastronegocios.com [NC]
RewriteRule (.*) https://www.gastronegocios.com/$1 [R=302,NC]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php?/$0 [PT]

Open in new window

Couple of things to keep in mind.

1) Very shortly all major browsers will start reporting all HTTP pages (non-HTTPS) as suspicious, so only run HTTP if this isn't a public site.

2) Use 302s as mentioned above, till everything's working.

3) Using RewriteLogLevel 4 suggests you're using Apache-2.2 rather than Apache-2.4 so you'll have to deal with.

a) No TLSv1.3 support

b) No HTTP2 support

c) Likely being hacked eventually, because Apache-2.2 is EOL (end of life), so no more security fixes.

Suggestion: Upgrade to Apache-2.4.37.1 as your Apache version so above items are fixed.
Hello guys, I was testing the rules and the one for the www works great, then the one for https works great too, but when I put the third rule it stops forcing www and https. The thing is that without that third rule the site pages won't load properly.

How can I make the third rule work without affecting the other previous two?
Provide a copy of your entire .htaccess showing your "third rule".
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.