Avoid multiple redirects in contao - .htaccess

I have analyzed my website with the portal web.dev from Google. This told me that I have too many redirects if I call the URL without www and with http:
It goes first to https and without www, then to http with www and only then to https and www.
This is my htacces file:
<IfModule mod_headers.c>
# Allow access from all domains for webfonts (see contao/core-bundle#528)
<FilesMatch "\.(ttf|ttc|otf|eot|woff2?|font\.css)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
<files serviceaccount.json>
Order allow,deny
Deny from all
</files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^ %{ENV:BASE}/app.php [L]
</IfModule>
I don't see at all where these redirects are implemented. I also found this variant to redirect directly. Even if I put them in the htaccess file, the redirects remain as described above.
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteRule (.*) https://www.%1/$1 [R=301,L]
</IfModule>
Can you tell me how all these redirects come about and why the last code snippet doesn't work?

Some of those redirects might be done by your Hoster. Also, in newer Contao versions, Contao automatically redirects to https in the front end, if HTTPS is enabled in the respective website root's settings in the back end.
In any case, you should implement the redirects yourself, e.g. in your web/.htaccess. For example:
# Redirect to www subdomain
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Note: the www redirect would redirect any domain that does not start with www. to www.. If you have a multidomain setup with different subdomains, you will need to adjust the www. redirect accordingly.

Related

htaccess - redirect http to https but only for certain domains

I have two domains pointing to the same place but I only want one of these to redirect all http requests to https.
http://www.thisisme.com should stay as it is
http://thisisme.mydomain.com needs to redirect to https://thisisme.mydomain.com
As an extra rule I need to make sure that http://thisisme.mydomain.com/health_check.php does not redirect.
Here's what I have so far.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# Don't redirect /heath_check.php to https
RewriteCond %{REQUEST_URI} !(health_check\.php)$
#This line needs looking at! Should only redirect any xxx.mydomain.com requests to https
RewriteCond %{HTTP_HOST} mydomain\.com
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# block hidden directories
RewriteRule "(^|/)\." - [F]
# This makes the url look pretty for codeigniter...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
</IfModule>
EDIT!
I actually need to do the opposite if the requested domain is not mydomain.com - it needs to redirect to http is https is requested
To exclude www.thisisme.com ,put the following condition right bellow RewriteEngine on line or above the http=>https rule :
RewriteCond %{HTTP_HOST} !^(www\.)?thisisme\.com$ [NC]

https and www not working properly

As I tried so many things to redirect www to non-www of subdomain via htaccess but not going well
I want to like this
https://test.example.com
but while I write like this
https://www.test.example.com
then the webpage gives me error like this
"Your connection is not private"
i tried this code in htaccess but not working properly
RewriteCond %{HTTP_HOST} ^www\.([^.]+\.example\.com)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
this code only redirects if i didnot mention https in www.test.example.com
To redirect everything to htpps I use the following. It is at the top of the .htaccess.
I have added your two lines for redirecting from www to the domain after the forwarding to https, and changed the HOST_HTTP to HOST_HTTPS.
Please note I haven't tried it.
Perhaps you can remove this if it doesn't apply: RewriteRule ^index\.php$ - [L]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://test.example.com/$1 [R,L]
RewriteCond %{HTTPS_HOST} ^www\.([^.]+\.example\.com)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
RewriteRule ^index\.php$ - [L]
</IfModule>

htaccess file not redirecting a certain url

I added an SSL to my site and have the following htaccess file in place to redirect:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} =off [OR]
RewriteCond %{HTTP_HOST} !^example\.com$
RewriteRule ^(.*)$ "https://example.com/$1" [R=301,L]
</IfModule>
This covers almost everything, so http://www.example.com, http://example.com, and example.com all forward to https://example.com. However, there is one scenario where it does not. If I enter https://www.example.com, it does not redirect to https://example.com and I get a security certificate error. Looking for a solution. Thank you in advance.
cdr6545
Try this
<IfModule mod_rewrite.c>
RewriteEngine On
Options +FollowSymlinks
# To redirect from www to non www (Rewrite www.example.com → example.com)
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.*) http%{ENV:protossl}://%1/$1 [R=301,NE,L]
# Redirect HTTP to HTTPS automatically (only if not in localhost)
RewriteCond %{HTTP_HOST} !=localhost
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

.htaccess problems with https redirect

