Apache, url rewrite - apache

I have the following .htaccess file inside my root directory:
RewriteEngine On
<If "%{SERVER_NAME} = 'example.com'">
# The actual condition is really long one so I replaced it for illustration.
RewriteCond %{HTTP_USER_AGENT} (iPhone|Blackberry|Android) [NC]
RewriteRule .* http://m.example.com%{REQUEST_URI} [R,L]
RewriteCond %{REQUEST_URI} ^/([a-z-]+)/$ [NC]
RewriteRule .* %{REQUEST_SCHEME}://%{SERVER_NAME}/?title=%1 [L]
</If>
<Else>
RewriteCond %{REQUEST_URI} ^/([a-z-]+)/$ [NC]
RewriteRule .* %{REQUEST_SCHEME}://%{SERVER_NAME}/?title=%1 [L]
DirectoryIndex /m/index.htm /m/index.php /m/index.html
</Else>
So as you can see its a pretty much simple way to redirect users of mobile devices to m.example.com and if that is the case I change the DirectoryIndex, few notes:
The reason I duplicate the same RewriteCond/RewriteRule is because I can't use them outside <If>/<Else> blocks.
The way I redirect(if/else) is not the question and I'm pretty sure not the best way, but if anyone have suggestions I'm all ears.
The problem:
If I access example.com/Article-Name on desktop browser there will be internal redirection to: example.com/?title=articleName but I won't see example.com/?title=articleName at my url bar as expected.
The exception:
If I access m.example.com/Article-Name my url bar is now m.example.com/?title=articleName.
I was expecting the same behavior as the desktop (internal redirection not redirection I can see on my url bar), I'm pretty sure its because the DirectoryIndex but I don't how to prove it or solve this issue, if anyone have a solution I will be very thankful.

The main issue with your code is that you're feeding it with an URL that is not the same as the current URL then, what happens is that it ignores the internal and make it an external redirect.
Another very important thing is that you forgot %{HTTP_USER_AGENT} to match against the mobile browsers.
Here is an idea to resolve your issue:
RewriteEngine On
# First we verify if its a mobile device and
# if its not already on the mobile subdomain
RewriteCond %{HTTP_HOST} !^m\.domain\.com$ [NC]
RewriteCond %{HTTP_USER_AGENT} (iPhone|Blackberry|Android) [NC]
RewriteRule ^ http://m.example.com%{REQUEST_URI} [R,L]
# here we deal with all the internal redirects for
# the mobile subdomain
RewriteRule ^m/index\.php$ - [L]
RewriteCond %{HTTP_HOST} ^m\.domain\.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /m/index.php?title=$1 [L]
# here we deal with the normal website
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /index.php?title=$1 [L]

Your doing internal redirects, if you want to redirect to a new URL use external ones
Replace [L] with [L,R=302]
or 301 if you want the result to be cached

Related

htaccess error on redirect - too many redirects

I'm trying to redirect all requests from one domain (domain.co.in) to another domain (domain.info.in). I've tried Rewrite directives and Redirect directive in htaccess, but getting too many redirects error in browser. Below is the configuration I'm trying to implement.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.co\.in [NC]
RewriteRule ^(.*)$ index.php/$1
RewriteRule ^(.*)$ http://domain.info.in/$1 [R,L]
My actual working htaccess configuration is
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php/$1
Using this, I'm able to redirect all requests to index.php and working fine. But when I add domain rewrite rules, I'm getting the redirect error. I've tried Redirect directive also,
Redirect 302 / http://domain.info.in/index.php/$1, but same error.
I tried the Fiddler tool mentioned in this post, Tips for debugging .htaccess rewrite rules. There it is working good.
Actually, I want to redirect all requests (www.domain.co.in, domain.co.in, www.domain.info.in) to domain.info.in
Any suggestions on this?
As per #CBroe's suggestion, I've updated the configuration and it works. As he said,
RewriteConds always affect the directly following rule.
And I've also added negation to the checking to redirect all other requests.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^domain.co.in$ [NC]
RewriteRule ^(.*)$ http://domain.info.in/$1 [R,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php/$1 [L]

.htaccess redirect facebook crawlers except privacy policy

