Removing www from URL and using directory-like URL's - apache

I have an issue removing the www from an URL. Also I want to use directory-like URL's (e.g. When I type www.foo.com/bar/baz into URL bar, it is converted into foo.com/index?page=bar&action=baz in the background and only in the background). But what I'm getting is that when I type in the URL with www and hit an Enter, I get back a foo.com/index?page=bar&action=baz in the URL bar. I only want foo.com/bar/baz to appear. (If I already wrote the URL without www, it's working fine.)
This is my code (only changed the original URL's):
RewriteCond %{HTTP_HOST} ^www\.foo\.com$ [NC]
RewriteRule (.*) http://foo.com$1 [L,R=301]
RewriteCond %{REQUEST_URI} !/index\.php
RewriteCond %{REQUEST_URI} !/Views/.*\.js
RewriteCond %{REQUEST_URI} !/Views/.*\.css
RewriteRule ^([^/]+)/([^/]+)(/[^/]+)* /index.php?page=$1&action=$2 [L,QSA]
RewriteCond %{REQUEST_URI} !/index\.php
RewriteCond %{REQUEST_URI} !/Views/.*\.js
RewriteCond %{REQUEST_URI} !/Views/.*\.css
RewriteRule ^([^/]+) /index.php?page=$1 [L,QSA]
So my question is obviously: What am I doing wrong and how can I make it work?

There may be some other Apache rules in play but from the look of it there may be an issue with slashes. It would be better if your first rule was this --
RewriteRule (.*) http://foo$1 [L,R=301]
Without the trailing slash. The reason for this is you will create a double // when redirecting www.foo.com/foo/bar. It will redirect to foo.com//foo/bar.
Your other rules should start with /, e.g. --
RewriteRule ^/([^/]+)/([^/]+)(/[^/]+)* /index.php?page=$1&action=$2 [L,QSA]
And --
RewriteRule ^/([^/]+) /index.php?page=$1 [L,QSA]

Related

htaccess issue with non-www redirect and trailing slash

I currently redirect all traffic to the www. version of my site. However, upon checking redirected links in a specific folder, I've noticed something that may / may not be an issue.
Basically, if I do a header check on www.example.com/example/examplepage/ it shows 200 OK.
If I check www.example.com/example/examplepage (without trailing /) it shows 301 redirect to the above as it should.
BUT, if I check example.com/example/examplepage/ (without www), it redirects to www.example.com/example/examplepage.php ... which then redirects to www.example.com/example/examplepage/ (the correct page).
I hope this makes sense?
a) is this OK?
b) am I missing something in my .htaccess?
RewriteOptions inherit
RewriteEngine On
RewriteCond %{THE_REQUEST} ^.*/index.htm
RewriteRule ^(.*)index.htm$ http://www.example.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteCond %{THE_REQUEST} \.php
RewriteRule ^tips/([^.]+)\.php$ http://www.example.com/example/$1/ [R=301,L]
RewriteRule ^tips/([^.]+[^./])$ http://www.example.com/example/$1/ [R=301,L]
RewriteRule ^(tips/[^.]+)/$ /$1.php [L]
Please note: the above PHP rule was created to "hide" .php extensions on a specific folder (didn't want them hidden anywhere else).
I managed to work it out (well, ok - got lucky guessing), but either way, it seems to work now. I've adapted the above rule order to show the following:
RewriteEngine On
RewriteCond %{THE_REQUEST} \.php
RewriteRule ^tips/([^.]+)\.php$ http://www.example.com/tips/$1/ [R=301,L]
RewriteRule ^tips/([^.]+[^./])$ http://www.example.com/tips/$1/ [R=301,L]
RewriteCond %{THE_REQUEST} ^.*/index.htm
RewriteRule ^(.*)index.htm$ http://www.example.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteRule ^(tips/[^.]+)/$ /$1.php [L]
This now results in:
http://example.com/tips/examplepage.php (and www version)
http://example.com/tips/examplepage - without trailing slash (and www version)
All finally redirecting to www.example.com/tips/examplepage/ (with trailing slash)
It also ensures www.example.com/examplepage.php (not within the "tips" folder) keeps it's extension.
It also re-writes index.htm to / (using both www and non-www).
I've tried to add as much detail here as possible in the hope it prevents someone else wasting an entire weekend pulling their hair out, going gray etc...

Redirection is not working with mod_rewrite in htaccess

I need to redirect few URIs having query string like:
/pages/foo.bar?pageId=123456 to http://some.site/spam/egg/
/pages/foo.bar?pageId=45678 to http://another.site/spaming/egging/
I have this in my htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=123456$
RewriteRule ^.*$ http://some.site/spam/egg/ [R=301,L]
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=45678$
RewriteRule ^.*$ http://another.site/spaming/egging/ [R=301,L]
But its not working, showing 404. What am i doing wrong?
You need to move these 2 rules i.e. before all other rules just below RewriteEngine On line as other rules might be overriding this.
(Based on your comments) Your culprit rule is this rule:
RewriteRule . index.php [L]
Which is actually rewriting every request to index.php and changing value of REQUEST_URI variable to /index.php thus causing this condition to fail:
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
From your example, you get redirected to
http://some.site/spam/egg/?pageId=123456
http://another.site/spaming/egging/?pageId=45678
You can use your browser developer tools to see the redirection (in the Network tab).
Maybe the query strings in the redirected URL lead to a 404? You can add a ? at the end of your redirection to clear the query string:
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=45678$
RewriteRule ^.*$ http://another.site/spaming/egging/? [R=301,L]

apache redirect to naked (non-www) domain messes up pages handler

all the urls in my website actually go through a PHP page that handles them by the page GET parameter (i.e. domain.com/sub/test is actually domain.com/page_handler.php?page=sub/test).
files or directories that exist don't go through the handler.
I've been trying to 301 redirect all www.domain.com requests to domain.com for improving SEO etc.
the problem is that this doesn't seem to work, no matter what rule I use and where I put it. this is the .htacess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#THIS IS THE DISCUSSED RULE:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteRule (.*[^\/])$ page_handler.php?page=$1 [QSA,NC,L]
RewriteRule ^/?$ page_handler.php?page= [L,QSA]
DirectoryIndex page_handler.php?page=
When I put the rule in the current line, it works ok with pages that are supposed to go through the handler BUT it makes existing resources go through it as well (e.g. domain.com/page_handler.php?page=js/script.js) which is not good.
When I put it after the other rules it redirects www.domain.com/something to domain.com/?page=something.
So, the question is: how to redirect urls that begin with "www." to the naked (non-www) domains without affecting the other rules?
Thank you!
The problem with your code is that you are applying the first two conditions only to the non-www rule. Conditions can only be tested for the rule that immediately follows them.
So, you'll need to move those down, and clean up a bit:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /page_handler.php?page=$1 [QSA,NC,L]
If this causes issues for you, then you may want to change the way your page is detected, by using the REQUEST_URI instead of a $_GET['page']. If you want to do this (which is actually a better method), the last rule can be changed to the following:
RewriteRule ^ /page_handler.php [QSA,NC,L]

.htaccess rewrite rule causes endless loop

I want my .htaccess file to redirect to some page if any wildcard as a subdomain entry hit the browser. i.e. I want
sam.xyz.com
To redirect to
sam.xyz.com/view.php?id=sam
I am using following rewrite rules for redirect.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.xyz.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+).xyz.com
RewriteRule ^(.*)$ /view.php?id=%1 [L,R]
Problem i am facing is that it does not shift to new domain keeping query string instead it generates an endless loop
sam.xyz.com
redirects to
http://sam.xyz.com/view.php?id=sam
But doesnt move to url above without endless loop.
Kindly help me out.
Thanks in advance,
you should add a condition for redirect to prevent redirection loop:
RewriteCond %{REQUEST_URI} !^/view\.php
the whole code would be:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.xyz.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+).xyz.com
RewriteCond %{REQUEST_URI} !^/view\.php
RewriteRule ^(.*)$ /view.php?id=%1 [L,R]
You are redirecting to: prefix.domain.tld/view.php?id=prefix
Ensure that the url does not contain: id=prefix.
This solution prevents, that someone call's the url: aaa.example.com/view.php?id=bbb
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.xyz.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+).xyz.com
RewriteCond %1::%{QUERY_STRING} !^([^:]+)::.*id=\1
RewriteRule ^ /view.php?id=%1 [L,R]
Note: (.*) in the rewrite rule is obsolete.
Leave the R away to do not redirect the visitor to the url (/view.php?id=%1)

