How to alter the url of a directory - .htaccess

I need to change the url of a directory so that:
www.example.com/foo/
becomes
www.example.com
I can't move the files.
Putting a htaccess file using mod_rewrite to simply rewrite www.example.com to www.example.com/foo wasn't a problem
RewriteEngine On
RewriteRule !^foo/ foo%{REQUEST_URI} [L]
However I must ensure that if the user requests www.example.com/foo that the http status is 404 or the user is redirected to www.example.com. Unfortunately whatever I do, it seems to end up in an infinite loop. For example this results in an infinite redirection loop:
RewriteEngine On
RewriteRule !^foo/ foo%{REQUEST_URI} [L]
RewriteCond %{REQUEST_URI} ^/foo
RewriteRule ^foo(.*) http://www.example.com$1 [R=301,L]

You need to condition on the original request sent to the server, since the %{REQUEST_URI} will change during the mod_rewrite processing, which causes the internal redirect loop.
Consequently, something like this should take care of things (for the 404, your 301 RewriteRule should work fine as well if you want to swap that in):
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/foo [NC]
RewriteRule ^ - [R=404]

Related

Redirect loop while looking for uri that does NOT contain specific string

I have an site lets say https://example.com/ and I would like to redirect every url that doesn't begins with /something to https://example.com/something/
I'm using Apache 2.4.29 (hosting) and my .htaccess looks like this.
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/something(.*)$ [NC]
RewriteRule ^(.*)$ /something/ [R=302,NC,L]
My problem is that when I'm on homepage (/) or any other page I'm redirected to /something/ which is correct but when I'm on /something/ I'm still beeing redirected to /something/ and it loops until ERR_TOO_MANY_REDIRECTS error shows up.
Here is a link to htaccess tester which shows that this should work and should not redirect me to /something/ when I'm already here but it is not the case on my hosting.
I was following this and this question but without success.
With your shown attempts, please try following set of rules. Please place them on top of htaccess rules file in case you already have existing rules.
Please make sure to clear your browser cache before testing your URLs.
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/?$
RewriteCond %{THE_REQUEST} !something [NC]
RewriteRule ^ /something? [R=302,NC,L]
You can try this rule with THE_REQUEST variable:
RewriteEngine On
RewriteCond %{THE_REQUEST} !\s/something [NC]
RewriteRule ^ /something/ [R=302,L]
Make sure to test it after completely clearing browser cache.
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. Example value of this variable is GET /index.php?id=123 HTTP/1.1

Apache redirect directive not acting as final rule

I am trying to achieve a simple redirect - from /news to /insights
I have the following in my .htaccess file:
redirect 301 /news /insights
<IfModule mod_rewrite.c>
RewriteEngine On
# Send would-be 404 requests to Craft
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>
Whenever I've used the redirect directive before, any matched URLs would be redirected and no further rewrites in the file would be processed. That is to say, going to /news would send you to /insights, and the rewrite to index.php would not be processed.
However, with this current setup, going to /news sends me to /insights?p=news, so for some reason the rewrite to index.php is still being processed.
Furthermore, if I comment out the index.php rewrite, then I get sent to /insights as expected.
This isn't how I've usually experienced this working so am unsure why it's doing this.
I have also tried the following:
RewriteEngine On
RewriteRule "^/news" "/insights" [R=301,L]
This simply results in a 404 instead of redirecting, which I also do not understand.
I am aware I could do the following:
RewriteEngine On
RewriteCond %{REQUEST_URI} "^/news"
RewriteRule ^ /insights [R=301,L]
which does work, however, I don't really want to have multi-line rewrites for lots of URLs, and would like to understand why the other 2 examples do not work.
You just need to insert this rule before last catch-all rule.
RewriteRule ^/?news/?$ /insights [R=301,L,NC]
Place it just below RewriteEngine On line so that mod_rewrite engine executed this rule before other rule.
Make sure to test it in a new browser.

Simple rewritecond in htaccess doesn't work as expected

