.htaccess rewrite root folder to subfolder - .htaccess

Please could I have some help redirecting URLs to a subfolder so that everything in https://example.com is rewritten to https://example.co.uk/subfolder?
The .htaccess file needs to be in /subfolder.

You could do something like the following in the root .htaccess file to rewrite all direct requests to the subfolder.
RewriteEngine On
# Rewrite all direct requests to the `/subfolder` directory
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^ subfolder%{REQUEST_URI} [L]
The check against the REDIRECT_STATUS environment variable ensures that only direct requests from the client (as opposed to internally rewritten requests) are rewritten to the /subfolder directory (thus avoiding a rewrite loop).
This also means that a direct request for /subfolder itself will also be rewritten to the /subfolder directory (ie. /subfolder/subfolder) - so you can have a sub-subfolder of the same name if you wish (otherwise direct requests for /subfolder will result in a 404). That is, unless you have an additional .htaccess file in the subfolder that also contains mod_rewrite directives, in which case these directives will be overridden.
UPDATE: Following your question update that now states the following...
The .htaccess file needs to be in /subfolder.
In that case, this is not possible. The .htaccess file that rewrites requests to the /subfolder must be in the document root (the parent directory).
If the .htaccess file is in the /subfolder itself then it will simply never be processed for requests outside of that subfolder in order to rewrite the request.

MrWhite already gave nearly all the explanation I should have attached to my answer. So, like he already stated in his answer, the directives given below should be written into the .htaccess file that is located in the folder where https://site1.co.uk points to for it to work as you expect.
Here are the directives you can use.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /subfolder/$1 [QSA,L]
</IfModule>
The first RewriteCond will help make sure that the request is not for a file that already exists in the folder that the .htaccess file is located.
The second RewriteCond line is similar to the first but this checks for a folder instead. After this line, you can, and probably should, add the REDIRECT_STATUS line from MrWhite's answer. See his answer for the explanation.
The RewriteRule line uses Regular Expressions (RegEx) to effect the rewrite. Remember to replace subfolder on this line to name of the folder you wish to use and this folder should exist in the same location that the .htaccess file is located, and like already explained, this must be the folder that https://site1.co.uk points to.
Hope this helps.

Related

How To check and remove if any subfolder exists in a Folder by Htaccess?

I have a file structure like this.
Folder
- .htaccess
- Subfolder
- Otherfolder
- file1.html
- file2.html
- filea.html
- fileb.html
I can have many folders at the place of 'otherfolder' and I don't want to add code for each subfolder of 'Subfolder'.
i want to remove all other subfolders names except folder.
I just want to get URL like - mywebsite.com/folder/file.html
Edit
currently I am using this code snippet in .htaccess
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^subfolder/([^.]+)\.html$ /folder/$1 [L,R]
RewriteCond %{REQUEST_URI} !/folder/subfolder/
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|gif|png|jpeg)$
RewriteRule ^(.+)/?$ /folder/subfolder/$1.html [L]
I can have many folders at the place of 'otherfolder' and I don't want to add code for each subfolder of 'Subfolder'.
This isn't possible in .htaccess alone. The problem is not in removing the subfolder from the URL (although this should already have been done in the internal link), the problem is internally rewriting the request back to the appropriate subfolder. There is no built-in mechanism to "search" for arbitrary files in .htaccess.
If you have a limited number of known subfolders then you can do this, but you need to add a rule (in the root .htaccess file) for every subfolder. However, this is not particularly efficient since you need to manually test for the existence of that file in each subfolder. You also have a potential problem of name collision. Obviously, if you effectively "flatten" the filesystem the file file1.html can only exist once on the filesystem, amongst all subfolders. If there is more than one file1.html then the first match wins.
In principle, you would need to do something like the following to rewrite a request for /folder/<file>.html back to /folder/subfolder/otherfolderN/<file>.html.
# Test "subfolder/otherfolder1"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder1/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder1/$0 [L]
# Test "subfolder/otherfolder2"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder2/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder2/$0 [L]
# Test "subfolder/otherfolder3"
RewriteCond %{DOCUMENT_ROOT}/folder/subfolder/otherfolder3/$0 -f
RewriteRule ^[^/.]\.html$ subfolder/otherfolder3/$0 [L]
The parent /folder/ could be abstracted out of the RewriteCond TestString if you wish, but the subfolder and otherfolderN would need to be hardcoded. (Although subfolder could be manually assigned to an environment variable to save repetition.)
Aside:
RewriteCond %{REQUEST_URI} !/folder/subfolder/
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|gif|png|jpeg)$
RewriteRule ^(.+)/?$ /folder/subfolder/$1.html [L]
A "problem" with this code is that it rewrites the request regardless of whether the target file exists or not. This is OK if you are rewriting all requests to a single subfolder, but if you have multiple subfolders then you must check for the target file's existence before rewriting.
This also rewrites the request even if it already maps to an existing file. So any legitimate files in the /folder/ directory (eg. filea.html and fileb.html in your file structure) would not be accessible.
This also rewrites every file type (except for the few file extensions listed in the preceding condition). It would, for instance rewrite a request for foo/bar/file.webp to /folder/subfolder/foo/bar/file.webp.html. If you are only wanting to rewrite .html files then include this in the RewriteRule pattern and the preceding condition is not required.

