Root folder change (.htaccess) - .htaccess

In my "public_html" directory I have the following structure:
- root
- index.html
- blog
- index.html
- lab
- index.html
- wp
- (WORDPRESS FILES)
The "lab" and "wp" directories are just subdomain directories ("http://lab.tomblanchard.co.uk" and "http://wp.tomblanchard.co.uk") which work fine.
Basically I want the main domain ("http://tomblanchard.co.uk") to point to the "root" directory without any actual redirecting, for example, I want "http://tomblanchard.co.uk" to point to the "index.html" file within the "root" directory, I want "http://tomblanchard.co.uk/blog" to point to the "index.html" file within the "root/blog" directory and so on.
I have kind of achieved this with the following code in my ".htaccess" file:
# Add directives
RewriteEngine on
# Remove ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Change root directory to "root" folder
Options +FollowSymLinks
RewriteCond %{REQUEST_URI} !(.*)root
RewriteRule ^(.*)$ root/$1 [L]
The only problem is that things like "http://tomblanchard.co.uk/root/" and "http://tomblanchard.co.uk/root/blog/" still work when really they shouldn't even be able to be accessed (404).
If anyone has any idea on how to sort this or has a stronger method of doing this it would be greatly appreciated.
Update
Finally got it working how I wanted it after hours of researching, I used the following:
# Add directives
RewriteEngine on
# Change root directory to "root" folder
RewriteCond %{THE_REQUEST} ^GET\ /root/
RewriteRule ^root/(.*) /$1 [L,R=301]
RewriteRule !^root/ root%{REQUEST_URI} [L]

The order of directives in mod_rewrite is important, as each rule sees the output of the previous rule as its input to test. You need to do 3 (or possibly 4) things, in order:
Deny access to any URL beginning /root/ (we have to do this first, else everything will be denied!)
It's generally good practice to ensure each URL has only one valid form, so URLs which do specify .html should cause a browser redirect to the non-.html form. This needs to happen before other rewrites, otherwise you can't tell the difference between a .html from the browser and one you've added virtually.
Look up any URL not denied above in the /root/ directory, rather than the configured DocumentRoot
Look up any URL not pointing at a directory under the URL + .html, if that file exists. This has to come after other rewrites, or the "file exists" check will always fail.
# General directives
Options +FollowSymLinks
RewriteEngine on
# Deny URLs beginning /root/, faking them as a 404 Not Found
RewriteRule ^root/ [R=404]
# Additional rule to strip .html off URLs in the browser
RewriteRule ^(.*)\.html$ $1 [R=permanent,L]
# Rewrite everything remaining to the /root sub-directory
# (Host condition was in your post originally, then edited out; this is where it would go)
RewriteCond %{HTTP_HOST} ^(www\.)?tomblanchard\.co\.uk$
RewriteRule ^(.*)$ root/$1
# Handle "missing" ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
PS: Note my careful language to describe (internal) rewrites, as opposed to (browser) redirects: the rule you have is not removing .html from anything, it is adding it, thus allowing the page to be accessed if someone else removes it. Since you are often modifying both within a set of rules, it's important to keep clear in your head the distinction between the URL the browser has requested, and the virtual URL Apache will ultimately serve.

You are not defining any rule to block /root address so how do you want to block it when there is nothing to do that?
Try this:
# Add directives
RewriteEngine on
RewriteCond %{REQUEST_URI} .root [NC]
RewriteRule (.*) / [L,R=404]
# Remove ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Change root directory to "root" folder
RewriteCond %{HTTP_HOST} ^tomblanchard.co.uk$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.tomblanchard.co.uk$
RewriteCond %{REQUEST_URI} !.root
RewriteRule (.*) /root/$1 [L,R=301,QSA]
This is not tested so if it wouldn't work, play around with it to get your need.

Related

Rewrite folders with .htaccess

For a website, I want to set up a redirection using .htaccess.
My folder structure is something like
/
/folderA/
/folderB/
/index/
where folderA and B and index contain subfolders and files. Now, I want to rewrite all requests for the root / and for all not existing folders and files to index. It should be masked. It seems to me like an easy task but I cannot get it to work. So far, I tried
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) /index/$1 [L]
The redirection somehow works but it does not work when I call the root http://example.org/ directly.
Is the root also seen as valid directory or excluded in the RewriteCond checks? Any ideas how to realize that?
Yes, the root is also a directory. You will need to add another rule to rewrite the root only. For example:
RewriteRule ^$ /index/ [L]
And since the root is a directory, you might as well exclude this from the first rule. ie. Change (.*) to (.+).
HOWEVER, your existing rule will result in a rewrite-loop (500 error) if the URL you are rewriting to in /index/... does not exist either*1. eg. If you request /foo, it rewrites to /index/foo and if /index/foo does not exist then it rewrites to /index/index/foo to /index/index/index/foo etc.
You will need to add an additional condition (or use a negative lookahead) to prevent requests to /index/... itself being rewritten.
(*1 Unless you have another .htaccess file in the /index subdirectory that contains mod_rewrite directives and you have not enabled mod_rewrite inheritance.)
For example:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/index/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index/$1 [L]
RewriteRule ^$ /index/ [L]

remove file names completely from url with .htaccess

