htaccess and forward one url to another - .htaccess

I have this rewrite code:
RewriteCond %{HTTP_USER_AGENT} ^.*iPhone.*$
RewriteRule ^(.*)$ http://stagingsite.com/site/mobile [R=301]
RewriteRule ^faq/$ /mobile/faq
The first line is working correctly. If the user is on an iphone then redirect to the mobile directory where the index page is displayed.
I also want users visiting:
http://stagingsite.com/site/faq
to get forwarded to http://stagingsite.com/site/mobile/faq if they're on an iphone but the last line of code above doesn't seem to be achieving this.
Any ideas what I have wrong?

RewriteCond directives only get applied to the *immediately following RewriteRule. So you have the condition that checks for iPhone, but that only gets applied to the redirect rule, and not the faq rule. You have to duplicate it:
RewriteCond %{HTTP_USER_AGENT} ^.*iPhone.*$
RewriteRule ^(.*)$ http://stagingsite.com/site/mobile [R=301,L]
RewriteCond %{HTTP_USER_AGENT} ^.*iPhone.*$
RewriteRule ^faq/?$ /site/mobile/faq [L]
You should also include L flags so the 2 rules don't accidentally interfere with each other. And your regex and target needs to be updated to accept an optional trailing slash and the subdirectory.

taking out the slash before mobile as
RewriteRule ^faq/$ mobile/faq
works?

Related

RewriteRule in .htaccess and Reverse Proxy

Here is my problem, I`m struggling with it for a few days.
We`ve got a domain firstpart.maindomanin.com nad subdomain secondpart.maindomain.com.
Under first domain there is a first part of the project (based on SaaS commerce) and second part (under secondpart.maindomain.com) - based on Symfony. Those two parts are connected through SOAP services etc.
For firstpart.maindoman.com we are using Cloudflare.
We`ve got reverse proxy so:
firstpart.maindomain.com/uk/made is pointed to secondpart.maindomain.com/uk
and now (we cant enable cloudflare secondpart.maindomain.com due to some unrelated issues) we want to redirect all url-s from secondpart.maindomain.com/uk to firstpart.maindomain.com/uk/made
so for example
secondpart.maindomain.com/uk/furniture to firstpart.maindomain.com/uk/made/furniture
secondpart.maindomain.com/uk/sales to firstpart.maindomain.com/uk/made/sales
etc.
so we need to change domain and add 'made' between language code and rest of url
Other than that we need to redirect all urls like
firstpart.maindomain.com/uk/furniture to firstpart.maindomain.com/uk/made/furniture
(add 'made' between language code and rest of url)
and we need to do it in htaccess under subdomain secondpart.maindomain.com.
I came up with something with:
RewriteCond %{HTTP_HOST} secondpart.maindomain.com$ [NC]
RewriteRule ^([a-z]{2,3})(.*)$ http://firstpart.maindomain.com/$1/made$2 [R=301,L]
and for url like
secondpart.maindomain.com/uk/furniture
I`m getting redirection to
http://firstpart.maindomain.com/uk/made/furniture
which is fine but after redirection there is infinite loop (so except changing urls is not working)
As it turned out HTTP_HOST for both firstpart.maindomain.com/uk/made and secondpart.maindomain.com/uk is the same and it is secondpart.maindomain.com so condition is not working.
I came up also with condition like
RewriteCond %{REQUEST_URI} !^made [NC]
RewriteRule ^([a-z]{2,3})(.*)$ http://firstpart.maindomain.com/$1/made$2 [R=301,L]
so condition is not met if there is a word 'made' inside URI and in this case it is the same as in first rule.
I tried several different configurations but nothing is working.
When i tested it with http://htaccess.madewithlove.be/ everything was fine and there was not redirection.
So im assuming there is something with reverse proxy on cloudflare.
Im not an expert in htaccess but really i tried a lot of solutions and nothing is working.
I would really appreciate some help with it.
P.S. Just in case here is a .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^([a-z]{2,3})(.*)$ http://vendauat.lauraashley.com/$1/made$2 [R=301,L]
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteRule .? %{ENV:BASE}/app.php [L]
</IfModule>
This condition:
RewriteCond %{REQUEST_URI} !^made [NC]
will always be met because your regex pattern says: if the request never starts with made, but the %{REQUEST_URI} variable always starts with /. Maybe what you want is this instead:
RewriteCond %{REQUEST_URI} !^/[^/]+/made/

