htacces redirect and mask - .htaccess

How would I redirect from the root folder to a sub folder and then mask that folder?
So instead of http://root.com/sub_folder
It would be just http://root.com
I have tried:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^root\.com$
RewriteRule (.*) http://root.com/$1 [R=301,L]
RewriteRule ^$ /sub [L]
However, that does not work. Any help will be welcome.

To clarify what I think you're looking for:
You want users who enter http://root.com with no trailing path to be rewritten silently to http://root.com/sub.
If a user directly enters http://root.com/sub, however, you want them to be redirected to http://root.com.
Any other path within root.com should be left alone.
The following two rules accomplish this. If you have more than one domain and only want this to apply to one domain, add your original RewriteCond in front of each RewriteRule.
RewriteRule ^sub/?$ http://root.com/ [R=301,L]
RewriteRule ^$ /sub [END]
First rule redirects /sub with or without trailing slash to root.com. Second rule rewrites base domain to /sub.
EDIT: Per Jon Lin's comment, below, the [L] flag only stops the current round of processing and internal rewrites are sent through the rules once more (I always forge that part). So, you can terminate the second line with [END] instead, which stops all rewrite processing. The catch is that [END] is only available in Apache 2.4 or higher, so if you're on an older version something trickier will need to be done.

Related

Two rules at the same time and their order

I have aim to use two domains (old and new). So when I go to address:
http://old.cz/whatever/whatever
I would like to get to:
http://new.cz/whatever/whatever
Perfectly works for me this thing:
RewriteRule ^(.*)$ http://www.new.cz/$1 [R=301]
But! At the same time I want following. When I go to address:
http://old.cz/
I want to get to:
http://new.cz/specific-page/specific-page
For that works this code:
Redirect 301 / http://new.cz/specific-page/specific-page
My issue is that in case I use both rules at the same time the first one is always prioritize and the second one suppressed. It means that when I go to http://old.cz/ I always get on only to http://new.cz/
Help me please.
Redirect and RewriteRule are directives of two different apache modules mod-alias and mod-rewrite . You can not combine these two directive for url redirection because of their different runtime behaviour. Use RewriteRule instead of Redirect.
RewriteEngine on
RewriteRule ^/?$ http://new.cz/specific-page/specific-page [L,R]
RewriteRule ^(.*)$ http://www.new.cz/$1 [R=301]

.htaccess Redirect + Rewrite in one rule

I have a rewrite rule to hide index.php, which is
working fine.
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
I am currently redirecting a specific sub-domain to another domain.
RewriteCond %{HTTP_HOST} ^(www\.)?deutschland\.example\.com$ [NC]
RewriteRule ^ http://www.example.de%{REQUEST_URI} [NE,R=301,L]
The redirect is working fine, but now I am getting index.php in the URL too, which is coming in the REQUEST_URI.
http://www.example.de/index.php/search/result
So how to remove 'index.php' from this redirected URL?
Note: Its the same php website application only, just using country-wise multiple domains.
(1) Rule order is important. (2) the last flag doesn't mean last; it means last on this cycle. (From Apache 2.4 the end flag does what you might think last does. See my Tips for debugging .htaccess rewrite rules for more discussion of this). So in this case rule(1) fires and then mod_rewrite loops around again and this time rule (2) fires giving what you find.
Swap the two rules around and it will work as expected.

htaccess rewriterule, [R,L=301] flags does not stop it. Why?

The beginning of .htaccess is
RewriteEngine On
#begin of rules for administration folder, redirect to https, if not https
RewriteCond %{REQUEST_URI} ^/administration
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L=301]
#end of rules for administration folder
#===no rules for /administration folder below this line===
#the rest part of .htaccess
Why does the rest part of .htaccess still performs for https://www.mydomain.com/administration/index.php ? How to stop the performing of the rest part of .htaccess file for urls that follow to administration folder? What's wrong in my code?
Thank you.
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Add this line on top of your .htaccess file:
RewriteRule ^administration - [NC,L]
I had simmilar issue these days and I got a really interesting answer from the user DaveRandom in the PHP chat:
"Basically, mod_rewrite effectively runs in a loop (this isn't really true but effectively that's what it does) and the [L] flag is like a "continue" statement in PHP (it stops processing the rules below in the current iteration but it will then start processing the rules again from the top). So in your rules, the first iteration was matching the first rule, and then the second iteration skipped the first rule (it produced the same output as the input) and then matched the second rule."
Possible Solution: "if you are using apache 2.4 using [END] instead of [L] would be a fix".
It is because you have syntax error. .htaccess will ignore erroring lines
Change this:-
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L=301]
To this:-
RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301]

How to write in htaccess file to force trailing slash and www at the same time

