Best htaccess method to force site-wide https

Is one way better than another for forcing site-wide https with the htaccess file? Here are a few methods suggested on different websites:

RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [L,R=301]

Does it make any difference which RewriteCond I use? It looks to me like all three RewriteConds are saying the same thing. Are they essentially interchangeable in achieving my purpose?

Also, the last two RewriteRules differ from the first. I'm assuming the syntax on the first ( ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} ) is correct for my purpose. Is this true?

Thanks!

Regards,
Jonathan
Jonathan GreenbergAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

nociSoftware EngineerCommented:
SERVER_NAME & HTTP_HOST might not be the same on shared hosting (or hosting of multiple domains...)
HTTP_HOST is preferred.

The RewriteCond is essential all the same as port 80 isbound to HTTP ...
the first does  an anchored  search to a whole string ^ = begin, $ is end .* = 0 or more any character.

without ^ & $  just an unanchored searched.

and the last is ^ (begin)   and optional /?   followed by some characters...  
.?    match one optional character  would match also (arguably  faster... as * does try to match as mutch as possible, walking the whole string.

Only the last one atualy uses the match results  ($1 in redirect URL).

I don't use apache myself,  you might miss the query string on the first 2 rules.....  so except for the SERVER_NAME the 3rd would be preferred i think.
0
Jonathan GreenbergAuthor Commented:
Thak you, noci, for the time you took to answer, but I'm afraid most of what you wrote is incomprehensible to me. My knowledge is limited, and I'm having a problem with your wording and punctuation.

You wrote "The RewriteCond is essential all the same as port 80 isbound to HTTP ...". I don't know what this means. I'm aware that port 80 is for http traffic, while port 443 is for https traffic. The first of the three rules deals specifically with port 80 traffic. Are you making a point that pertains to this fact?

Thanks,
Jonathan
0
nociSoftware EngineerCommented:
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTPS} off
are equivalent   as is checking "off" or "!= on"  are equivalent  in a true/false sense.....
They are 3 different ways to express the same.  The Best test (as it expresses what you want most direct way  is)
For rewriteRule {MATCH} {REPLACE} {OPTIONS} ..... the best match is in the last rule
^/?(.*)      will match a / only or any other string as well.... but NOT introduce an extra / on the replacement.
The last rule won't work with shared hosting or hosting on a server with multiple domains... so that needs fixing:
The first 2 rules forget about an optional query string... so they may miss some URL's
So the best set (IMHO) would be:

RewriteCond %{HTTPS} off
RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [L,R=301]
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
IT Pros Agree: AI and Machine Learning Key

We’d all like to think our company’s data is well protected, but when you ask IT professionals they admit the data probably is not as safe as it could be.

Olaf DoschkeSoftware DeveloperCommented:
I just have this and it works fine for me:

RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Open in new window


Bye, Olaf.
0
nociSoftware EngineerCommented:
Hi Olaf,
that means you will never get the part in an URL after ?xxxxxxxxx
so an URL like:    http://example.com/index.php?query_string

Will match & discard the query string.... no problem if Query string isn't used,  but otherwise there are missing parts.
and return this:    http://example.com/index.php
1
Dave BaldwinFixer of ProblemsCommented:
I am using this on 4 different sites.  All of them provide both HTTP_HOST and SERVER_NAME variables.  No problems with query strings.
RewriteEngine On 
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

Open in new window

1
Olaf DoschkeSoftware DeveloperCommented:
I have more rules when %{HTTPS} is on bringing back %{QUERY_STRING}, so this is kept with 301 redirects.

But good point, if you want all in one your rule would take anything of the rest of the URI after the first dash as $1, you might also add %{QUERY_STRING} to my rule to get that part and perhaps even wrap it in ?query=%{QUERY_STRING} for your routing to take it in as $_GET['query'] (or similar), as in

RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}?query=%{QUERY_STRING} [R=301,L]

Open in new window


It just renders all requests for normal files (images etc.) quite useless, therefore I'd relay this to further rules.

Bye, Olaf.
0
Julian HansenCommented:
Just add QSA to your Flags to ensure the Query String is retained
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L]

Open in new window

1
Olaf DoschkeSoftware DeveloperCommented:
Quote from https://httpd.apache.org/docs/2.4/rewrite/flags.html

When the replacement URI contains a query string, the default behavior of RewriteRule is to discard the existing query string, and replace it with the newly generated one.
Which means you only need this QSA flag, when you want to merge query strings.

By the way, the rewrite rule I used was given in my hosters FAQ. Your mileage can vary, as there are options in the servers main configuration that can make the one or other solution preferable. For example about the usage of %{HTTP_HOST} vs. %{SERVER_NAME} see https://stackoverflow.com/questions/2297403/what-is-the-difference-between-http-host-and-server-name-in-php

(The whole discussion is worth reading, not just the best answer. You'll see depending on apache version and configuration one or the other can be better.)

One more tip: Test your rewrite rules by making raw http requests with a tool like cURL and see how your server reacts, preferably with rules applied to a subdomain like test.yourdomain.com and/or on localhost, first.

Bye, Olaf.
0
Jonathan GreenbergAuthor Commented:
Thanks to all, and apologies to the three participants without awarded points. I tried to award points to all by using what EE seems to be calling the "Classic View," but the "Assisted Solution" buttons cannot be selected - at least I cannot select them in Firefox on my Mac.
0
Jonathan GreenbergAuthor Commented:
Yes, thank you, Julian. But it looked to me like there was a problem with the interface. I'm in Firefox on a Mac (although I doubt it was a browser- or platform-dependent issue), and I was not able to assign points by clicking the Assisted Solution button. The buttons APPEARED functional, in that mouseovers had a visual affect, yet they produced no result.

So, yes, I WOULD like to spread the points a bit, but I'm not sure I'll be able even if you reopen the question.
0
Olaf DoschkeSoftware DeveloperCommented:
Maybe the new system works better with Firefox. As far as I followed other threads about the new system you mark all answers you want to be assists as helpful before picking the main answer.

Bye, Olaf.
0
nociSoftware EngineerCommented:
I found that assists could only be selected if the mail solution has been selected. Quite a bummer is they are on opposite ends of a long list and one first has to scroll the whole list and then again the other way.
0
Jonathan GreenbergAuthor Commented:
Julian, it worked this time. I think the reason for this is that, as someone just pointed out (sorry, I'm in a popup that's hiding the page, and I can't see who it was), there's a need to select the Assisted Solutions before the Best Solution, and I initially tried this in reverse order.

Thanks again to all who participated!
0
Jonathan GreenbergAuthor Commented:
One last thing to all who are interested. I've been using one or the other of these two configurations, and both seem to handle redirection, including query strings, without issue.

RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
1
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.