Please review my .htaccess file

Hi Guys!

I just wanted to check that everything is written correctly in my .htaccess file. It all works as expected, but just wanted to check that I won’t cause any unforseen problems.

Here it is:

RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} ^/(checkout|login|myaccount)\\.php
RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(checkout|login|myaccount)\\.php
RewriteCond %{REQUEST_FILENAME} !\\.(gif|png|jpg|jpeg|css|js)$ [NC]
RewriteRule .? http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTP_HOST} !^$
RewriteRule ^(.*)$$1 [L,R=301]

Thanks in advance.

Awww, so close! Everything is nice, but the last line isn’t.

Odd, because the other RewriteRules are fine (and are based on the exact same principle).

change the last RewriteRule to

RewriteRule .?{REQUEST_URI} [L,R=301]

and you’re golden! :slight_smile:

Why, you ask? Because (.*) is the most nasty regex there is and should be avoided at all costs, plus the replacement solution I provided is faster because it doesn’t have to “eat” up everything; it’ll just fire no matter what, without even caring about the input URL :slight_smile:

Perfect!!! Thank you so much for the advice I appreciate it. I’ve added it to my site and works lovely!

Thanks again.


I must disagree with Rémon as for the code you’ve used (he IS correct in using %{REQUEST_URI} with .? but that’s technique). Let me just comment on the code.

RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} ^[COLOR="Red"]/[/COLOR](checkout|login|myaccount)\\.php
# ^/ is Apache 1.x specific and will not work on Apache 2.x
# See elad's ISAPI doesn't redirect thread for more of an explanation
RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^[COLOR="Red"]/[/COLOR](checkout|login|myaccount)\\.php
# Ditto
RewriteCond %{REQUEST_FILENAME} !\\.(gif|png|jpg|jpeg|css|js)$ [NC]
RewriteRule .? http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTP_HOST} !^www\\.mydomain\\.com$
# minor but if you want to ensure those .'s are dot characters, RewriteRule ^(.*)$$1 [L,R=301]
# same .? => %{REQUEST_URI} recommended



Are you sure about that? :wink:

Hi DK,

Thanks for your comments. However, I am running Apache 2 and it seems to redirect fine.

I’m not aware that the Apache Foundation has fixed that incompatibility between versions. If they have, kudos to them as it was a major PITA to have mod_rewrite fall over when moving to an Apache 2.x server.

Okay, a quick test on my test server (Apache 2.2.16 on WinDoze 7 Pro) showed that it did not match the leading /. Please identify the Apache version (and OS) if you find that it does match the leading /.



It has always matched the leading / in %{REQUEST_URI}, otherwise you wouldn’t be able to do

RewriteRule .?[b]%{REQUEST_URI}[/b] [L,R=301]

(note the absence of a slash between [noparse][/noparse] and %{REQUEST_URI}. %{REQUEST_URI} must be starting with a / then :wink:


The Apache Foundation has improved mod_rewrite to understand that it must add the / after the {HTTP_HOST} variable.

IMHO, until it’s shown that Apache 2.x.y has made the leading / optional, it’s still best to use:

Apache 1.x: ^/{regex}
Apache 2.x: ^{regex without leading /}
Apache 1.x OR 2.x: ^/?{regex}

Again, if anyone can verify that a different version of Apache (greater than 2.2.16) allows a required leading / in the DocumentRoot, PLEASE let me know which version of Apache (and OS) you’re using.




If we were talking RewriteRule you would be completely correct. However, we are talking about matching %{REQUEST_URI} in a RewriteCond.
In that case there is a leading slash, in both Apache 1.x as well as 2.x

If you don’t believe me, try this

RewriteEngine On
RewriteCond %{REQUEST_URI} !test
RewriteRule .? /test?q=%{REQUEST_URI} [R=301]

and browse to /blah; you’ll be redirected to /test?q=/blah

I did not type that / and it’s not in the RewriteRule, so it must be in the %{REQUEST_URI}.
If it’s in the {REQUEST_URI}, I must put it in my test when I check against it in a RewriteCond.

If that does not convince you, the manual says (here):

It says the same in manual for 1.3, see Apache module mod_rewrite

I tested this on Apache 2 on Win7 Ultimate (WampServer 2)

What? Where did you get that info?

When I put the following in my .htaccess (yes, I know it’ll loop)

RewriteRule .? http://%{HTTP_HOST} [R=301]

and use HTTP Live Headers in FireFox to look at the raw HTTP Headers, it says


GET / HTTP/1.1
Host: sp
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.7,nl;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive

HTTP/1.1 301 Moved Permanently
Date: Sat, 20 Aug 2011 00:46:55 GMT
Server: Apache/2.2.17 (Win32) PHP/5.3.5
[B][COLOR="Red"]Location: http://sp[/COLOR][/B]
Content-Length: 217
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1

Note that Apache did ~not~ add a / at the end of %{HTTP_HOST}, it’s just [noparse]http://sp[/noparse] without a tailing slash …