Avoid infinite loop with 301 redirects - .htaccess

I'm using .htaccess to redirect
http://www.example.com/foo/
to
http://www.example.com/foo/bar
This is my code:
redirect 301 /foo/ http://www.example.com/foo/bar
However this produces a feedback loop, something like
http://www.example.com/foo/barbarbarbarbarbar etc.
I've tried placing delimiters around it:
redirect 301 ^/foo/$ http://www.example.com/foo/bar
but then the redirect simply doesn't take place. I'm probably missing some very simple point of syntax. Any ideas? Thanks.
EDIT
Here's my (almost) full .htaccess file:
RewriteEngine On
RewriteBase /
# Canonical is www version
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
#redirect => http unless special page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(javascripts|images|library|stylesheets)
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#redirect => https for special pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# send to router
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]

Have your rules like this:
RewriteEngine On
RewriteBase /
# Canonical is www version
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^ http://www.example.com%{REQUEST_URI} [L,R=301]
#redirect => http unless special page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} on
RewriteCond %{THE_REQUEST} !/(javascripts|images|library|stylesheets)
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#redirect => https for special pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} off
RewriteRule !^index\.php$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^foo/?$ /foo/bar [L,NC,R=301]
# send to router
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
make sure to test this in a new browser or clear your browser cache before testing.

For your information, it really depends on your hosting provider. It may be behind a Load Balancer and you don't have the proper env var set (like HTTPS and others...).
In my case (Infomaniak), nothing actually worked and I got infinite redirect loop.
The right way to do this for Infomaniak is actually explained in their support site:
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://your-domain.com/$1 [R=301,L]
So, always check with your hosting provider. Hopefully they have an article explaining how to do this. Otherwise, just ask the support.

It depends on what is the resource that you want to expose with your redirect.
Is it a file or a directory.
if you would expose a directory under bar you should try :
RedirectMatch 301 ^/foo/ http://www.example.com/foo/bar/
if you would redirect to a file you should use this syntax :
redirect 301 /foo http://www.example.com/foo/bar
you can see this post for more informations

Instead of using redirect, you can use passthrough.
RewriteRule ^/foo$ /foo/bar [PT]

Related

redirection from HTTP to HTTPS show public folder

I want to make redirection from http to https.
I try to use this .htaccess code
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
but that show the public folder in the url,
more explain my site is www.example.com white this code is going like this www.example.com/public/
I have this code is my .htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
and I want to make the redirection to a specific domain, if the users try for example : example.com, I need to redirect to www.example.com
any solution ?
That is happening because you're also requesting the URI in the RewriteRule. You need to change the rules to the following:
RewriteEngine On
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
You can see this rule working here with the /public/ URI and it going to https://example.com only. Make sure you clear your cache before testing this.

htaccess non-www to www while http to https and http://www to https://www

Basically, i want to have these
non-www to www
http to https
http://domain.com to http://www.domain.com
My current htaccess is this.
Options -Indexes
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?url=$1 [QSA,NC,L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI}$1 [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}$1
It works fine this way, but when you manually go to http://domain.com, and change it to https://domain.com, it added two sets of index.php.
Any ideas please?
What I can see to be an issue with your code is that you have $1 on the WWW and HTTPS redirects, which would add the request URI path at the end twice, since you already have %{REQUEST_URI}:
Options -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}:443%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?url=$1 [QSA,NC,L]
Also it would be easier if you first redirect HTTP to HTTPS (if needed) and then check whether or not the WWWW is missing to redirect (again if needed).
Could probably leave the HTTPS rule without [R=301,L] but if the URL is already right we want to avoid processing more rules.
Keep in mind that the ORDER of your rules is very important.

Redirect select pages to https

I have a very simple question that for some reason I cannot figure out, and hours of searching has not helped either. Using an .htaccess file, how can I redirect just /login.php and /index.php to https, and then redirect any other page to just http? I currently use this code to redirect to https, but it redirects every page:
RewriteCond %{SERVER_PORT} !443
RewriteRule ^(.*) https://www.ruxim.com/$1 [R]
thank you very much.
The %{SERVER_PORT} variable depends on the UseCanonicalPhysicalPort in your config. If it's not setup, then you may not be able to match against that variable, easier to use %{HTTPS} instead.
RewriteCond %{HTTPS} off
RewriteRule ^/?(login|index)\.php https://www.ruxim.com%{REQUEST_URI} [L,R]
RewriteCond %{HTTPS} on
RewriteRule !^/?(login|index)\.php http://www.ruxim.com%{REQUEST_URI} [L,R]
If you don't need the redirect to non-https, then you don't need the second rule.
Try something like this;
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_FILENAME} =index.php [OR]
RewriteCond %{REQUEST_FILENAME} =login.php
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
I'm note 100% sure if the [OR] will comply suddenly in the middle.
Please apply following conditions to secure only /login.php and /index.php pages. Other pages will be work on HTTP path (non-secure pages).
RewriteEngine On
RewriteBase /
# force https for /login.php and /index.php
RewriteCond %{HTTPS} =off
RewriteRule ^(index|login)\.php$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# don't do anything for images/css/js (leave protocol as is)
RewriteRule \.(gif|jpe?g|png|css|js)$ - [NC,L]
# force http for all other URLs
RewriteCond %{HTTPS} =on
RewriteCond %{REQUEST_URI} !^/(index|login)\.php$
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Remove www site-wide, force https on certain directories and http on the rest?