htaccess directory management

im going to ask a really simple question. i dont want my link to show this when i run my page :
http://localhost/example/assets/gallery.php
what i want is :
http://localhost/example/assets/
so how to do it in .htaccess file ?
i would really appreciate it if you can help because im so confused after reading forums .
my htaccess is like this right now but you know it only helps to remove extension :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
How to make assets/gallery.php -> assets/
In the assets folder make a .htaccess file
Paste in this code :
DirectoryIndex gallery.php
This code changes the Directory Index (like a index.php file) to the gallery.php file meaning gallery.php is now like the index.php file.
The DirectoryIndex method that #RyanTheGhost suggests in his answer should have worked for the specific example you posted (where you request a directory and are serving a file from within that directory). However, the mod_rewrite directives you currently have in the document root1 will conflict with any requests for directories2 (although the DirectoryIndex should take priority).
However, the DirectoryIndex method is not very practical if you have many such files. And if you are not requesting a directory then this method naturally won't work anyway.
You could instead rewrite the URL using mod_rewrite in your existing .htaccess file, before your current directives.
1 I'm assuming your .htaccess file is in the document root.
For example:
# Rewrite "/example/assets/" to "/example/assets/gallery.php"
RewriteRule ^example/assets/$ example/assets/gallery.php [L]
Or, to avoid repitition:
# Rewrite "/example/assets/" to "/example/assets/gallery.php"
RewriteRule ^example/assets/$ $0gallery.php [L]
Where the $0 backreference contains the entire URL-path that is matched by the RewriteRule pattern. ie. example/assets/ in this case. NB: There is no slash prefix on the RewriteRule pattern or the substitution string.
Note that since you are requesting a directory (ie. /example/assets/) you need to ensure there is no DirectoryIndex document in that directory (eg. index.html or index.php), otherwise this will be served (by mod_dir) instead, overriding your internal rewrite above.
2 Your current directives that append the .php extension are arguably incorrect:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
This rule appends the .php extension to any request that does not map to a physical file, even if the file with a .php extension does not exist either. This can result in the incorrect URL being reported back to the user in the 404 error document (depending on how this is implemented). For example, the default Apache 404 error document will report that /foo.php does not exist, when the user requested /foo.
This rule will also rewrite directories (since they are "not files") which will result in a 404 (as opposed to a 403 or directory listing, if enabled). Although a DirectoryIndex document will override this.
Additionally, the NC flag is superfluous and there is no need to backslash-escape the literal dot inside a character class.
You could instead check that the corresponding .php file exists before rewriting, instead of checking that the requested URL does not map to a file.
For example:
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
The request is now only rewritten when the corresponding .php file exists, which naturally avoids any conflicts with directories.

Maintain separate .htaccess files in sub-folder

How do I maintain 2 separate .htaccess files so as to avoid dumping rules in the main .htaccess file.
For example: I want all the urls trailing after ^shows(/.*)?$ to point to .htaccess created under controllers/shows (.htaccess)
Depending on your rewrite rules, this can be accomplished with minimal rewriting (heh) of the .htaccess file. Take for example this .htaccess file stored in the webroot /var/www/html:
RewriteEngine On
RewriteRule ^/foo/help/(.*)? /foo/help.php?q=$1
Rewriterule ^blog/(.*)? blog/index.php?id=$1
We're doing two kinds of rewrite here:
www.example.com/foo/help/123 -> wwww.example.com/foo/help.php?q=123
www.example.com/blog/myarticle -> www.example.com/blog/index.php?id=myarticle
Notice the first RewriteRule is using absolute paths, while the second is using a relative path.
If I were to move the first RewriteRule into /var/www/html/foo/.htaccess, the file would look like this:
RewriteEngine On
RewriteRule ^/foo/help/(.*)? /foo/help.php?q=$1
Note that nothing needs to change, since you're using an absolute path.
Now if I were to move the second RewriteRule into /var/www/html/blog/.htaccess, the file would look like this:
RewriteEngine On
RewriteBase /blog/
RewriteRule ^(.*)? index.php?id=$1
Note the paths in the RewriteRule were stripped to make them relative to the current directory, which is now /blog. Also note the RewriteBase directive, which is necessary when using relative rewrite rules in a subdirectory.
Check out this question for another example of using subdirectory .htaccess rewrite rules.

