.htaccess strange Redirect behaviour - .htaccess

I have following .htaccess (domain names have been changed and file shortened):
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=302,L]
Redirect 302 / https://www.destination.com/software/pwa
Redirect 302 /cases https://www.destination.com/cases
Redirect 302 /cases/digitaal-meldpunt-voor https://www.destination.com/cases/ontwikkeling
When I visit https://www.example.com, I am redirected properly to https://www.destination.com/software/pwa. But when I visit https://www.example.com/cases, I am being redirected to https://www.destination.com/software/pwacases.
Looks like the first rule is interfering with the others and I have no clue why, Google says that this should be working properly.
If I rewrite the .htaccess to:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=302,L]
RewriteRule ^(|/)$ https://www.destination.com/software/pwa [R=302,L]
RewriteRule ^cases(|/)$ https://www.destination.com/cases [R=302,L]
Both redirects are working properly. Why doesn't the first .htaccess work as intended?

Redirect 302 / https://www.destination.com/software/pwa
Redirect 302 /cases https://www.destination.com/cases
Redirect 302 /cases/digitaal-meldpunt-voor https://www.destination.com/cases/ontwikkeling
As noted in comments, the mod_alias Redirect directive uses simple prefix-matching, and everything after the match is appended to the end of the target URL. So, the first redirect above matches everything and everything after the initial slash is appended to the end of the target URL - which is what you are seeing.
To resolve this you can reorder the Redirect directives so the most specific is first.
Or, you could use a mod_alias RedirectMatch instead which matches against a regex (like the mod_rewrite RewriteRule), rather than simple prefix-matching.
For example:
RedirectMatch 302 ^/$ https://www.destination.com/software/pwa
RedirectMatch 302 ^/cases$ https://www.destination.com/cases
RedirectMatch 302 ^/cases/digitaal-meldpunt-voor$ https://www.destination.com/cases/ontwikkeling
Which matches only the URLs /, /cases or /cases/digitaal-meldpunt-voor exactly.
Note that in your RewriteRule (mod_rewrite) directives you have also allowed for an optional trailing slash? The Redirect directives would also have allowed for an optional trailing slash because they are prefix-matching.
It is the prefix-matching nature of the Redirect directive that allows you to easily mass-redirect everything from one domain to another whilst maintaining the URL-path:
Redirect / https://newdomain.example/

Related

How to stop RewriteRule overruling Redirect 301 in htaccess

I would like to make some massive redirects in .htaccess because of a migration. I'm using both RewriteRule and Redirect 301. But the RewriteRule keeps overwriting the Redirect 301 rules, despite of the order.
For example:
I would like to redirect /retraites-nl-cat-595.html to https://www.vihara.nl/meditatieretraites/
But all the other url's that contains 595 to https://www.vihara.nl/tag/vipassana/
I have this in .htaccess:
RewriteEngine on
RewriteRule ^$ https://www.vihara.nl [R=301]
Redirect 301 /retraites-nl-cat-595.html https://www.vihara.nl/meditatieretraites/
RewriteRule ^(.*)595(.*)$ https://www.vihara.nl/tag/vipassana/ [L,R=301]
But this is not working because the RewriteRule is overruling the Redirect 301 rule. The same happens when I switch the order of the last 2 lines.
Is there a way to change this? So the Redirect 301 will be overruling the Rewrite rule, instead of the other way around?

301 /product?title=jar&id=190 to homepage

i'm trying to redirect a page to homepage and cant seem to make it work with .htaccess for some reason
/product?title=jar&id=190 to homepage
i've already tried
Redirect 301 ^/product?title=jar&id=190 /
and
Redirect 301 ^/product?title=jar&id=190 /index
and a couple other redirects but for some reason they are not working
Redirect directive works on URL path only. Since your URL contains a query String title=jar&id=190 you will need to use RewriteRule for this .
RewriteEngine on
RewriteCond %{QUERY_STRING} ^title=jar&id=190$ [NC]
RewriteRule ^product/?$ /? [L,R=301]

htaccess regex to prevent rouge indexed url's

looking for a regular expression in my .htacess that will allow
http://example.com/index.php or http://example.com/anything-else
but redirect
http://example.com/index.php/anything-else
this is as close as I can come to the proper regex
RewriteEngine on
RewriteCond %{QUERY_STRING} index.php/
RewriteRule ^index\.php$ /send-them-to-404/? [L,R=301]
You can use AcceptPathInfo directive as I already mentioned in comments but if
urls were indexed by search engines then you need to use a 301 redirect to redirect them to a 404 page. 301 redirect updates previously indexed urls to the new ones.
RewriteEngine on
RewriteRule ^.+\.php/.+$ /404.php [L,R=301]

