Forum Moderators: phranque

Message Too Old, No Replies

Can't get a redirect for non-www

www works, but not non-www

         

Terabytes

6:29 pm on Mar 19, 2019 (gmt 0)

10+ Year Member



Probably the first time I've asked about this since I joined...

I recently changed over to https, (like today!) Everything works fine, except the redirect from the non-www to the https-www...

I'm not really sure what the first set instructions are for, however the ssl doesn't work without it
(placed by the hosting)

What am I doing wrong here?
Looking for any http to 301 to https with the www!


RewriteEngine on
RewriteBase /

RewriteEngine On
RewriteCond %{HTTPS} =off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301]

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


It seems to want to modify my code...
the last line would be to https www example com

Thanks so much for everyone's time and effort!


[edited by: not2easy at 8:09 pm (utc) on Mar 19, 2019]
[edit reason] for readability - please use "example.com" [/edit]

phranque

8:33 pm on Mar 19, 2019 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



the first ruleset does not specify the canonical hostname in the substitution string.
the second ruleset will never fire due to the default/implied [AND].

you should essentially combine those rulesets into one:
RewriteEngine On

RewriteCond %{HTTPS} =off [OR]
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$ [NC]
RewriteRule (.*) https://www.example.com/$1 [R=301,L]

not2easy

8:43 pm on Mar 19, 2019 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I fixed that linking problem you had, using (quote) instead of (code) was one cause, not using example.com contributed to it.

This line:
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301]
is leaving off the www. part - if that code was added by the host, maybe they did not understand what you wanted it to do. Changing it to:
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
should add it.

The next 3 lines sort of repeat and repair the first lines.

The part about "RewriteEngine on" only needs to be there once - if at all.

These lines should come after the index\.(html|php) rewrite and after other rules you may have in your htaccess file.

lucy24

9:04 pm on Mar 19, 2019 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



A domain-name-canonicalization redirect is the last place you want to use %{HTTP_HOST}, since the whole point is to get everyone to the same host, no matter what bizarre version of the name (possibly even including port number) was requested.

Although HTTPS is supposed an absolute toggle--it's either on or off, with no ifs, ands, buts or maybes--it doesn't hurt to express the condition as !on to cover all possibilities.

The domain-name condition is expressed as a negative so it is interpreted as “absolutely anything other than this one and only exact name which is the only name I will accept”.

Although it’s customary to make the hostname optional (“either exactly this or exactly nothing”) it isn’t strictly necessary, since a request with no hostname will never get past the VirtualHost envelope. Which I have to assume you’ve got, unless your site dates back to 1993* and you’re still getting visitors using your numerical IP address.


* My fingers attempted to type 1883.

whitespace

9:56 pm on Mar 19, 2019 (gmt 0)

10+ Year Member Top Contributors Of The Month



A domain-name-canonicalization redirect is the last place you want to use %{HTTP_HOST}


That depends if you have any plans to implement HSTS [en.wikipedia.org] and submit to the HSTS preload list [hstspreload.org] - in which case it becomes a requirement to first redirect from HTTP to HTTPS on the same host before canonicalising the domain name (with a possible second redirect).

(Although I'd argue that if you are using .htaccess for this redirect then HSTS may not be the way to go.)

whitespace

10:26 pm on Mar 19, 2019 (gmt 0)

10+ Year Member Top Contributors Of The Month



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


Bit of an aside, but you should (always) use the "L" flag with external redirects. Without the L flag, processing continues... if it was caught by the second redirect (although with the original code that wouldn't have happened, because of the conflicting conditions as phranque pointed out) then you'd get a malformed redirect for the form:


https://www.example.com/https://example.com/foo

Terabytes

2:30 am on Mar 20, 2019 (gmt 0)

10+ Year Member



Thanks for the help everyone!
A special thanks to phranque for the code snippet! (you totally nailed it)

I can't follow everything, nor get my head completely around this aspect of rewrites, but I keep reading and perhaps it will click eventually..

Thanks for everyone's time!
Tera

phranque

5:09 am on Mar 20, 2019 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



A special thanks to phranque for the code snippet! (you totally nailed it)

I can't follow everything, nor get my head completely around this aspect of rewrites, but I keep reading and perhaps it will click eventually..

the code snippet i provided does the following:
- if the requested protocol is a non-secure protocol
- or if the requested hostname is not exactly the canonical hostname (or nothing)*
- redirect the requested path to the canonical protocol and hostname with a 301 status code

* the "or nothing" covers the rare case of certain HTTP 1.0 requests when you're not on shared hosting