How to use [OR] or substitute in an .htaccess file?
Summary The [OR]
flag isn't working consistently across different servers. Details and question below.
I have a website hosted on Godaddy and I wrote this code for an .htaccess
file to redirect users to the https
version of my site. It works great.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www\.firstsite\.com%{REQUEST_URI} [R=301,L]
</IfModule>
I used the same .htaccess
file for a different site hosted on Network Solutions and it crashed the site. It produced this error.
This page isn’t working
www.secondsite.com redirected you too many times.
ERR_TOO_MANY_REDIRECTS
I removed the [OR]
flag for the network solutions site and the site loaded without the error. This is the updated code.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www\.secondsite\.com%{REQUEST_URI} [R=301,L]
</IfModule>
Unfortunately without the [OR]
it doesn't redirect based on the first condition, RewriteCond %{HTTPS} off
. However it still redirects based on the second condition RewriteCond %{HTTP_HOST} !^www\. [NC]
I'm not sure how to fix this. I need the [OR]
but I can't use it. Is there a way to use [OR]
differently or is there a substitute for situations like this? Thanks so much!
The
[OR]
flag isn't working consistently across different servers.
This is (almost) impossible. The OR
flag is a fundamental construct/operator in mod_rewrite. If this construct is not working properly then you have a serious problem with your server, requiring reinstallation or finding a new host. This scenario is just so improbable.
However, what is far more likely is that one of the operands in the OR'd expression is not as you expect. ie. In this instance, either one of the server variables HTTPS
or HTTP_HOST
is not set as you expect it to be. And out of the two, it is more likely that the HTTPS
server variable is not being set (or not set as you expect) - as I mentioned in my comment. This is quite "normal" and depends on your server config and how the SSL cert is managed. eg. If your SSL cert is managed by a front-end proxy (like CloudFlare) then the HTTPS
server variable probably is not set. This would seem to be consistent with the results you are seeing.
Debugging
The following tips are just to help with initial debugging in order to find an eventual solution.
NB: Whilst testing, it is preferable to use temporary (302) redirects, which are not cached by the browser. 301 (permanent) redirects are cached hard by the browser, so you must ensure the cache is disabled, which makes testing problematic. Please ensure the cache is cleared before continuing.
-
Try (temporarily) changing this to an HTTP to HTTPS (only) redirect, ie. remove the www canonicalisation. Do you still get a redirect loop? For example:
RewriteCond %{HTTPS} off RewriteRule ^ https://www.example.com%{REQUEST_URI} [R,L]
(Aside: No need to escape dots in the
RewriteRule
substitution - this is an ordinary string, not a regex.) -
If the above triggers a redirect loop then check what the server variable
HTTPS
contains. ie. Remove the above HTTP to HTTPS redirect and add the following instead:RewriteRule ^foo$ /?HTTPS=%{HTTPS} [R,L]
And access the URL
https://example.com/foo
directly. You should be redirected tohttps://example.com/?HTTPS=<value>
. What is the<value>
? (The<value>
might be empty.) -
Check the HTTP request headers your application is seeing. If you are using PHP then check the
$_SERVER
and$_ENV
superglobal arrays and specifically check for the indicesHTTPS
,SERVER_PORT
,SCRIPT_URI
andHTTP_X_FORWARDED_PROTO
(which corresponds to theX-Forwarded-Proto
header - if set at all). However, there could well be others, specific to your server. For example, some hosts set an environment variable calledHTTPS
(as opposed to a server variable of the same name). Add what you find to your question.If you see an
X-Forwarded-Proto
request header then you are behind a front-end proxy, like this question on StackOverflow.
See also this question on Pro Webmasters for a similar "discussion" and eventual solution.
UPDATE: ... a site hosted on Network Solutions...
I've just done a bit of digging regarding "Network Solutions" (NS) and it seems this may not be possible!? This I find utterly staggering if true, however, I would think it must still depend on how and what type of SSL cert is installed?
(Still check the HTTP request headers and server/script variables as mentioned above.)
However, the Network Solutions support document on SSL Redirects states:
Network Solutions® uses a proxy SSL this does not allow the use of server-side variables to detect HTTPS (secure). All server-side coding will always detect HTTP (non-secure), and for programs that attempt to redirect non-secure connections (
http://
) to a secure connection (https://
) will result in an infinite loop and server error after 30 seconds.You can use a client-side program (like javascript) to detect if it's secure and redirect if it's not. You can use the below coding to create a redirect. Just modify the code so that it redirects to the correct secure domain and add it into the HTML of any sensitive pages you may have.
<script language="javascript"> if (document.location.protocol != "https:") { document.location.href = "https://subdomain.yourdomain.com" + document.location.pathname; }; </script>
The "proxy SSL" should identify itself, or at least identify the HTTPS state in the "proxied" request to the application server. However, this implies it does not.
See also the following related question on StackOverflow. However, the "other" solutions presented there don't seem viable IMO. The eventual conclusion would seem to be a reference to the above support doc (and JavaScript solution) from NS.
https://stackoverflow.com/questions/4686668/https-redirect-for-network-solutions