RewriteCond & RewriteRule ignore folder - .htaccess

I have an URI domain.tld/a/b/c.php?p=123 that I want to redirect to another one (otherdomain.tld) while ignoring all foldernames and parameters.
This is what I have added to my .htaccess:
RewriteCond %{HTTP_HOST} ^domain.tld$
RewriteCond %{REQUEST_URI} ^/a/b/c.php$
RewriteRule ^(.*)$ https://otherdomain.tld/?
The result is nice and the redirect to otherdomain.tld happens as intended, parameters are removed and everything, but I end up at this URI:
otherdomain.tld/b/
I do not understand why folder "b" is still there. Could someone please explain it to me and point me to where my error in my RewriteRule (or RewriteCond) is? Thank you.
Solution
I found the solution myself through a hint by #starkeen. Since there were other RewriteRules with other RewriteConditions, I have have added two flags - R and L - and it worked like charm. So the last rule now reads like this:
RewriteRule ^(.*)$ https://otherdomain.tld/? [R,L]
...and everything works fine.

Related

htaccess extract path only from THE_REQUEST into a variable

This should be rather simple, but after trying for several hours and also searching everywhere, all the related answers do not suffice.
I have this so far:
RewriteCond %{THE_REQUEST} /([a-zA-Z0-9-_/\.]+)?
RewriteRule ^(.*)$ - [E=TRGT:%1]
What the match should be doing is the following:
for URL example.com it should contain nothing, or not be defined
for URL example.com/ it should contain nothing, or not be defined
for URL example.com/some-word it should contain some-word
for URL example.com/some-word/ it should contain some-word
for URL example.com/some-word/?foo=bar it should contain some-word
for URL example.com/another_word/ it should contain another_word
for URL example.com/folder/file.ext it should contain folder/file.ext
for URL example.com/some/other.dot?bar=foo it should contain some/other.dot
for URL example.com/thing.ext/?foo=bar&bar=foo it should contain thing.ext
What I have so far seems to be working, except for when the request ends in some/ -or some/?thing=wat .. then it contains some/
I think I'm missing something really simple; any help will be appreciated, thank you.
UPDATE
I've managed to achieve these exact requirements with the following code, but, after trying many ways to do it in a 1-liner it fails horribly, so I did it in several lines:
RewriteCond %{THE_REQUEST} (?<=\s)(.*?)(?=\s)
RewriteRule ^(.*)$ - [E=HREFPATH:%1]
RewriteCond %{ENV:HREFPATH} (^.*)?\?
RewriteRule ^(.*)$ - [E=HREFPATH:%1]
RewriteCond %{ENV:HREFPATH} /(.*)
RewriteRule ^(.*)$ - [E=HREFPATH:%1]
RewriteCond %{ENV:HREFPATH} (.*)/$
RewriteRule ^(.*)$ - [E=HREFPATH:%1]
If anybody can reduce that to a s3xy 1(or 2)-liner I will choose your answer; thanks in advance.
Based on the accepted answer here the following fulfills the requirements of the question:
RewriteCond %{THE_REQUEST} \s/+([^?]*?)/*[\s?]
RewriteRule ^ - [E=HREFPATH:%1]

How to create RewriteRule for Full path negative pattern without changing URL

I've got probably a little problem, which is the redirect from A to B without changing URL (still A) and send A as GET variable. And the second thing is to check if A doesn't start like /news.....
For example:
User access url: www.custom.com/news and rewrite does nothing here but if user access url: www.custom.com/something/abc it will redirect it to www.custom.com/router.php?path=/something/abc and visible URL for user will be still www.custom.com/something/abc
Now, I've got rule like this one:
RewriteRule !^(/news.*)$ /router.php?path=$1 [NS,R=301,L]
But it doesn't do the job and it creates and error for infinity loop(ERR_TOO_MANY_REDIRECTS)
Could you give me at least some advice how to resolve my problem?
Edit.
I've changed rule a bit and add a RewriteCond but there's still infinity loop. What's wrong here?
RewriteCond %{REQUEST_URI} !^/news.*$
RewriteCond %{REQUEST_URI} !^/router\.php.*$
RewriteRule ^(.*)$ /router.php?path=$1 [NS,R=301,L]
Edit2.
Above code now works(I've removed escape character from condition rule), but redrect still changes URL to www.sample.com/router.php=something/abc
EDIT 3:
I was wondering why my route was displaying a little bit odd, and I found the solution.
First this is that redirect was in infinity loop so that's why I've got www.sample.com/router.php?path=something/abc rather than www.sample.com/something/abc(it looped twice and saved router.php as last URI).
Second thing is that I had L-flag where I should use it... And I've add NC-flag for sure that everything will redirect.
That's my code if it could help someone:
RewriteCond %{REQUEST_URI} !^/news.*$
RewriteCond %{REQUEST_URI} !^/assets.*$
RewriteCond %{REQUEST_URI} !^/images.*$
RewriteCond %{REQUEST_URI} !^/router.php.*$
RewriteRule ^(.*)$ /router.php?path=$1 [NC]
Thanks to CBroe for help!
EDIT 4:
I thought that everything's fine, but now I found that when I am typing in a URL: www.sample.com/abc and press Enter it rewrite to the router.php and does not change URL so it is still www.sample.com/abc.
But when I am using links with href like: www.sample.com/abc it rewrite to router.php but the URL is changed too! After clicking link it's changing URL to: www.sample.com/abc?path=abc where I want to still have www.sample.com/abc
I was searching a lot and everywhere rewrite didn't make changes like mine code.
Does anyone have idea how to fix it? Thanks!
I found what was creating this weird issue.
It was a slash at the end. So if url was ending without "/" at the end it was automatically adding "/" and then GET path variable.
So I did a Rule for redirecting without slash url to url with slash.
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ /$1/ [L]

RewriteCond according to the first part of url not working

I'm trying to work on doing some rewrite but it's not working. Here is my code:
RewriteCond %{REQUEST_URI} !^(static/|server/|internal.php).*$
RewriteRule ^(.*)$ /internal.php?request=$1 [L]
I'm trying to redirect everything to /internal.php?request=blablabla, except the internal.php itself, and things in two folders called static and server, since these two folders have images and so on.
For example,
/hello/world => /internal.php?request=hello/world/
/static/a/b/c/a.jpg => /static/a/b/c/a.jpg not changed
But the code is not working, the RewriteCond seems not able to restrict rewrite of internal.php, and the two folders. Now what's happening is everything is going to rewrite to internal.php, and internal.php would be rewrite to internal.php again. And finally give me a 500 after infinite loops. Which I don't want any rewrite happen. What's wrong?
You are missing a leading / in the request URI expression, also you should escape the dot in internal.php so that it actually matches a dot instead of every char:
RewriteCond %{REQUEST_URI} !^/(static/|server/|internal\.php).*$
RewriteRule ^(.*)$ /internal.php?request=$1 [L]
Note that this will also rewrite /static and /server where the trailing slash is omitted, if you want to avoid that you could for example add another condition:
RewriteCond %{REQUEST_URI} !^/(static|server)$
RewriteCond %{REQUEST_URI} !^/(static/|server/|internal\.php).*$
Tough it should be possible to put this in a single expression, however I'm not that experienced with regular expressions, so I'm pretty sure that this not the most elegant way:
RewriteCond %{REQUEST_URI} !^/(((static|server)(/.*)?)|(internal\.php.*))$

.htaccess redirect from one subfolder to other subfolder

I know this sounds like so many other questions here, but I can't seem to find the answer.
Say you are on:
www.domain.com/folderA/folder2/folder3/
I want that to redirect to:
www.domain.com/folderB/folder2/folder3/
So the whole structure stays the same.. it just redirects.
Now so far I have:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/folderA [NC]
RewriteRule ^(.*)$ /folderB/$1 [R=301,L]
But when I use that, it'll just do
www.domain.com/folderB/folderA/folder2/folder3/
What am I doing wrong? How do I get rid of that folderA?
The pattern ^(.*)$ includes also the prefix folderA. You must specify folderA explicitly in the pattern and capture only the latter part in the RewriteRule. Then you can drop the RewriteCond
RewriteEngine on
RewriteRule ^/?folderA/(.*)$ /folderB/$1 [R,L]
Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.

Rewrite htaccess old oscommerce links

I am trying to rewrite all the old oscommerce links to a new website. But I am having trouble with part of the URL I need to rewrite.
The link looks like this:
http://www.domain.com/product_info.php?cPath=3_72&products_id=129&osCsid=6j3iabkldjcmgi3s1344lk1285
This rewrite works for the above link:
RewriteCond %{REQUEST_URI} ^/product_info\.php$
RewriteCond %{QUERY_STRING} ^cPath=3_72&products_id=129&osCsid=([A-Za-z0-9-_]+)$
RewriteRule ^(.*)$ http://www.domain.com/apple/air.html? [R=301,L]
But will not work for:
http://www.domain.com/product_info.php?cPath=3_72&products_id=129
My problem is that I want the rewrite to work no matter if the &osCsid=6j3iabkldjcmgi3s1344lk1285 part is included or not.
I think you can achieve this by not specifying the closing delimiter ($)
Give this a try:
RewriteCond %{REQUEST_URI} ^/product_info\.php$
RewriteCond %{QUERY_STRING} ^cPath=3_72&products_id=129
RewriteRule ^(.*)$ http://www.domain.com/apple/air.html? [R=301,L]
By not putting the $ at the end of the regex string you are basically saying: match any string that starts with ..., no matter what comes after
Hope this helps :)
This should do the job just fine:
RewriteCond %{QUERY_STRING} ^cPath=3_72&products_id=129
RewriteRule ^product_info\.php$ http://www.domain.com/apple/air.html? [R=301,L]
There is no need for separate condition RewriteCond %{REQUEST_URI} ^/product_info\.php$ -- this part can be (actually, SHOULD BE, for better performance) moved to RewriteRule.
This is enough ^cPath=3_72&products_id=129 -- it tells "When query strings STARTS with ...". No need to include optional/non-important parameters osCsid=([A-Za-z0-9-_]+).
This rule is to be placed in .htaccess file in website root folder. If placed elsewhere some small tweaking may be required.

Resources