I have just upgraded my website from HTTP to HTTPS and my .htaccess, which worked perfectly before, is now behaving strangely. I have the following in there:
Remove trailing slash
Remove php extension
...plus others, but I guess these are the problematic ones.
The behaviors I'm getting, on an example page, are:
http://www.navanter.com/e-tips - no problem
https://www.navanter.com/e-tips.php - no problem
http://www.navanter.com/e-tips.php - seems to double the URL in the address bar
Am I missing something obvious? Code is:
Order Deny,Allow
DirectoryIndex index.php
# Secure text files
<Files ~ "\.txt$">
Order allow,deny
Deny from all
</Files>
# Redirect non-www to www:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
ErrorDocument 404 /404.php
RewriteEngine On
# All calls go to SSL
RewriteEngine On
RewriteCond %{ENV:HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ https://www.navanter.com/$1 [R=301,L]
# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ https://www.navanter.com/$1 [R=301,L]
# Resolve .php file for extensionless php urls
RewriteRule ^([^/.]+)$ $1.php [L]
For this specific problem, your rewrite rules for removing the trailing / and the .php extension shouldn't need the full URL in the substitution. You might also consider reordering some of those rules.
Updated Example:
Require all granted
DirectoryIndex index.php
# Secure text files
<Files ~ "\.txt$">
Require all denied
</Files>
ErrorDocument 404 /404.php
RewriteEngine On
# Redirect HTTP to HTTPS and non-www to www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [R=301,L]
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]
# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,R=301,L]
# Resolve .php file for extensionless php urls
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ /$1.php [NC,L]
A couple things to note here:
The directives above were modified to use the updated apache 2.4 syntax
The RewriteEngine on directive should come before the other rewrite rules
The HTTP -> HTTPS and non-www -> www redirect logic can be done in a single operation
The PHP extension stripping, and subsequent remapping, should be done without the full URL to avoid the duplication behavior you observed. This last bit should fix the problem.
If you need further info on some of the syntax employed here, you can check the mod_rewrite documentation.

How to resolve the conflict between www and https redirect on .htaccess? [duplicate]

I have the following htaccess code:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond !{HTTPS} off
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
I want my site to be redirected to https://www. with HTTPS, and enforcing the www. subdomain,
but when I access http://www. (without HTTPS), it does not redirect me to https://www with HTTPS.
To first force HTTPS, you must check the correct environment variable %{HTTPS} off, but your rule above then prepends the www. Since you have a second rule to enforce www., don't use it in the first rule.
RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
About proxying
When behind some forms of proxying, whereby the client is connecting via HTTPS to a proxy, load balancer, Passenger application, etc., the %{HTTPS} variable may never be on and cause a rewrite loop. This is because your application is actually receiving plain HTTP traffic even though the client and the proxy/load balancer are using HTTPS. In these cases, check the X-Forwarded-Proto header instead of the %{HTTPS} variable. This answer shows the appropriate process
Michals answer worked for me, albeit with one small modification:
Problem:
when you have a single site security certificate, a browser that tries to access your page without https:// www. (or whichever domain your certificate covers) will display an ugly red warning screen before it even gets to receive the redirect to the safe and correct https page.
Solution
First use the redirect to the www (or whichever domain is covered by your certificate) and only then do the https redirect. This will ensure that your users are not confronted with any error because your browser sees a certificate that doesn't cover the current url.
#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#Now, rewrite to HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If you are using CloudFlare or a similar CDN you will get an infinite loop error with the %{HTTPS} solutions provided here. If you're a CloudFlare user you'll need to use this:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
BAD SOLUTION AND WHY!
Don't ever use the solution below because when you are using their code that is something like:
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.example.com%{REQUEST_URI} [L,R=301]
The browser goes to:
http://example.com
Then redirects to:
https://example.com
Then redirects to:
https://www.example.com
This is too much request to the server.
Most of the answers even accepted one has this problem.
BEST SOLUTION AND THE ANSWER
This code has an [OR] condition to prevent dual changes at url!
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]
This is the best way I found for Proxy and not proxy users
RewriteEngine On
### START WWW & HTTPS
# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
### END WWW & HTTPS
There are a lot of solutions out there. Here is a link to the apache wiki which deals with this issue directly.
http://wiki.apache.org/httpd/RewriteHTTPToHTTPS
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e. http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context
To redirect http:// or https:// to https://www you can use the following rule on all versions of apache :
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]
Apache 2.4
RewriteEngine on
RewriteCond %{REQUEST_SCHEME} http [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]
Note that The %{REQUEST_SCHEME} variable is available for use since apache 2.4 .
If you are on CloudFlare, make sure you use something like this.
# BEGIN SSL Redirect
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# END SSL Redirect
This will save you from the redirect loop and will redirect your site to SSL safely.
P.S. It is a good idea to if check the mod_rewrite.c!
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Notes: Make sure you have done the following steps
sudo a2enmod rewrite
sudo service apache2 restart
Add Following in your vhost file, located at /etc/apache2/sites-available/000-default.conf
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
Now your .htaccess will
work and your site will redirect to http:// to https://www
Similar to Amir Forsati's solution htaccess redirect to https://www but for variable domain name, I suggest:
RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%2%{REQUEST_URI} [R=301,L]
Set in your .htaccess file
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I used the below code from this website, it works great https://www.freecodecamp.org/news/how-to-redirect-http-to-https-using-htaccess/
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L]
Hope it helps
I try first answer and it doesnt work...
This work:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Resources