redirect loop with mod_rewrite - apache

I'm trying to add a language prefix to my pages through mod_rewrite
eg:
https://example.com/ > https://example.com/en/
and internally it need to translate to `https://example.com/?language=en
I've managed to do it for the base url, but when I try to do it with some other redirect implied, it's always end in an infinite loop.
eg:
https://example.com/product-p-22.html > https://example.com/en/product-p-22.html
and internally became `https://example.com/product_info.php?product_id=22&language=en
here is my actual config:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/(en|fr)/
RewriteCond %{REQUEST_URI} .(php|html) [OR]
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{QUERY_STRING} !language=
RewriteRule ^(.*)$ en/$1 [L,R=301]
RewriteCond %{REQUEST_URI} !^/example
RewriteRule ^(.*)/$ index.php?language=$1&%{QUERY_STRING}
RewriteRule ^(.*)/(.*)-p-(.*).html$ product_info.php?products_id=$3&language=$1&%{QUERY_STRING}
I've tried many flags like L, END, DPI or some combination of those, but with no luck.
when I look at the debug logs, it seems to find the right url, but then restart parsing the default url:
pass through /var/www/example/product_info.php
init rewrite engine with requested uri /product-p-22.html
pass through /product-p-22.html
any though on what I'm doing wrong here?
Server version: Apache/2.4.41 (Ubuntu)