mod redirect rule

I just want to redirect the URL through the mod rewrite ruls. I have applied this rule excluding (R=301)
Example :
from http:///webapp/wcs/stores/servlet/en/marksandspencer to http:///en/marksandspencer
I am using this rules for the mod redirect rules.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(/)?$
RewriteCond %{REQUEST_URI} !^/webapp.*$
RewriteCond %{REQUEST_URI} !^/wcsstore.*$
RewriteRule ^/(.*)$ /webapp/wcs/stores/servlet/$1 [PT,NC,L,QSA]
RewriteRule ^/webapp/wcs/stores/servlet/(.*) /$1 [NE,L,QSA]
RewriteRule ^(/)?$ /webapp/wcs/stores/servlet/en/marksandspencer [PT,NC,L]
No idea what you're trying to do, but if you're using Apache 2.0 or higher, the leading slash is stripped off of URI's when matching is done within a RewriteRule. Also, you have a rule that looks like you're adding a /webapp/wcs/stores/servlet/ to the beginning of a URI, then the very next rule it looks like you are removing it. This will probably cause a loop.
Taking a wild guess at what you are trying to do, I think you need to add a condition to the 2nd rule, and remove the leading slashes:
# internally rewrite URI by appending "/webapp/wcs/stores/servlet/" to the front
RewriteCond %{REQUEST_URI} !^(/)?$
RewriteCond %{REQUEST_URI} !^/webapp.*$
RewriteCond %{REQUEST_URI} !^/wcsstore.*$
RewriteRule ^(.*)$ /webapp/wcs/stores/servlet/$1 [PT,NC,L,QSA]
# if a request is made with "/webapp/wcs/stores/servlet/" in it, redirect to a URI with it stripped
RewriteCond %{THE_REQUEST} ^(GET/POST)\ /webapp/wcs/stores/servlet/
RewriteRule ^webapp/wcs/stores/servlet/(.*) /$1 [R=301,L,QSA]
RewriteRule ^$ /webapp/wcs/stores/servlet/en/marksandspencer [PT,NC,L]