Link to home
Start Free TrialLog in
Avatar of matt1237
matt1237Flag for United States of America

asked on

http and https apache rewrite to include www

This is what I am currently using and it appears to work for non-SSL pages.  The goal here was to ensure a prepended www to domain names (www.domain.com), but NOT to sub domain names (www.subdomain.domain.com).

RewriteEngine On
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^\w+\.\w+\.\w+ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}$1 [R=301,L]

I would like to do this exact same thing for https as well but don't know how???

PS: If you see a cleaner way to do the above feel free to advise.
Avatar of caterham_www
caterham_www
Flag of Germany image

You're using the rule-set in your httpd.conf? Put the same into your <virtualhost...> for port 443 but change http:// into https://

You may change

RewriteCond %{HTTP_HOST} !^$

into
RewriteCond %{HTTP_HOST} !=""

as well, which is the same but a literal comparison instead of a regular expression.
Avatar of matt1237

ASKER

I like the idea of using !="" since I'm guessing it would be faster not having to do regular expressions.  Was that your point?
More Explanation:
These two files are needed for each virtual host on my GoDaddy dedicated Fedora server.  I am using Plesk to make things a little easier since I have over a hundred domains.
  • httpd.include (includes default info for each domain and I cannot modify it since any changes elsewhere will cause it to overwritten)
  • vhost.conf (this file is where all changes are made to either overwrite things in httpd.include or whatever I want to do in addition.  What you see in the first post is what is already in this file)
Both port 80 and 443 are using the same directory and I don't believe I have to write out <VirtualHost insert-IP-address-here:443>...</VirtualHost>
anywhere in vhost.conf file... is there another way to do this?  I've already tried this and it worked for http but not https:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^\w+\.\w+\.\w+ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}$1 [R=301,L]
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^\w+\.\w+\.\w+ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}$1 [R=301,L]
ASKER CERTIFIED SOLUTION
Avatar of caterham_www
caterham_www
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You're a genious!  Thank you for the optimization and pointers.  I didn't know about vhost_ssl.conf before.  Once that was created, everything worked beautifully.  Essentially that file does the http/https conditioning for me so it's very easy to separate code for the two.
Here is the file code for vhost.conf:
RewriteEngine On
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^\w+\.\w+\.\w+ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}$1 [R=301,L]
<Directory /var/www/vhosts/domain.com/httpdocs>
php_admin_value open_basedir "/var/www/vhosts/domain.com/httpdocs:/tmp"
Options +FollowSymLinks
</Directory>
And final code for vhost_ssl.conf:
RewriteEngine On
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^\w+\.\w+\.\w+ [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}$1 [R=301,L]
<Directory /var/www/vhosts/domain.com/httpdocs>
php_admin_value open_basedir "/var/www/vhosts/domain.com/httpdocs:/tmp"
Options +FollowSymLinks
</Directory>  
I wrote this line myself to make sure no subdomains get "www" appended to them.  It seems to work, but is this an ok way to do it?
RewriteCond %{HTTP_HOST} !^\w+\.\w+\.\w+ [NC]
Yes, it should work in most cases. The RegEx \w does hot match a hyphen ('-')  (but '0-9a-z_'). A '-' is a valid character in a HTTP_HOST, too. But if you don't use such a character, that's not an issue, of course.
The condition will also match a.b.c.d.e.f (multiple levels). If that is not intended, you may use

^[^.]+\.[^.]\.[a-z]{2,4}\.?(:[0-9]{2,4})?$

[^.] = anything but not a period

The RegEx will take care of
foo.example.com
foo.example.com.
foo.example.com:80
foo.example.com.:80

which are all valid HTTP_HOSTs.