Dynamic domain redirection to HTTPS and non-www - apache

I have two domains at the moment: example.pl and example.com.
I'm trying to make sure they all go to https://example.pl or http://example.com respectively but I have a problem (or my browser also remembers old state).
I have this code at the moment:
RewriteCond %{ENV:HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^example.pl [NC]
RewriteRule ^ https://example.pl%{REQUEST_URI} [L,NE,R=301]
RewriteCond %{ENV:HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,NE,R=301]
But I'm not sure if it's working correctly (http://example.com redirects somehow to https://example.pl) and also whether this can be done in one block of code?

RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^example.com [NC]
Both these conditions cannot be successful, so the rule will ultimately fail (do nothing) if requesting the www subdomain over HTTPS.
If it's just two domains then you need to modify the 3rd condition to allow an optional www subdomain and use regex alternation to match the two domains.
For example:
RewriteCond %{ENV:HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com|example\.pl) [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
The %1 backreference matches the captured subpattern in the last matched RewriteCond directive, ie. either example.com or example.pl. The important point is that the 3rd condition is always successful, since the only purpose of this 3rd condition is to capture the domain name.
You will need to clear your browser cache since any (erroneous) 301 (permanent) redirects will have been cached by the browser.
But I'm not sure if it's working correctly (http://example.com redirects somehow to https://example.pl) and also whether this can be done in one block of code?
That's not possible with the rules you've posted. It's possible you are seeing a cached redirect from an earlier (erroneous) 301 permanent redirect.
See my earlier answer for an any domain solution.

Related

htaccess turn on https and www BUT only when live, not locally

I would like to have .htaccess code that adds https and www to my URLs – but only when my site is live, not when I am developing locally on my computer.
I have the following
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L,NE]
But this doesn't appear to be adding the www when my site is live. So for example https://example.com doesn't have the www and all the links are broken. For example https://example.com/about just gets a 404 Not Found error message.
Thanks for any help. I don't understand .htaccess files/code.
EDIT / UPDATE
Comparing the code to other code, should it be the following?
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
Comparing the code to other code, should it be the following?
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC,OR]
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L,NE]
Yes.
Your original rule explicitly removed the www subdomain. If you had requested http://www.example.com/ (note HTTP), you would have been redirected to https://example.com/ (HTTPS + non-www). But nothing would happen if requesting https://www.example.com/ - the canonical URL (the rule is skipped because the 2nd and 3rd conditions fail).
The %1 backreference contains the match from the first capturing group in the preceding CondPattern. eg. Given the CondPattern ^(?:www\.)?(.+)$ then %1 contains whatever is matched by (.+) (the first capturing group), ie. the hostname, less the optional www. prefix.
There is no difference between testing %{HTTPS} off or %{HTTPS} !on - the result is the same.
Test first with 302 (temporary) redirects to avoid potential caching issues. You will need to clear your browser cache before testing since the erroneous redirect will have been cached by the browser.
RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
Checking for a port number would seem to be unnecessary here. This will fail if you are using localhost on the standard port (80 or 443) since the port number will be omitted from the Host header. Something like !^localhost would suffice, or perhaps !^localhost($|:) if you happen to using a domain name that starts localhost!

.htaccess redirect all tld's to another and force https

Hello i try to redirect all my top level domains to another one and this is already working but i also want to force https. With the following code it is working fine for all top level domains such as '.de', '.net' and so on.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\.)?domain\.com$ [NC]
RewriteRule ^(.*) https://domain.com/$1 [R=301,NE,L]
My problem is i also want to force https for my main tld => '.com'
Well, and here we are:
RewriteEngine On
RewriteCond (http://) !^(www\.)?domain\.com$ [NC]
RewriteRule ^(.*) https://domain.com/$1 [R=301,NE,L]
For my bad, this is not working. I get an 'Too many redirects' error. My question is now is it the code/redirection or is there something else wrong maybe with the server configuration of my provider? I noticed the 'Too many redirects' error in any way i tried till now for redirect from 'http://' to 'https://' and i tried so many different ways... .
Try:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^(www\.)?domain\.com$ [NC]
RewriteRule ^(.*) https://domain.com/$1 [R=301,NE,L]
Adds an "or" condition so that it redirects if there's no HTTPS OR if the domain is different.
The (http://) isn't a variable, it's a literal "http://", which will obviously never match ^(www\.)?domain\.com$, which is why that condition is always true.
Since you're using cloudflare, which internally routes requests (that are not HTTPS), you can't use the %{HTTPS} variable, you need to look at the forwarding protocol:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https [OR]
RewriteCond %{HTTP_HOST} !^(www\.)?domain\.com$ [NC]
RewriteRule ^(.*) https://domain.com/$1 [R=301,NE,L]

Can't get htaccess rule to work: force SSL on all pages, force non-SSL on two specific pages

I am no htaccess expert, but after Googling for two hours I gave up. Maybe you can help me?
I have my entire site on SSL. However, I have two pages that reference non-secure dynamic content from elsewhere. I need these to be on http instead of https.
The first part of my rules work. All the site is forced to SSL except for those two pages. However, the last part doesn't: force those two pages to non-SSL. It is probably very stupid but does anyone see where I go wrong?
#add www. if missing WORKS
RewriteEngine on
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [L,R=301]
#force SSL/https WORKS
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/webshop2/localize\.php
RewriteCond %{REQUEST_URI} !^/webshop2/layoutstripper\.php
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#force http DOES NOT WORK
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} ^/webshop2/localize\.php [NC]
RewriteCond %{REQUEST_URI} ^/webshop2/layoutstripper\.php [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
You need an [OR] flag in your second SSL rule. The 2 conditions you have essentially say:
the request must be HTTPS
the URI must start with: /webshop2/localize.php
the URI must start with: /webshop2/layoutstripper.php
As you can see, the last 2 conditions will always fail, as the request can't be BOTH at the same time. If you add an [OR] flag in there, it makes it true if the URI is one or the other:
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} ^/webshop2/localize\.php [NC,OR]
RewriteCond %{REQUEST_URI} ^/webshop2/layoutstripper\.php [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

htaccess to strip www and force SSL

I have what I believe to be a rather well crafted .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L,NE]
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
This says to me "strip the www. off the url and force https." And it works fine except for those people who happen to type in https://www.somedomain.com/. Those people are presented with a warning that there is a problem with the site certificate. It seems that the www is not getting stripped in this particular case.
You can actually combine both rules into one:
RewriteCond %{HTTP_HOST} ^www\. [NC,OR]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L,NE]
Then make sure to clear your browser cache to test this.
However just remember that certificate negotiation between web server and browser happens before mod_rewrite is invoked.

htaccess http to https with www. Without redirecting sub domain

I have a RewriteRule that redirects my main domain to https://www.sta-games.com which works fine, but when I try to access my subdomain http://files.sta-games.com, it redirects to my main domain.
Heres my redirect rules
#HTTPS Redirection
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Can anyone see the problem?
You need to adjust your rules so that it looks for the whole domain instead of just part of it. Right now you are only looking for the absence of www. So that is why your subdomain redirects.
First you need to combine your rules because it seems you want to redirect if https is not on and there is no www, so make that one rule. Then use your actual domain name in the rule. Replace example.com with your domain. This should fix your issue.
#HTTPS Redirection
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com
RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [L,R=301]
Have an additional skip condition for all domains except the main domain:
RewriteCond %{HTTP_HOST} ^(www\.)?sta-games\.com$ [NC]
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.sta-games.com%{REQUEST_URI} [L,R=301,NE]
Test this after clearing your browser cache.