Htaccess - Rewrite engine (reverse engineering a line of code)

On a site I'm working on, if you enter the url, plus 1 directory, the htaccess adds a trailing slash.
So, this: http://www.mysite.com/shirts
Becomes this: http://www.mysite.com/shirts/
The htaccess that runs the site is quite long and complex, so it's not easy to find or test which rule is causing the rewrite. I was able to track down the issue to this line of code (I think):
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
Does this rule match the behavior I'm describing above? It seems to be the cause, but it doesn't make logical sense to me. I don't unsderstand where the trailing slash is coming from.
Can someone shed some light on this for me? Thanks in advance.
Edit: MORE:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^mysite\.com$
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
By default apache will add the ending /, you will have to use:
DirectorySlash Off
To disable that behavior which is caused by mod_dir, you can read more about it here.
However if you're trying to remove the / to fix images not showing. That is not the right way to do it, you should instead use the HTML base tag, for example:
<BASE href="http://www.yourdomain.com/">
Read more here about it.
Your current rule as you have updated on your question:
RewriteCond %{HTTP_HOST} ^mysite\.com$
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
Means:
if domain on the URL is only mysite.com
redirect current URL to domain with www.
So an example of it would be, if you access:
http://domain.com/blog/some_blog_article
It will redirect the user to:
http://www.domain.com/blog/some_blog_article
Note how it retains everything and only add the www. to the domain.
If you really want to redirect it regardless here is one way to do it:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
# check if it is a directory
RewriteCond %{REQUEST_FILENAME} -d
# check if the ending `/` is missing and redirect with slash
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]
# if file or directory does not exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# and we still want to append the `/` at the end
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]

Set up of conditional redirect in htaccess

