Keep path when rewriting with .htaccess - apache

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]

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]

https rules for htaccess including www redirect and removal of ".html" extensions

Currently my .htaccess looks like this and works perfect for http.
It redirects to www. and removes the .html file extension.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
I have tried the .htaccess from this answer but still the site in question is completely messed up. E.g https://example.com/work shows a 404.
Also all images that are linked in the source code with /img/example-01.jpg do not show.
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Can you please help me with getting a .htaccess file that:
1.
Redirects to https
2.
Redirects to www. subdomain
3.
Removes .html from file extension so that example.com/work shows the work.html page.
Thank you for your help.
If your current .htaccess works fine, this modification should do:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [OR]
RewriteCond %{REQUEST_SCHEME} !https
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]

How can I set the RewriteCond for the exact URL only?

I need to make a hidden redirect from sitename.dom to sitename.dom2 keeping the rest of string untouched.
For now I use:
RewriteCond %{HTTP_HOST} ^sitename.dom
RewriteRule ^(.*) http://sitename.dom2/$1 [P]
and it works perfectly. But. Due to multilanguage on my website the frontpage has the following path:
sitename.dom2/lang
thats why when user calls sitename.dom he is being redirected (hidden) to sitename.dom2/ and he's getting 404 page.
So, please advise how do I make a strict redirect for exact request only sitename.dom without any further?
I had tried
RewriteCond %{HTTP_HOST} ^sitename\.dom$
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*) http://sitename.dom2\/lang [P]
with no luck.
BTW, inside the website language subpath doesn't affect at all. sitename.dom/lang/page works as good as sitename.dom/page
I had to add the single redirect before all other. And use dom2 instead of dom1 in this rule.
Here is the solution:
RewriteEngine On
#redirect front page only:
RewriteCond %{HTTP_HOST} ^sitename\.dom2$ [OR]
RewriteCond %{HTTP_HOST} ^www\.sitename\.dom2$
RewriteRule ^/?$ "http\:\/\/sitename\.dom2/\lang" [L]
#redirect all other pages:
RewriteCond %{HTTP_HOST} ^sitename\.dom2
RewriteRule ^(.*) http://sitename\.dom1\/$1 [P]
Simply add /lang in your first RewriteRule directive:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^sitename.dom$
RewriteRule ^ http://sitename.dom2/lang%{REQUEST_URI} [P]

How to stop htaccess rewrite rule updating browser URL

I've read through many of the similar requests such as:
Apache rewrite rule - prevent rewritten URL appearing in browser URL bar
But I can't figure out what I'm doing wrong, any help would be much appreciated.
I'm using codeigniter 3 and it's root is at the following location:
https://example.com/api/v1.0
I've set up a basic route and all is working fine with Codeigniter E.g. If I navigate to:
/api/v1.0/index.php/pages/view/about
the appropriate page appears so all seams well. What I really want is for the URL to get rewritten so that when I enter:
/api/v1.0/pages/view/about
it goes to the same page. I've added a htaccess file that rewrites the rule and all works as expected:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /api/v1.0/
RewriteCond $1 !^(index.php|resources|robots.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
The problem is, when I enter the the url:
/api/v1.0/pages/view/about
it goes to the correct page, but the browser URL gets updated to:
/api/v1.0/index.php/pages/view/about
My question is, how can I stop the browser URL from being updated?
Update - my web servers site behind an AWS ELB that acts as the https end point. I have the following in the httpd.conf to ensure that any non 'www' prefixed URLS and any http calls are redirected to https://www
<VirtualHost *:80>
RequestHeader set X-Forwarded-Proto "http"
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{REQUEST_URI} !^/_hostmanager/
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^test\. [NC]
RewriteCond %{HTTP_HOST} !^signup\. [NC]
RewriteCond %{REQUEST_URI} !^/_hostmanager/
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
I don't think this rule is causing an issue as its not being invoked, I'm providing the correct prefix and protocol.
Many thanks in advance,
Rob
Check that index.php isn't set for $config['index_page'].
If it is change it to:
$config['index_page'] = '';
OK, after much testing it would appear that my virtual host settings in httpd.conf were causing the issue. If I removed these rules and then the local .htaccess rules worked exactly as expected.
I've removed the local .htaccess rules and added the following to rule to httpd.conf:
RewriteRule ^/api/v1\.0/([A-Za-z0-9-/]+)/?$ /api/v1.0/index\.php/$1 [NC,L,QSA] # Process API Call
My Virtual Host section now looks like this:
RequestHeader set X-Forwarded-Proto "http"
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{REQUEST_URI} !^/_hostmanager/
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^test\. [NC]
RewriteCond %{HTTP_HOST} !^signup\. [NC]
RewriteCond %{REQUEST_URI} !^/_hostmanager/
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^/api/v1\.0/([A-Za-z0-9-/]+)/?$ /api/v1.0/index\.php/$1 [NC,L,QSA] # Process API Call
So now calls to:
/api/v1.0/some/directory
Will get rewritten to this:
/api/v1.0/index.php/some/directory
And this happens without redirecting the browser or affecting the browser URL. What I don't understand is why this is not entering into an infinite loop as I have no rewrite precondition to check for calls to the /api/v1.0/index.php/*
Anybody know why this is no entering into an infinite loop?

Apache, url rewrite

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