Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTACCESS RewriteCond without messing up localhost

I have the following bunch of domains:

  • myDomain.de
  • myDomain.com
  • myDomain.co.za
  • myDomain.org
  • myDomain.com
  • myDomain.com.na

What is the shortest way to write in the htaccess, to make ALL domains...

  1. Redirect to https://www.myDomain.com. I.e. Regardless of the domain that is entered, it will add www AND redirect to https, and
  2. Still work on my localmachine (so that if someone types in http://localhost/site/src that it won't redirect to the www sites?
like image 879
coderama Avatar asked Dec 01 '22 10:12

coderama


2 Answers

Let's see if this works:

RewriteEngine On

# Check if the host name contains a . (localhost won't)
# Check if the host name starts with www
# Check if the host name ends with .com
# Check if the connection is secure
RewriteCond %{HTTP_HOST}  \.
RewriteCond %{HTTP_HOST} !=svn.myDomain.com
RewriteCond %{HTTP_HOST} !^www   [OR]
RewriteCond  %{HTTP_HOST} !\.com$ [OR]
RewriteCond %{HTTPS}     !=on
RewriteRule ^.*$ https://www.myDomain.com/$0 [R=301,L]
like image 57
Tim Stone Avatar answered Dec 02 '22 23:12

Tim Stone


A foolproof solution:

# If not on www., redirect to www. on SSL
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteCond %{HTTP_HOST} !^www
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]

# If not on SSL(ish), redirect to SSL
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

Let's break it down.

If the requesting client is NOT on the reserved localhost IP address

RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}

Typically, when accessing a locally hosted website, the IP address of the client is 127.0.0.1. Every now and then, it's 127.0.1.0. But the entire 127.x.x.x range is reserved for local, so I'm checking against all of them, just in case you have a fun setup.

This is safer than checking for localhost or checking for the existence of a . -- it also allows you to edit your /etc/hosts file to point www.myDomain.com to your localhost for more realistic testing. Or, if you're like me, you have a domain nomenclature, like nathan.dev.mydomain.com or mydomain.com.dev.

Checking for "www."

RewriteCond %{HTTP_HOST} !^www\.

If the domain doesn't (! = doesn't) start with (^ = start with) www....

Port 443 vs HTTPS environment variable

RewriteCond %{SERVER_PORT} !^443$

Using port 443 is a safer check as the HTTPS environment variable cannot be guaranteed when working with load balanced servers.

The actual rule

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

This will force everything to use the "www." equivalent of that domain. E.g. mydomain.com becomes www.mydomain.com; mydomain.de becomes www.mydomain.de.

As an alternative, you can use the following rule which forces every domain to redirect to the www. as well as the .com:

RewriteRule ^(.*)$ https://www.myDomain.com/$1 [R=301,L]

Two condition/rule blocks, not one.

Using two blocks, you can have a little more clarity as to what exactly is going on. In addition, writing this as one block simply won't work if the requirement is to allow the use of any TLD. You could combine them into one block, if you used the alternate rule above. The one-block alternate would look like this (notice the addition of [OR]):

RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteCond %{HTTP_HOST} !^www [OR]
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(.*)$ https://www.myDomain.com/$1 [R=301,L]

It's also worth noting that the two-block solution sometimes results in two redirects, but if you leave it in the exact order, you'll reduce redirects.

Example: With the current order of rules, if a client requested http://mydomain.com, the first block would apply (no www. exists) and will redirect to https://www.mydomain.com. However, if you flipped the order, then the server would first detect the lack of SSL and the client would be redirected to https://mydomain.com, then the server would detect the lack of www. and serve an additional redirect to https://www.mydomain.com. tl;dr: Don't change the order. :)

Happy hacking!

like image 30
Nathan J.B. Avatar answered Dec 03 '22 00:12

Nathan J.B.