this mod_rewrite rule has me for a loop - apache

I want to have /path/short serve up the content held by the file /path/short.html, but if the user types /path/short.html or /path/short/ I want him to be redirected (with 301) to /path/short. This is what I have so far in my .htaccess:
RewriteEngine On
RewriteBase /path
RewriteCond %{REQUEST_URI} !=/path/handle.html
RewriteCond %{REQUEST_URI} !^/path/short(.html|/)?$
RewriteRule ^(.+) /cgi-bin/handle\.cgi?$1 [PT,QSA]
RewriteRule ^path$ /path/short.html
#-------
RewriteRule ^short/$ /path/short [R=301,L]
# RewriteRule ^short.html$ /path/short [R=301,L]
The rules reflect the fact that handle.cgi will receive all other requests (ie, /path/this, /path/, /path/somethingelse, etc.) which is working great. So far, the /path/short/ redirects correctly to /path/short and /path/short is properly showing the content in /path/short.html, however, uncommenting the last line causes a loop. So, how do I get this to work?

You can use this code in /path/.htaccess:
RewriteEngine On
RewriteBase /path/
RewriteCond %{THE_REQUEST} /(short)(/|\.html) [NC]
RewriteRule ^ %1? [R=301,L]
RewriteRule ^(short)/?$ $1.html [L,NC]

A friend pointed me towards another question which helped me arrive at this solution:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/ads/short(.html|/)?$
RewriteRule ^(.+) /cgi-bin/handle\.cgi?$1 [PT,QSA]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^short(.html|/)$ /ads/short [R=301]
RewriteRule ^short$ /ads/short.html
which works perfectly.

Related

RewriteRule - remove params keys and keep values in address bar

RewriteEngine ON
RewriteRule ^video$ video.php [L]
the above line works
example.com/video is interpret as example.com/video.php
now I need example.com/video?id=5&s=lorem-ipsum
to interpret as example.com/video/5/lorem-ipsum - and vice versa
RewriteCond %{THE_REQUEST} video?id=([^\s&]+)&s=([^\s&]+) [NC]
RewriteRule ^ %1/%2? [R=301,L]
RewriteRule ^([\w-]+)/([\w-]+)/?$ video?id=$1&s=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ video?/$1/$2 [L,QSA]
doesn't work - in both directions
pls help
With your shown attempts, please try following .htaccess rules file. These rules are assuming you want to infernally rewrite to index.php you can change php file name in 2nd set of rules as per your requirement.
Make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##External redirect Rules from here..
##Redirect 301 to example.com/video/5/lorem-ipsum from example.com/video?id=5&s=lorem-ipsum
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{THE_REQUEST} \s/(video)\?id=([^&]*)&s=(\S+)\s [NC]
RewriteRule ^ /%1/%2/%3? [R=301,L]
##Internal rewrite for example.com/video?id=5&s=lorem-ipsum
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^video/([^/]*)/(.*)/?$ index.php?id=$1&s=$2 [QSA,NC,L]

Index Coverage - Redirect Error from Index.php

I thought I solved this problem two years ago but now since a couple of weeks I get harassed by the Google Search Console with "Index Coverage" referring to the /index.php of my homepage (all variants of my website are listed in the Search Console and I have a canonical URL in the head part). Also, if I call my www.xxx./index.php it says "Page doesn't work - too many redirects".
Now I know this is not directly a programming issue, but since it involses the htaccess, which is somehow red and black art and just voodoo, I can't get my code to be working correctly/my site being accessible and correctly redirected.
My .htaccess adresses the problem the following. I already tried switching out and deleting parts but it keeps sticking around like a reckless goblin:
// This should redirect to http with www
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
// This should redirect index.php requests - to be redirected to https://www.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\/index\.php\ HTTP/
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
// Redirect from capital Index.php to index.php
RewriteRule ^Index\.php$ /index.php [R=301,L]
// This redirects from /html and /index requests combined with .php to the https:// version
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.(html?|php)\ HTTP/
RewriteRule ^index\.(html?|php)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^index\$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
// I'm not sure anymore...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R]
Edit: I feel that the problem is - like my browser and the search console says - that too many redirects happen (to www.xxx.de/index.php). So I tried out different .htaccess parts and deleting some to minimize the redirections, which for now doesn't seem to work.
I assembled the parts together on my own (not via a framework), I guess that explains sth.
Edit 2: After I deleted line after line and tested the effects, the only part that affects the /index.php is as expected the RewriteRule ^index\.(html?|php)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L], but then the website is also simply accessible under /index.php
What about replacing
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
with
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}/ [R=301,L]
Since essentially what you want is to redirect the users that referenced /index.php to /?
I replaced
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\/index\.php\ HTTP/
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^Index\.php$ /index.php [R=301,L]
with
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{THE_REQUEST} /index\.php
RewriteRule ^index\.php https://www.%{HTTP_HOST}/ [R=301,L]
RewriteRule ^Index\.php$ /index.php [R=301,L]
and now /index.php is correctly redirected to my www.xxx.net/ without any loop.

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]

Redirect not working for complex rewrite rules (.htaccess)

I'm trying to make a redirect from a non-www version of the link to the www one. Its working fine for something like http://mywebsite.com but it fails for a request like http://mywebsite.com/artists/metallica/ or even a complex one. The whole .htaccess file is bellow. Any clues?
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*).html
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://mywebsite.com/$1/ [L,R=301]
RewriteRule ^artists/([^/-]+)-p([^/]+)/$ /artists.php?l=$1&p=$2 [QSA,L]
RewriteRule ^artists/([^/]+)/$ /artists.php?l=$1 [QSA,L]
RewriteRule ^submit/$ /submit.php [QSA,L]
RewriteRule ^users/$ /users.php [QSA,L]
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.mywebsite.com/$1 [R=301,L]
Try this rule:
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
But make sure that you put this rule in front of those rules that just do an internal rewrite. Otherwise an already internally rewritten rule might get redirected externally.

htaccess problems with redirect for no www

I've been trying everything to manage a redirect from www.domain.com to domain.com,
but nothing seems to work for me. I always get a redirect loop - and I've tried various things I found here or on Google.
So here is my .htaccess, maybe someone could help me figure out what I can do to redirect correctly or if there is something wrong in here.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
# Redirect all to .php
# Example: example.com/hello -> example.com/hello.php
RewriteRule ^(.*)$ $1.php [L,R=301]
# show example.com/index.php always as example.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://example.com/ [R=301,L]
Thank you so much!
I've already spent so much time trying to figure this out.
You have a rule that always matches, which is responsible for the infinite redirection. I've updated your ruleset below to fix that problem and perform the redirection you mentioned at the top of the answer. Let me know if this does what you expect.
RewriteEngine On
# Redirect www.example.com to example.com
RewriteCond %{HTTP_HOST} ^www [NC]
RewriteRule ^.*$ http://example.com/$0 [R=301,L]
# This performs an external redirection? Is that what you want?
# Don't do the rewrite if we're already pointing at a file, otherwise we'll
# just redirect over and over because .* matches what we redirect to, too
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^.+$ $0.php [L,R=301]
# show example.com/index.php always as example.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://example.com/ [R=301,L]
The answer is Apache documentation, the documentation tell how to force usage of www. You just have to reverse the example.
RewriteCond %{HTTP_HOST} !^example\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://example.com/$1 [L,R]