Based on your shown samples, could you please try following. Please make sure you clear your browser cache before testing your URLs.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^en [NC]
RewriteRule ^(.*)$ en/$1 [NC,R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php?language=en [NC,QSA,L]
RewriteRule ^([^/]*)/([^-]*)-p-([^.]*)\.html$ product_info.php?products_id=$3&language=$1& [NC,L,QSA]

Have it this way in your site root .htaccess:
RewriteEngine On
RewriteCond %{THE_REQUEST} !\s/+(en|fr)/ [NC]
RewriteRule ^ /en%{REQUEST_URI} [NC,R=301,L]
RewriteRule ^([a-z]{2})/[^-/]+-p-([^./]+)\.html?$ product_info.php?language=$1&products_id=$2 [L,QSA]
RewriteRule ^([a-z]{2})/$ index.php?language=$1 [QSA,L]

Related

How to htaccess url rewrite multi language

Can someone help me with the htaccess rewrite url?
I need to convert ?lang=en to /en
To always display the language used in the url
When someone comes to example.com to automatically 301 redirect them
to example.com/en as the main language.
When a user chooses another language to stay on the same page e.g.
example.com/en/contact.php
I have a total of three languages on the site en, de, hr.
The problem with my code is when I go to example.com/contact and select a language, it takes me back to the homepage example.com/en. If I type manually example.com/en/contact it works.
If I am at example.com/en/contact and choose another language e.g. /de url changes to example.com/en/de and a 404 error.
My current htaccess code looks like this
# Convert ?lang=en in /en
RewriteRule ^([a-z]{2})/?$ ?lang=$1 [QSA,L]
RewriteRule ^([bs|en|de]{2})/(.*)$ $2?lang=$1&%{QUERY_STRING} [L,QSA]
# Remove trailing slash from URL
RewriteCond %{REQUEST_URI} /(.+)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://example.com/%1 [R=301,L]
# Remove php extension in URL
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
With your shown samples, could you please try following.
Please make sure to clear your browser cache before testing your URLs.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-SSL} !ON
RewriteCond %{HTTP_HOST} ^(?:www\.)reg\.bmi\.id$ [NC]
RewriteRule ^/?$ https://reg.bmi.id [R=301,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\scontact/contact\.php [NC]
RewriteRule ^ https://reg.bmi.id [R=301]
RewriteRule ^ contact/contact.php [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

.htaccess Adding HTTPS forcing to existing rewrite rules of subdirectory

Probably I'm overseeing something very basic, htaccess is not my field of expertise.
My site is https-only, to achieve this, the root folder / contains these lines:
RewriteEngine On
RewriteCond %{ENV:HTTPS} !on
RewriteRule ^(.*) https://%{HTTP_HOST}/$1 [R=301,L]
This works just fine. Now we have a new folder called /projects, which contains its own htaccess rules to translate the url in a database query by a file called /projects/project.html
The working htaccess within the folder /projects is:
RewriteEngine On
RewriteBase /projects/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ project.html?project=$1 [QSA,L]
Now I would like to force https connection on this one, because the https rule in the main directory is not applied on /projects if you visit by http://URL directly. Therefore I modified the file to:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://example.com%{REQUEST_URI} [R=301,L,NE]
RewriteBase /projects/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ project.html?project=$1 [QSA,L]
With this, it switches to https, but I keep getting "ERR_TOO_MANY_REDIRECTS".
When I change the lines as #thickguru suggested, like this:
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
It will redirect me to https://example.com/index.html right away.
I fiddled around with the settings, also with the information of this post, however still I can't get it to work.
I just noticed it the variable you are matching against is %{ENV:HTTPS} , so , you can use the following rule in /projects/.htaccess :
RewriteEngine on
RewriteCond %{ENV:HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R]
Clear your browser cache or try a diffrent browser to test this.
Use this in your .htaccess:
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://www.example.com%{REQUEST_URI} [R=301,L,NE]
Also, place this above your your other RewriteRule, so that your .htaccess will look like:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://www.example.com%{REQUEST_URI} [R=301,L,NE]
RewriteBase /projecten/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ project.html?project=$1 [QSA,L]
EDIT - Try this:
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

Why isn't my htaccess RewriteRule working for my query strings?

I am moving an ASPX site to Wordpres -- from an IIS server to Apache -- and I am having problems getting the pages with query strings to redirect. I looked into the Apache documentation and am trying to use mod_rewrite, but so far no luck.
For example I would like to redirect these pages:
www.mysite/Product/Product.aspx?mapid=324$ to
www.mysite/blue-widgets/widget7/
www.mysite/Product/Product.aspx?mapid=681$ to
www.mysite/blue-widgets/widget12/
www.mysite/Product/Product.aspx?mapid=841$ to
www.mysite/blue-widgets/widget82/
Here is where I am at. I have tried several iterations of this but can't get it to work. I am starting to think that it might have something to do with first few Rules, which were generated by the server and Wordpress. The site is an addon domain, which the server treats like a subdomain.
My rewrites are the last three. Any ideas why these aren't working? Thanks for any help.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /~username/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /~username/mysite/index.php [L]
RewriteCond %{QUERY_STRING} ^mapid=324$ [NC]
RewriteRule ^/Product/Product\.aspx(.*)$ ^https://www.mysite/blue-widgets/widget7/? [L,R=302,NC]
RewriteCond %{QUERY_STRING} ^mapid=681$ [NC]
RewriteRule ^/Product/Product\.aspx(.*)$ ^https://www.mysite/blue-widgets/widget12/? [L,R=302,NC]
RewriteCond %{QUERY_STRING} ^mapid=841$ [NC]
RewriteRule ^/Product/Product\.aspx(.*)$ ^https://www.mysite/blue-widgets/widget82/? [L,R=302,NC]
</IfModule>
I believe the following will work:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^mapid=324$ [NC]
RewriteRule /Product/Product\.aspx https://www.example.com/blue-widgets/widget7/? [L,R=302,NC]
RewriteCond %{QUERY_STRING} ^mapid=681$ [NC]
RewriteRule /Product/Product\.aspx https://www.example/blue-widgets/widget12/? [L,R=302,NC]
RewriteCond %{QUERY_STRING} ^mapid=841$ [NC]
RewriteRule /Product/Product\.aspx https://www.example/blue-widgets/widget82/? [L,R=302,NC]
RewriteBase /~username/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /~username/mysite/index.php [L]
To better explain for others, the order of the rules is important. Since the Wordpress rules change the RewriteBase and change the URL the rules for the .aspx pages will never be hit if they are at the bottom.

how to fix htaccess error with multiple rewrite rule - ERR_TOO_MANY_REDIRECTS

why this htaccess has error. it says "to many redirect" please help thanks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php [L]
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ http://us.domain.com/ae_en/$1 [R=301,L]
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^us\.domain\.com$
RewriteCond %{REQUEST_URI} !^/(ae_en|ae_ar) [NC]
RewriteRule ^(.*)/ae_en/%{REQUEST_URI} [R=301,L]
I cannot try the wrong code, it always appear error
There are several issues with your .htaccess. I would suggest both re-ordering and editing the rules.
This would be a better approach, in my opinion. I'll explain the parts below.
RewriteEngine on
RewriteBase /
Options +FollowSymLinks
# External redirect: Remove www from domain
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# External redirect: Ensure language code is set
RewriteCond %{HTTP_HOST} ^us\.domain\.com$
RewriteCond %{REQUEST_URI} !^/(ae_en|ae_ar) [NC]
RewriteCond %{REQUEST_URI} !^/index.php$ [NC]
RewriteRule ^(.*)$ /ae_en/$1 [R=301,L]
# Internal redirect: Pass everything non-existent to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php [L]
Structure
First, general options and settings should come at the top and only once, i.e.
RewriteEngine on
RewriteBase /
Options +FollowSymLinks
Second, I like to get the external URL to show up correctly, so I group all external redirects here - denoted with comments in the above code block.
Third, internal "redirects" follow, meaning mapping the (now correct and final) external URL to the correct scripts.
This structure ensures that the internal scripts are only matched on a URL that will not change when re-run against the .htaccess on the next RewriteRule match.
Omitting external redirect for index.php
I guess you added the index.php redirection handling after adding in the internal redirect, which probably has caused index.php to show up in the browser. So, with the above structure in place, I assume it will not show up again.
Error in last RewriteRule
As Mike Rockett pointed out in the comment above, there also was an error in the last RewriteRule.
Avoid redirect loop
To avoid a redirect loop when rewriting to index.php with the last rule, you have to explicitly exclude index.php from language code redirection, i.e.
RewriteCond %{REQUEST_URI} !^/index.php [NC]

htaccess - redirect to https not working

Per: https://exp-resso.com/blog/post/2011/08/securing-your-expressionengine-website-with-https
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond $1 ^(member|account|checkout|system) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
This tells your server “If HTTPS is off, and the request starts with
member OR account OR checkout OR system (not case sensitive), redirect
to https://current-domain/current-page”. It’s a nice simple method of
locking down entire subfolders / template groups.
I've added this to my htaccess file like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond $1 ^(sign-in|sign-up) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
However, when I go to my http://mydomain.com/sign-in, the URL doesn't change to https://mydomain.com/sign-in. Any idea what's wrong?
EDIT 1:
My htaccess also has the following (to remove "www") and I wonder if having both might be causing the problem?
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
EDIT 2:
Process of elimination, it turns out this is causing the problem:
<IfModule mod_rewrite.c>
RewriteEngine On
# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
When I comment out the RewriteRule, the https:// is forces. What's causing the conflict?
Try to put (sign-in|sign-up) condition inside RewriteRule:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(sign-in|sign-up)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,NC,R=301]
What about this? (If port == 80 then redirect )
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} member [OR]
RewriteCond %{REQUEST_URI} account [OR]
RewriteCond %{REQUEST_URI} checkout [OR]
RewriteCond %{REQUEST_URI} system
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
First make sure that rewrite works on your server and that the htaccess is read (e.g. by issuing a redirect on every URL).
Then use RewriteCond %{REQUEST_URI} ^/(sign-in|sign-up) instead of RewriteCond $1 ^(sign-in|sign-up) [NC]
It works and is easier to read too
So you htaccess should look like this
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} ^/(sign-in|sign-up) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]