Check for a directory inside a subdirectory dynamically - .htaccess

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]

Related

How can I make a htaccess redirect without keeping the path?

I am really confused... I have searched and experimented, but can't seem to get anything to work. So I gave up and asked here :)
How can I redirect /subfolder to root, but every page inside the subfolder should be redirected to root?
/subfolder redirects to root
/subfolder/another-folder redirects to root (not root/another-folder)
Thanks.
To redirect requests from /subfolder to / (to the root folder) ,you can use the following Rule in your htaccess file:
RewriteEngine on
RewriteCond %{THE_REQUEST} /subfolder/(.*)\sHTTP [NC]
RewriteRule ^.+$ /%1 [NE,L,R]
The RewriteRule above will redirect any request from /subfolder/foobar to /foobar but you will get a 404 not found error since /foobar doesn't exist in your /root fodder.
To solve this ,you need a RewriteRule to internally rewrite requests from /root to /subfolder .The following rule will Internally map http://example.com/foobar to http://example.com/subfolder/foobar .The redirection from root to the subfolder is invisible.
Add the following right bellow the subfolder to /root redirection rule
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ /subfolder/$1 [L]
EDIT :
My apologies. I misread your question. If you want to redirect your /subfolder requests to just the root folder ,try this:
RewriteEngine on
RewriteCond %{THE_REQUEST} /subfolder/(.*)\sHTTP [NC]
RewriteRule ^.+$ / [NE,L,R]

URL rewrite to remove trailing folder name

We have a server, and have several folders under the /var/www/ folder.
We have pointed our domain name to the IP of the server, and by default we expect to load one folder as the website (since its not possible to point a folder with DNS).
I have written .htaccess in such a way that when you enter the IP or the domain name, the request redirects to the website folder.
However, whenever we enter the IP or the domain name, the name of the folder is getting added to the URL.
Here is the present .htaccess:
Options +FollowSymlinks -Multiviews
#DirectoryIndex folder/
RewriteEngine on
ReWriteBase /
RewriteRule ^$ /folder [L]
RewriteRule ^$ folder/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+folder/([^\s]+) [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (?!^folder/)^(.*)$ /folder/$1 [L,NC]
where the folder is the folder's website
so,
www.domain.com
becomes
www.domain.com/folder/
Is there a way to rewrite the URL to remove the folder name?
Thanks in advance :)
EDIT : Added .htaccess code
Have your rule like this in DocumentRoot/.htacess:
DirectorySlash On
Options +FollowSymlinks -MultiViews
RewriteEngine on
ReWriteBase /
# redirect /folder/abc123 to /abc123
RewriteCond %{THE_REQUEST} \s/+folder/(\S*) [NC]
RewriteRule ^ /%1 [R=301,L,NE]
# skip rewrites for real files/directories
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule !^(index\.)?$ - [L]
# route everything internally to /folder
RewriteRule ^((?!folder/).*)$ folder/$1 [L,NC]
It sounds like you made an external redirect instead of an internal rewrite. An external redirect is denoted by the [R] flag (with optional parameter) and causes Apache to send a 301 or 302 header back to the client with a different url that client should request. This causes the client to show the new url in the address bar.
What you want is an internal rewrite. When you request the url, the url is internally rewritten to the place where the resource is actually located. You do this by omitting the [R] flag, and not using a domain name in the rewritten part. It typically looks something like this:
RewriteCond %{REQUEST_URI} !^/folder
RewriteRule ^(.*)$ /folder/$1 [L]

Root folder change (.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.

Hidden redirect of / to subfolder using .htaccess in TYPO3

We're setting up a TYPO3 installation, and if the user calls example.com/ we'd like the server to redirect to /typo/index.php?id=106.
This should happen without a change in the address bar. Every other file access on the server (for example example.com/test.png) should be redirected to example.com/typo/test.png).
This is the .htaccess file in the root directory. As I understand, it will redirect everything which doesn't have /typo in the URL to the subfolder and attach the parameters:
RewriteCond %{REQUEST_URI} !^/typo/
RewriteRule ^(.*)$ typo/$1 [L]
Now, this already seems to work, when I call example.com/index.php?id=106 I'm not getting a 404. Unfortunately TYPO3 seems to have some trouble (or the .htaccess configuration isn't correct), because we get a message saying "No input file specified".
What's also missing is the initial redirect when no path is specified. It should then go to /typo/index.php?id=106.
You may try this in one .htaccess file in root directory:
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /
# URL with no path
RewriteCond %{REQUEST_URI} ^/?$ [NC]
RewriteCond %{REQUEST_URI} !index\.php [NC]
RewriteRule .* /typo/index.php?id=106 [NC,L]
# URL with path
RewriteCond %{REQUEST_URI} !^/typo [NC]
RewriteRule ^(.+) /typo/$1 [NC,L]
Maps silently:
http://domain.com/ to
http://domain.com/typo/index.php?id=106
and
http://domain.com/anything
http://domain.com/typo/anything
For permanent redirection, replace [NC,L] with [R=301,NC,L]

How do i redirect a directory to the parent directory in htacess

I have this website http://www.foo.com/bar/index.php. I recently moved my site FROM foo.com/bar/index.php TO foo.com/index.php
In my htaccess file, how do i write the conditions so that if any request is made from lets say .foo.com/bar/somedirectory/somefile REDIRECT to foo.com/somedirectory/somefile
In the htaccess file in your document root, preferably above any rules that do routing (to index.php, for example), add these rules:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/bar/(.*)$
RewriteCond %{DOCUMENT_ROOT}/%1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1 -d
RewriteRule ^/?bar/(.*)$ /$1 [L]
If you want to externally redirect the client (changing the URL in the browser's address bar), then add the R flag in the rule's brackets: [L,R=301].
Add below to your foo.com/bar/.htaccess file:
RewriteEngine On
RewriteRule ^(.*)?$ http://%{HTTP_HOST}/$1 [R=301,QSA,L]

Resources