I've been asked to make an existing web site multi-language.
In preparation for this I have had to move all existing pages from /path/page to /en/path/page
To maintain any existing incoming links I now need to set up an htaccess redirect to send any requests from their original urls to the new /en/path/page urls but I'm having trouble getting this to work.
This is what I currently have;
RewriteCond %{REQUEST_URI} !^/en$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
Which I think is meant to check the requested URI and if it doesn't begin with /en then prepend /en onto the requested URI... but I'm obviously mistaken since it doesn't work.
Any help appreciated. Thank you.
UPDATE.
Since this is an ExpressionEngine site and there is an additional rule to remove the index.php portion of the URL here are both rules
# Rewrite for new language based urls
# This is to try and get all current pages going to /en/(old url) with a 301 redirect
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
# Removes index.php
RewriteCond $1 !\.(gif|jpe?g|png|ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
I have also tried this with the language rewrite after the index.php one. I'm still getting stuck in loops.
What it does is, checking whether the URI is not exactly /en, since the $ indicates the end of the string right after en.
Try this, it checks whether the URI is not exactly /en or /en/ or doesn't start with /en/, and if that's the case it will prepend /en/:
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
update Considering the other rules you have in your .htaccess file, it is necessary to have the language rule not match again for the following internal redirect to /index.php..., otherwise you'll end up with an endless loop.
There may be better ways to prevent this, however the first thing that comes to my mind would be checking for index.php in the first condition:
RewriteCond %{REQUEST_URI} !^/(index\.php|en)(/.*)?$
So this will cause the rule not to apply after the internal redirect. But be careful, this solves the problem for this specific case only in which the internal redirect goes to index.php!

ModRewrite in htaccess sends me to the full path

I have got those two rules:
RewriteCond %{HTTP_USER_AGENT} iPhone [NC]
RewriteRule ^categories$ home.php?categories=1[L,NC,PT,R=301]
RewriteRule ^featured$ home.php?featurez=1 [L,NC,PT,R=301]
The problem is that teh categories work and the featured doesnt work.
works:
http://apps.com/iphone/categories
doesnt work:
http://apps.com/iphone/featured
The second rule that doesnt work sends me to here
http://apps.com/var/www/vhosts/apps.com/httpdocs/iphone/home.php?featurez=1
It seems to send me the root of the root of my directory and that whole thing is prefixed with the root of my site..why?
How is that possible.
Rewrite conditions only apply to the immediately following rule, so your condition doesn't apply to the "featured" rule at all. You'll have to duplicate it.
Apache tries to guess whether the target of a rule is a URL-path or a file-path, and it's guessing incorrectly. You can try to fix it by either including a rewrite base or make your targets absolute URL-paths.
I've already answered this in your previous question using either of those solutions will fix the file-path appearing in the redirect.
RewriteBase /iphone/
RewriteCond %{HTTP_USER_AGENT} iPhone [NC]
RewriteRule ^categories$ home.php?categories=1[L,NC,PT,R=301]
RewriteCond %{HTTP_USER_AGENT} iPhone [NC]
RewriteRule ^featured$ home.php?featurez=1 [L,NC,PT,R=301]
or
RewriteCond %{HTTP_USER_AGENT} iPhone [NC]
RewriteRule ^categories$ /iphone/home.php?categories=1[L,NC,PT,R=301]
RewriteCond %{HTTP_USER_AGENT} iPhone [NC]
RewriteRule ^featured$ /iphone/home.php?featurez=1 [L,NC,PT,R=301]

Creating a mod_rewrite rule in an htaccess file

I am trying to create a mod_rewrite rule to direct people to a sub-folder. Currently the code looks as follows:
RewriteEngine On
RewriteCond %{HTTP_HOST} abcsite.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^!www\.abcsite\.*$
RewriteCond %{REQUEST_URI} !^/abc/.*$
RewriteRule (.*)$ /abc/$1 [L]
The redirect works if the user types www.abcsite.com, but not if they type abc.com. Is there something that I am missing or should do differently to make sure the user goes to the correct folder (regardless of how they type the URL)?
Side note: The htaccess file that I am dealing with is a Joomla file, so all contents of it deal with another Joomla site. I appreciate the help.
Because you have conditions for that.
RewriteCond %{HTTP_HOST} abcsite.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^!www\.abcsite\.*$
RewriteCond %{REQUEST_URI} !^/abc/.*$
All above rules will pass only its abcsite.com
You add following rules also then it work for abc.com too.
RewriteCond %{HTTP_HOST} abc.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^!www\.abc\.*$
RewriteCond %{REQUEST_URI} !^/abc/.*$
RewriteRule (.*)$ /abc/$1 [L]
There's a stray ! in your second condition. A ! in front of the pattern means that the condition is true when the regex doesn't match (like in the third condition). A ! inside the pattern is just a literal symbol.
The host conditions should be something like:
RewriteCond %{HTTP_HOST} ^abcsite\.com$ [OR,NC]
RewriteCond %{HTTP_HOST} ^www\.abcsite\.com$ [NC]
And in fact, they can be joined into a single condition (note, no [OR] here):
RewriteCond %{HTTP_HOST} ^(www\.)?abcsite\.com$ [NC]
Your third condition is intended to prevent redirect loops (/foo → /abc/foo → /abc/abc/foo → …). What it says is that the rule isn't applied if the request URL starts with /abc/. However, your actual redirect is an internal redirect: if a user accesses abcsite.com/foo, the server internally rewrites this to /webroot/abc/foo, but REQUEST_URI stays the same, /foo.
The reason this doesn't cause a redirect loop as it is is likely rewrite rules in abc/.htaccess which override this one once the redirect is done.
What should be checked instead in the third condition is the path matched by the rewrite rule:
RewriteCond $1 !^abc/
RewriteRule (.*) /abc/$1 [L]

Resources