Firstly, I would like to remove the www. from my domain name
http://www.example.com => http://example.com
I would also like for certain directories to be secure (https), while the rest remain http
http://example.com/login => https://example.com/login
Obviously it needs to work for all conditions, for example if someone types in:
http://www.example.com/login => https://example.com/login
Also when people navigate away from the login page it returns to http. Currently in the .htaccess is the following which is done automatically by the software I am using and I suppose needs to be there for it to work:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ./index.php
Any ideas on how I can achieve dream control all these things?
Thanks in advance!
===================
#Gumbo Following your advice this is my complete .htaccess
RewriteEngine On
# remove www from host
RewriteCond %{HTTP_HOST} ^www\.(.+)
RewriteCond %{HTTPS}s/%1 ^(on(s)|offs)/(.+)
RewriteRule ^ http%2://%3%{REQUEST_URI} [L,R=301]
# force HTTPS
RewriteCond %{HTTPS} =off
RewriteRule ^(login)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# force HTTP
RewriteCond %{HTTPS} =on
RewriteRule !^(login)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ./index.php
Options -Indexes
Navigating to http://example/login still goes to http://example/index.php when it should go to https://example/login Do I have the order wrong?
Try these rules:
# remove www from host
RewriteCond %{HTTP_HOST} ^www\.(.+)
RewriteCond %{HTTPS}s/%1 ^(on(s)|offs)/(.+)
RewriteRule ^ http%2://%3%{REQUEST_URI} [L,R=301]
# force HTTPS
RewriteCond %{HTTPS} =off
RewriteRule ^(login|foo|bar|…)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# force HTTP
RewriteCond %{HTTPS} =on
RewriteRule !^(login|foo|bar|…)$ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
You also might want to add some additional conditions to only change the protocol on GET and HEAD requests but not on POST requests.
This code works for me:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
remove www (tested):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^www\.yoursite\.com$ [NC]
RewriteRule ^(.*)$ http://yoursite.com/$1 [L,R=301]
redirect (not tested):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} \/login/?.*\ HTTP [NC]
RewriteRule ^(.*)$ https://yoursite.com/login [L,R=301]
After reading this all post time line i have get success for following error: My website(c4dprime.com) was attached https: in mozilla firefox browser. Google and internet explore are show domain address as http: (The real problem in firefox) I did not want https: for my domain in any browser because one unknow redirect attached with my domain by https: (Cause for this error)after Installing following plugins in wordpress,(Easy redirect for ssl).... I have told to every one do not use any low level plugins for wordpress.
Anyway! After reading many articles and tutorials at this topic via google search engine. Now i am happy to say i have solve this problem from this post tips. Remember one thing about me i am new to in this form and wordpress.
This tip is help full for me
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^www\.yoursite\.com$ [NC]
RewriteRule ^(.*)$ http://yoursite.com/$1 [L,R=301]
After edit or some changes in my .htaccess file following code i have use now with solved this error.
AddHandler c4d-prime .com
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteBase /
RewriteRule ^$ http://www.c4dprime.com/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Unable to make a 301 domain redirection

Hi I have an application which uses opencart. I would like to make a 301 reditect in case the user types http://example.com. To be redirected in http://www.example.com (301 status code)
Here is my .htaccess content:
RewriteEngine On
\#OPENCART REWRITES START
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php
\#OPENCART REWRITES END
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
I get 302 redirection instead of 301.
Thanx,
Granit
Have you tried doing:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
Emphasis on the second line, as it matches against http://example.com as opposed to matching against anything-but www.example.com, which will break if you happen to use subdomains. I'm not sure if this is exactly related to your 301/302 issue, but it could have an affect. Also, try on your Rule [R=301,NC,L].
Try it with a different order. Put your rules that cause an external redirect before those that only cause an internal redirect:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
#OPENCART REWRITES START
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php
#OPENCART REWRITES END

Resources