Im trying to implement 2 rules
1) Forced www.
I have got it working by doing
RewriteCond %{HTTP_HOST} ^domain.com
RewriteRule (.*) http://www.domain.com/$1 [R=301,L]
2) Add trailing forward slash on all urls
I got this far by doing this
RewriteCond %{HTTP_HOST} ^domain.com
RewriteRule (.*) http://www.domain.com/$1/ [R=301,L]
and then I ran into a problem,
type url
1) www.domain.com --rewrites to--> http://www.domain.com/ ---Desired Result
2) domain.com --rewrites to--> http://www.domain.com// ---Undesired Result
3) domain.com/location1 --rewrites to--> http://www.domain.com/location1/ ---Desired Result
4) www.domain.com/location1 --rewrites to--> http://www.domain.com/location1 ---Undesired Result
How can I write it so that i get these 2 rules working?
this rule will redirect all visits without the www:
RewriteCond %{HTTP_HOST} ^domain.com
RewriteRule (.*) http://www.domain.com$1 [R=301]
See that I removed the flag to make it the last rule.
and the second one to put the trailing slash:
RewriteRule (.*[^/])$ $1/ [R=301,L]
It won't redirect when the URL already ends in a slash. You'll get 2 redirects when someone visits a page without the www and without the slash. If you just want to do this due to search engines, it is fine. If your own site often point to a URL like this, you'll need another regexp.
If SEO is your motive, also take a look to canonical URLs
try putting the add slash part before the www part - should work fine.
I've never used this directive, but two thoughts that may be helpful come to mind:
Your original patterns do nothing to exclude URLs that already end with a slash. I think you need a pattern more like
^domain.com.*[^/]
Otherwise URLs that end with a slash pass, and so another slash is added.
Why are you doing this, anyway?
Why change the host name to add the "www"? If the request is making it to your server, then with or without the www, it made it, so why do you care? If the request is not making it to your server, then your rules will never be applied anyway, as of course . I was thinking that maybe your example is oversimplified, maybe in real life you're redirecting to a different server. But in that case, why would you care what the original host name was at all? Just fill in the host name you need.
Why add the slash? Apache servers automatically add the slash if the name turns out to be a directory anyway. You can't have a file and a directory with the same name, so at most this would just change the error message on not-founds.

Force removal of index.php with .htaccess

I'm currently using the following to rewrite http://www.site.com/index.php/test/ to also work directly with http://www.site.com/test/, but I would like to not only allow the second version, I would like to FORCE the second version. If a user goes to http://www.site.com/index.php/test/ it should immediately reroute them to http://www.site.com/test/. index.php should never appear in a url. Stipulation: this should only apply to the first index.php. If I have a title like http://www.site.com/index.php/2011/06/08/remove-index.php-from-urls/ it should leave the second index.php, as it is part of the URL.
Current rule that allows but does not force:
#Remove index.php
RewriteCond $1 !^(index.php|images|css|js|robots.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Thanks.
As you wrote, if a user goes to http://www.site.com/index.php/test/ this rule will imediately reroute him to http://www.site.com/test/
RedirectMatch 301 /index.php/(.*)/$ /$1
I'm not sure if that is what you need as your current rewrite rule is opposite to mine.
First (and wrong) answer - see below
You can accomplish a redirection with these directives (in this order):
RewriteCond %{REQUEST_URI} ^index.php
RewriteRule ^index\.php/(.+)$ /$1 [R,L]
RewriteCond $1 !^(index.php|images|css|js|robots.txt)
RewriteRule ^(.*?)$ /index.php/$1 [L]
That will first redirect all the requests that begin with index.php to the corresponding shortened url, then silently serve index.php/etc with the second rule.
EDIT - Please read on!
In fact, the solution above generates an infinite redirection loop, because Apache takes the following actions (let's say we request /index.php/abc):
first RewriteCond matches
Apache redirects [R], that is, generates a new HTTP request, to /abc
/abc fails first RewriteCond
/abc matches second RewriteCond
Apache does not redirect, but rewrites this URI (so it makes an "hidden" request), to /index.php/abc . We are again at point 1, that's a loop.
Please note...
By using the [L] (last rule) flag, we can only tell Apache not to process more rewrite rules, but only if the current rule matches. Since a new HTTP request is made, there is no information about how may redirection we have been through yet. So, any time one of the two matches, and in any case it generates a new request (=>loop)
Using the [C] (chain rules) flag is kinda pointless because it makes Apache process a rule only if the previous rule matches, while the two rules we have are mutually excluding.
Using the [NS] (not if subrequest) flag on rule #1 is again not an option because it aƬsimply does not apply to our case (see Apache RewriteRule docs about it)
Setting env variables is not an option (alas), since a new request is made at pt 2, thus destroying all environment variables we set.
An alternative solution can be to rewrite e.g. /abc , to /index.php?path=abc. That is done by these rules (please, delete your RedirectMatch similar rule before adding these):
RedirectMatch ^/index\.php(/.*) $1
RewriteCond %{REQUEST_URI} !^/(index.php|images|css|js|robots.txt|favicon.ico)
RewriteRule ^(.+) /index.php?path=$1 [L,QSA]
I don't know the internals of CodeIgniter's scripts, but as most of the MVC scripts, it will read $_REQUEST['PATH_INFO'] to understand which page is requested. You could slightly modify the code that recognizes the page like this (I assumed that the page path is stored in the $page var):
$page = $_REQUEST['PATH_INFO'];
if(isset($_GET['path']) && strlen($_GET['path'])) $page = $_GET['path']; // Add this line
This won't break the previous code and accomplish what you asked for.

Resources