With some modifications is possible to hide extension of the web files like http://www.abc.com/asd/zxc/ against to zxc.php but the thing I wanna do is remove file names completely from the url like http://www.abc.com/asd/ it doesn't matter user where to go in web site but the url should be stay static all the time.
Is it possible to do that with .htaccess?
I already tried this but it didn't work:
RewriteOptions inherit
RewriteEngine On # enables url rewriting
RewriteCond %{REQUEST_FILENAME} !-d # if requested uri is not directory (!-d)
RewriteCond %{REQUEST_FILENAME}\.php -f # and if there is a file named URI+'.php' (-f)
RewriteRule ^(.*)$ $1.php # then if there is any thing in uri then rewrite it as uri+'.php'
I'm not sure, but isn't the problem that you would like to check so the supplied url fragment is not a directory and not a file, and if that's the case, append .php to the fragment?
Something like this might work:
RewriteEngine On # enable mod_rewrite
RewriteBase / # set the 'base' for the rewrite
# you might need to modify this one.
RewriteCond %{REQUEST_FILENAME} !-f # not a file
RewriteCond %{REQUEST_FILENAME} !-d # not a directory
RewriteRule ^(.*)$ /$1\.php [L] # append '.php' to the path
#
If you have the following directory structure, and of course the .htaccess file in the root of the structure:
/code/test.php
/index.php
You should be able to access the test.php and index.php files by using the following urls:
http://example.com/code/test/
and
http://example.com/index/
The example.com needs to be change to a valid domain or ip address.

remove .php from url with htaccess

I need to know how to remove the ".php" from the directory index file
I don't want to see this:
http://www.domain.nl/wa.admin/index.php?login_msg=nopassword
I saw a lot of posts but they did not work for me for some reason.
these are my basic rules
RewriteRule ^admin[/]*$ /wa.admin [L]
RewriteRule ^([^./]{2}[^.]*)$ /index.php?page=$1 [QSA,L]
What do I have to do internally, because it comes from a redirect ?
Do I have to use absolute url's to make it work?
thanks, Rich
This should work for you.
RewriteBase /
# Stop rewrite process if the path points to a static file anyway
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule (.*) index.php
Explained in words: If the requested resource is a folder or a file don't rewrite, if not rewrite to the index.php.
In your case wa.admin/index.php?login_msg=nopassword will look like wa.admin/?login_msg=nopassword.
Don't forget to update you application. This rule only mapps requests to the appropriate files. This doesn't impact you HTML output. This means with this rewriting you can access both URLs but it's up to you which you want to link in your application.
If you want to distribute your app with others you may use the environment in combination with the if tag to determine whether mod_rewrite is available or not.
<IfModule mod_rewrite.c>
# Enable URL rewriting
RewriteEngine On
# Set flag so we know URL rewriting is available
SetEnv REWRITEURLS 1
# You will have to change the path in the following option if you
# experience problems while your installation is located in a subdirectory
# of the website root.
RewriteBase /
# Stop rewrite process if the path points to a static file anyway
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule (.*) index.php
</IfModule>
Use apache_getenv("REWRITEURLS"); to acess the value of the set variable.
You code might look like this (untested):
<?php
$rewriteurls = apache_getenv("REWRITEURLS");
if ($rewriteurls == '1') {
//adjust all your links
}
?>

Why is .htaccess always returning the target page as a variable here?

I have the following in my .htaccess file:
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)$ page.php?query=$1
however no matter what i type into the url, $1 is always equal to page.php
What I Expect to happen:
myurl.com/test >> myurl.com/page.php?query=test
What is happening:
myurl.com/test >> myurl.com/page.php?query=page.php
You likely have 2 redirects taking place. page.php itself is being redirected to page.php?query=page.php. You need to exclude it from the redirect. Better yet, exclude all real existing files and directories. Also, add [QSA'] to append any additional querystring params, as well as[L]` to stop processing any further rewrites that may come later in the file.
RewriteEngine on
RewriteBase /
# if the request is NOT for a real file or directory
# (page.php is a real existing file)
# do the rewrite
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteRule ^(.*)$ page.php?query=$1 [L,QSA]

Check for a directory inside a subdirectory dynamically

I have a bunch of domains which points to the same directory "public_html" on my host.
There is a .htaccess file in the main folder that locally redirects each domain to a particular folder with the same name as %{HTTP_HOST} mod_rewrite variable. (eg: redirect www.domain.com to public_html/www.domain.com/)
This is the content of the .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond /%{HTTP_HOST}/#%{REQUEST_URI} !^([^#]+)#\1
RewriteRule ^(.*)$ %{HTTP_HOST}/$1 [L]
I'm having a problem when it comes to the Directory Slash directive.
If I try to access a folder in the domain url without the forward slash like http://www.domain.com/folder, the mod_dir applies the DirectorySlash and externally redirects my request to http://www.domain.com/www.domain.com/folder/
I tried applying a 301 redirect AFTER the domain directory redirect like this:
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ $1/ [R=301,L]
But for this to work, I would have to be able to check if the %{REQUEST_FILENAME} exists inside the %{HTTP_HOST} 'folder'. I even tried the following, for no success:
RewriteCond /%{HTTP_HOST}/%{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ $1/ [R=301,L]
How can I check, Dynamically, if the %{REQUEST_FILENAME} is a directory, which would be inside a directory with the same name as %{HTTP_HOST}?
Thanks in advance
If you work with -d you need to provide an absolute filesystem path. So try this:
RewriteCond %{DOCUMENT_ROOT}/%{HTTP_HOST}%{REQUEST_URI} -d
RewriteRule ^(.*[^/])$ $1/ [R=301,L]

Resources