First of all, three redirects are hardly too many redirects – the browser limit is 20. If you're hitting that limit something else is amiss.
Second, if you enable BOTH the HSTS AND the non-www to www redirection the generated code actually reads:
##### Redirect non-www to www -- BEGIN
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}>s ^(on>(s)|.*>s)$
RewriteRule ^(.*)$ http%2://www.%{HTTP_HOST}/$1 [R,L]
##### Redirect non-www to www -- END
That is to say, we DO take into account the fact that your site is using HTTPS and HSTS – as long as Apache is aware of the fact that HTTPS is being used. We'll circle back to that later. First, let's see what this rule set means.
The first line means "this block up to the RewriteRule applies only when the hostname does not start with www.".
The second line means "the following regular expression will return 's' as the second catch group if Apache reports that HTTPS is enabled, an empty string otherwise". This is the first bit that takes care of HTTP vs HTTPS
if and only if Apache knows about it. Hold that in your mind.
The third line means that the redirection will be http://www.YOUR_HOSTNAME/whatever if and only if the second rule didn't return an 's' (Apache believes we are in plain HTTP mode). However, it will be
https://www.YOUR_HOSTNAME/whatever if the second rule returned 's', i.e. your Apache believes that we are under HTTPS.
So the line you claimed you changed does not, in fact, exist. You did not understand how the rule works. You thought you understood but you failed to take into account what that "%2" stood for in the third line.
The problem is not the rule I wrote but the fact that
even though you are visiting https://siteurl.com Apache believes it is NOT running under HTTPS. This means that you are using a different SSL terminator in front of Apache, e.g. NginX as a reverse proxy.
I am explaining this twice every week. We can NOT cater for this use case because Apache itself does know your site is being accessed over HTTPS. There are plenty of wrong solutions, though!
One wrong solution is to force the redirection to always be with an https:// prefix. That's what you did. It's wrong because the non-www to www redirection must not cross the TLS boundary. There are valid use cases for serving content over plain HTTP to non-browser clients who might not understand HTTPS. Probably you don't care about these use cases.
Another wrong solution is to look at the protocol being used. If it's https stick with it. However the problem with this is that a misconfigured server might respond with plain HTTP to an https:// protocol request. Keeping the protocol in this case could lead to secure cookies being leaked over plain HTTP.
The third and ultimately worse solution is let the user decide which of these two bad solutions they want to shoot their feet with. Not only the problems become opaque to the user, we are now shifting the blame to the user for making a choice in an inscrutable option.
As far as I can tell there is no correct way to handle it. Which one of the bad ways to handle it may be more relevant to you is a matter of knowing your use case and understanding the repercussions of the choice of a bad solution to a problematic server implementation. The correct way to handle it would be Apache knowing when the site is running under TLS even if there's a TLS terminator in front of Apache. Or just live with the three redirections for the very first time someone visits your site if and only if they use the non-www domain. Every future access to the site from a browser will not suffer a triple redirect. The browser will automatically upgrade the protocol to HTTPS (thanks to HSTS) and most likely remember the non-www to www redirection. Therefore you'll have typically zero and at most one redirection. That's what I am doing for our own site and it causes no problem (our site
does have NginX in front of Apache for accelerating static file delivery).
Nicholas K. Dionysopoulos
Lead Developer and Director
🇬🇷Greek: native 🇬🇧English: excellent 🇫🇷French: basic • 🕐 My time zone is Europe / Athens
Please keep in mind my timezone and cultural differences when reading my replies. Thank you!