.htaccess 301 rewrites with question marks

I'm using something similar to the following:
RewriteEngine on
Redirect 301 / http://newdomain.co.uk/link/
Redirect 301 /showcase.asp?showcaseid=1 http://newdomain.co.uk/track1
Redirect 301 /showcase.asp?showcaseid=2 http://newdomain.co.uk/track2
Redirect 301 /showcase.asp?showcaseid=3 http://newdomain.co.uk/track3
Redirect 301 /showcase http://newdomain.co.uk/link/tracks
With that in mind any URL other than the mentione would go to http://newdomain.co.uk/link
Which is fine however any of the other URL's that use a "?" go to say http://newdomain.co.uk/link/showcaseid=1 for /showcase.asp?showcaseid=1
Also with the
Redirect 301 /showcase http://newdomain.co.uk/link/tracks
can I just write as follows:
Redirect 301 /showcase tracks
You can't match against the query string (everything after the ?) in a Redirect directive. You have to use mod_rewrite's %{QUERY_STRING} variable:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^showcaseid=([0-9])
RewriteRule ^showcase\.asp$ http://newdomain.co.uk/track%1 [L,R=301]
RewriteRule ^showcase$ http://newdomain.co.uk/link/tracks [L,R=301]
RewriteRUle ^$ http://newdomain.co.uk/link/ [L,R=301]
Note that the order is important. You generally want the more general matching rules to be at the end.

htaccess Redirect 301 problem .. all redirects with one string fail to redirect and 404

So I have moved a website and am trying to 301 redirect everything, which I do quite often so this is a weird problem but probably something stupid I'm not seeing.
ALL of my redirects are working fine, except any redirect that the first string starts with "/Dining" or "/dining" are failing. For example, this redirect works fine-
Redirect 301 /healthfitness/teeth.cfm /healthcare/pretty-teeth
...as well as 100s of others.
But all of these are failing (many more than I'm showing)-
Redirect 301 /Dining/diningreviews/vawines.cfm /shopping/wines-2004
Redirect 301 /Dining/diningathome/carrotcake.cfm /home-garden/carrot-cake-2003
Redirect 301 /Dining/diningathome/oldvarolls.cfm /home-garden/virginia-rolls-2003
Redirect 301 /Dining/diningathome/pumpkincake.cfm /home-garden/pumpkin-cake-2003
The top of my .htaccess file looks like this-
RewriteEngine On
RewriteBase /
#uploaded files
RewriteRule ^(.*/)?files/$ index.php [L]
RewriteCond %{REQUEST_URI} !.*wp-content/plugins.*
RewriteRule ^(.*/)?files/(.*) wp-content/blogs.php?file=$2 [L]
# add a trailing slash to /wp-admin
RewriteCond %{REQUEST_URI} ^.*/wp-admin$
RewriteRule ^(.+)$ $1/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
<IfModule mod_security.c>
<Files async-upload.php>
SecFilterEngine Off
SecFilterScanPOST Off
</Files>
</IfModule>
#Everything below here are Redirect 301s
Dont redirect statements have to include the protocol in the destination?
You must include the domain name in the redirect.
Never mix mod_alias and mod_rewrite directives in the same file. If you use RewriteRule for any of your rules, you must use RewriteRule (not Redirect or RedirectMatch) for ALL of your rules.
List all redirects (using RewriteRule syntax) before any of the rewrites (using RewriteRule syntax) otherwise you will inadvertently expose rewritten pointers back out on the the web as new URLs.
The code you are currently using is very very inefficient. The .* patterns mean your .htaccess file will attempt hundreds of thousands of "back off and retry" trial matches for every URL request hitting the server.
In particular,
^(.\*/)? should be replaced by ^([^/]+/)\* in two places.
^.\*/ should be replaced by ^/([^/]+/)\*
!.\*wp-content/plugins.\* should be replaced by !wp-content/plugins
^([_0-9a-zA-Z-]+/)?(.\*\\.php)$ should be replaced by ^([_0-9A-Z-]+/)?([^.]+\\.php)$ with the [NC] flag also added.
The "add a trailing slash to /wp-admin" redirect should be the very first ruleset in the file and the target URL should include the protocol and domain name. That rule should be immediately followed with a non-www to www canonicalisation rule.
The new code may well run hundreds of times quicker.

Resources