This is super simple but it's driving me crazy! I have a website at http://example.org/ and a subdirectory at http://example.org/ccc/
I want to redirect anything outside of the /ccc/ directory to a different website.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/ccc/?.*
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
But this code doesn't work, it redirects the /ccc/ directory. According to my research and testing with this htaccess tester, it should not redirect because the RewriteCond is checking against /ccc with optional slash and other characters after it.
What is happening? Does this look correct?
Edit: This method from this answer is also not working, the CCC domain is being redirected:
RewriteEngine on
RewriteRule ^ccc index.php [L]
RewriteRule (.*) https://new-website.com/$1 [R=301,L]
PHP 5.4.45, Apache/2.2.31
Assuming ccc/ directory doesn't have a separate .htaccess, you may use this rule:
RewriteEngine on
RewriteCond %{THE_REQUEST} !\s/ccc[/?\s] [NC]
RewriteRule ^ https://new-website.com%{REQUEST_URI} [L,R=301,NE]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. An example value of this variable is GET /index.php?id=123 HTTP/1.1
It looks like [L] isn't behaving normally and I'm guessing it's the old version of Apache (2.2.31) because these rules worked on a separate website. I found this solution which seemed to work for this case, the third line below:
RewriteEngine on
RewriteRule ^ccc/? index.php [L]
RewriteCond %{ENV:REDIRECT_STATUS} != 200
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
Explanation from that question:
The problem is that once the [L] flag is processed, all the next RewriteRules are indeed ignored, however, the file gets processed AGAIN from the begin, now with the new url.
This magic Condition will not process the catch all if the file was already redirected.

mod_rewrite RewriteRule takes priority over Redirect in .htaccess

I have two different kinds of rules in my .htaccess file. The first group matches on exact files, and then I have a generic catch-all for everything else. I have read you can use the [L] for rewrite rules, but is there an equivalent for Redirect 301? For example, my .htaccess file looks like this:
Redirect 301 /exact_page.html http: //www.newsite.com/new_page1.html
Redirect 301 /some_other_page.html http ://www.newsite.com/new_page2.html
RewriteEngine on
RewriteRule ^(.*)$ http://www.newsite.com/$1 [R=301,L]
What I would like is for pages exact_page.html and some_other_page.html to be redirected exactly as shown, and everything else gets maps from the domain to the new domain, with the rest of the url intact. Instead, it looks to me like the first two Redirect 301's are being ignored, or more precisely, are being superseded by the final rule. Is there a way to tell apache to stop after it finds the first match?
I think something like this should work:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(exact_page\.html|some_other_page\.html)$
RewriteRule ^(.*)$ http://www.newsite.com/$1 [R=301,L]
RewriteRule ^exact_page\.html$ http://www.newsite.com/new_page1.html [R=301,L]
RewriteRule ^some_other_page\.html$ http://www.newsite.com/new_page2.html [R=301,L]

redirecting subdomain to subfolders not containing an index.php with .htaccess

i am getting a 500 internal server error with the following:
RewriteCond %{HTTP_HOST} ^data\.mysite\.com$ [NC]
RewriteRule ^(.*)$ data/$1 [L,QSA]
-----------------???
when i replace the RewriteRule line by the following:
RewriteRule ^(.*)$ data/index.php?r=$1 [L,QSA]
it works , but in real case i will not have an index.php in the folder, i will have folders containing images...
Any Idea??
original question here
Your rewrite rules are looping, each time the URI is rewritten, it is reapplied to all the rules until the rules don't change the URI. So when you request /something, the rewrite rule gets applied and the URI is changed to /data/something, then it is resent through the rewrite engine, then it gets rewritten to /data/data/something then /data/data/data/something etc. Eventually mod_rewrite will reach its recursion limit and return a 500 server error. You can try a few things to end the loop, assuming you really only want a single /data/ to be appended in the beginning. You can add one of the following before your RewriteRule
RewriteCond %{REQUEST_URI} ^/data
or
RewriteCond $1 ^/data

Resources