I have a SPA app with dynamic content for sharing on Facebook so I am redirecting Facebook crawlers to a nice static page using the following rule in htaccess:
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
This works great! But there is one problem... I can't make my app live because Facebook requires a link to privacy policy, terms and conditions etc - and these get redirected too!!
I need to ignore a certain URLs - anything requested in /docs/ - from the above rule EDIT: so that urls containing /docs/ are followed as normal (no redirect, just served normally). I can't get .htaccess to pick up on the ignore rule. I would have thought this would do it (with thanks to https://stackoverflow.com/a/1848579/4881971):
RewriteRule ^(docs)($|/) - [L]
so I would have thought my .htaccess file would look like this :
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$
RewriteRule ^(docs)($|/) - [L]
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
but when I use Facebook Object Debugger on https://mysite.tld/docs/privacy I get a 404! It redirecting to https://sharing.mysite.tld/api/share/docs/privacy
How do I retain the rule but ignore requests from mysite.tld/docs/* ? Thanks.
Could you please try following, please make sure you clear your browser cache before testing your URLs. This considers your uri starts from docs.
<IfModule mod_rewrite.c>
RewriteEngine ON
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$ [NC]
RewriteCond %{REQUEST_URI} ^/docs [NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
In case you want to pass URLs where docs could come anywhere in uri(not from starting what 1st solution looks for), then try following Rules.
<IfModule mod_rewrite.c>
RewriteEngine ON
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$ [NC]
RewriteCond %{REQUEST_URI} docs [NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
Have it like this with a negated comdition:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit [NC]
RewriteRule %{THE_REQUEST} !\s/+docs [NC]
RewriteRule ^ https://sharing.mysite.tld/api/share%{REQUEST_URI} [L,R=301,NE]

Apache rewrite "domain.com/folder" to "folder.domain.com" with keeping redirection from "folder.domain.com" to "domain.com/folder"

I want folder.domain.com to point at domain.com/folder
and
I want domain.com/folder to be rewritten in the URL of page in the browser to folder.domain.com.
In both cases I want to see an URL like this folder.domain.com.
Tried:
Redirect 301 /subdomain http://subdomain.example.com
Neither work:
RewriteCond %{THE_REQUEST} ^GET\ /ucp/profile\.php?([^=]+)=(\S+) [NC]
RewriteRule ^ucp/profile\.php$ /ucp/%1/%2? [R=301,L,NC]
# Now, deal with internal rewrites (which will not cause redirection):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ucp/([^/]+)/([^/]+)/?$ /ucp/profile.php?$1=$2 [NC,L]
enter code here
And many many more.
Is it even achievable?

Keep path when rewriting with .htaccess

I recently moved my webpage from HTTP to HTTPS and I now got a couple of things that doesn't work like before.
The problem I'm having is that when a user is trying to go to:
http://example.com/i/<imageID> they are redirected to:https://www.example.com/i/image.php?id=<imageID>. This is "correct", but not what I want. I want the links to stay at /i/<imageID> regardless of the user came from http or https.
I have two .htaccess-files that I use to control this redirection on my webpage.
First .htaccess (root directory):
RewriteEngine on
RewriteOptions inherit
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Second .htaccess (image directory - /i):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^=]+)$ image.php?img=$1 [NC,L]
This redirection was working just fine before I added the first .htaccess-file that redirects the user from HTTP to HTTPS, but now it seems to be broken.
I'm not that familiar with htaccess-files so I hope someone out there can help so I can get my clean URLs back. :)
UPDATED ANSWER --> updated again
%{REQUEST_URI} only includes the URI WITHOUT the querystring. But this is stored in and can be retrieved in another variable --> %{QUERY_STRING}
I edited the code accordingly for the first .htaccess-file
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI}%{QUERY_STRING} [L,R=301,QSA]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}%{QUERY_STRING} [L,R=301,QSA]
If you change your second .htaccess file to the following, it should be clean :)
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/i/image.php
RewriteRule ^/i/(.*) /i/image.php?img=$1 [P,NC,L,QSA]
The [P] stands for 'proxy' meaning that your Apache is seen by the client as a proxy (ofc, without his notice), because your Apache executes the actual (correct) request, while the client only sees the result.
My new take on your problem
RewriteCond %{HTTP_HOST} ^(www\.)?(.*)$
RewriteRule ^(.*)$ https://%2$1 [R=Permanent,L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^=]+)$ image.php?img=$1 [NC,L]

htaccess issue causing internal server error too many redirects

so I am playing with .htaccess to have clean URLs in my codeigniter app.
in short, i am trying to:
1) remove index.php in urls (redirect permanent)
http://localhost/directory/index.php*
to
http://localhost/directory/*
http://my.domain.com/index.php*
to
http://my.domain.com/*
2) rewrite requests for certain controllers to index.php/[controller_name]
http://localhost/directory/controller1*
to
http://localhost/directory/index.php/controller1*
http://my.domain.com/controller2*
to
http://my.domain.com/index.php/controller2*
my htaccess file currently goes like this:
Options +FollowSymlinks
RewriteEngine On
#RewriteBase /
# Redirect index.php
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{THE_REQUEST} !/system/.*
RewriteRule ^(.*)index\.php((/)(.*))?$ /$1/$4 [R=301,L]
first issue:
this does not work for http://localhost/dir/index.php/controller1.
instead redirecting to http://localhost/dir/controller1, it redirects to http://localhost//controller1 ($1 return empty string?)
# Rewrite CI certain controllers
RewriteCond %{THE_REQUEST} directory/(home|other_controller) [NC]
RewriteRule ^(.*)(home|other_controller)(.*)$ /$1index.php/$2$3 [NC,L]
second issue:
this does not work for http://localhost/dir/home gives internal server error (too many redirects).
but if I test added R=301 code, it successfully redirect to http://localhost/dir/index.php/home. but this is not my intention to redirect, I only need to rewrite it.
please advise.. :)
Try with this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
You can place this in the directory the bootstrap file (index.php) is in.
If you have FastCGI implementation, you need to add a question mark in the rewrite rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]