removed .html extensions with htaccess now index.html give 403 error

After entering the code below, my home page gives a 403 error. The rest of the site works perfectly. All instances of .html were removed.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Any advice?
Thank you!
example.com leads ti the 403 error. If I write example.com/index it works fine.
Something else must have changed for this to result in a 403 error. The code you posted won't actually do anything when you request example.com/ - the same as if that code didn't exist at all. (UPDATE: However, this assumes your .htaccess file is located in the document - it appears this is not the case - see below.)
However, what will trigger a 403 in such cases is when "formatted directory listings" are disabled and the directory index document cannot be found (or has been disabled).
So, try setting the appropriate directory index at the top of your .htaccess file:
DirectoryIndex index.html
It is the DirectoryIndex that serves the appropriate file when requesting your "home page", not your directives in .htaccess.
UPDATE:
It [.htaccess] is located in my root directory. Would it be better to put it in the public_html folder?
Yes, the code you posted should go in the /public_html directory (ie. your document root). If these directives are in a .htaccess file above the document root then the RewriteRule pattern will match the URL-path public_html/ and rewrite the URL to public_html/.html which is possibly where your 403 error is coming from ("dot" files are usually hidden/protected OS files and you may also have a directive in your server config blocking access. However, this behaviour may also be dependent on other factors in the server config/OS). However, with that code in the document root then a request for example.com/ (your home page) won't be processed by these directives (which is good) - mod_dir should then serve the index.html file in this instance.
However, you don't want to process "directories" anyway (public_html is obviously a "directory", not a file). Which is what's happening above. eg. .html shouldn't be appended to public_html/ to begin with (or example.com/path/to/directory/ or any other directory). This can be avoided by adding an additional condition to your rule block to avoid directories (as well as files). For example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ $1.html [L]
Simply adding that additional RewriteCond directive might be enough and still allow you to keep your .htaccess file above the document root. (However, you may still need to move the .htaccess file as well, as described above.)
Also, the NC flag is not required here and literal dots don't need to be escaped when used inside a character class.
You could also extend this code to first check the existence of the file (with a .html extension) before rewriting, although this may be unnecessary in your case. For example:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^.]+)$ $1.html [L]
This requires an additional "file check" which may be an unnecessary overhead.

htaccess rewrite being overwritten

I have the following htaccess file in the root of my site to redirect a directory 'MyDirectory' to another URL (to stop google indexing both sites)
RewriteCond %{HTTP_HOST} ^myurl\.co\.uk$ [OR]
RewriteCond %{HTTP_HOST} ^www\.myurl\.co\.uk$
RewriteRule ^mydirectory\/(.*)$$ "http\:\/\/www\.redirectURL\.com/" [R=301,NC]
I then have another htaccess file in the 'MyDirectory' directory above which handles the URL and query string in a user friendly way:
RewriteRule ^Answers/(.+)$ Answers.php?articleName=$1 [QSA]
However, when i have the ReWriteRule ^Answers... section in my other htaccess it stops the redirect in the root of my site from working.
Any suggestions why the ^Answers/... rewrite is overwritting my redirect to www.redirectURL.com.
Thanks
.htaccess is per directory directive and for any URI path it current directory's .htaccess is processed first. If no .htaccess is found then it starts going 1 level up the directory tree until it finds one. It processes DocumentRoot/.htaccess in the end.
In your case since you have a /MyDirectory/.htaccess therefore all the directives are read from that file only thus overriding all the rules of DocumentRoot/.htaccess.
However you can add this line after RewriteEngine On in /MyDirectory/.htaccess
RewriteOptions inherit
This will process parent .htaccess after completing current one.

Resources