URL rewriting for nested level directories - .htaccess

I have a assets folder in my webserver which contain files like javascript, css and deep level of other folders. When user tries to access this folder using url like:
www.example.com/assets
I show then 404.html file, which is done easily as:
RewriteEngine On
RewriteRule ^/assets/$ /404.html [NC,L]
But as I say it a multiple folder inside it, also for which show 404 error. I don't want to write rewrite rule for all the folders inside it (because their is many). I am a beginner in url rewriting, can anybody show me how can I achieve this with a line or two lines of code.

Add the line:
RewriteRule ^/assets/(([^/]*)/)+$ /404.html
Which will match /assets/{anything}/{anything}/{anything}/...

If you're wanting to prevent visitors from listing the files in your directories, you can use
Options -Indexes
in your .htaccess file.

You just need this rule to forward all /assets/* requests to /404.html:
RewriteRule ^assets(/|$) /404.html [NC,L]
Make sure this rule is your first rule.

Related

.htaccess need help to serve requests to index.php in non root folder

I have a specific website structure:
root:
styles.css
pages/index.html
folder_with_assets_1
folder_with_assets_2
folder_with_images
I've renamed index.html to index.php in order to get rid of .html extension in the URL
But the problem is that index.php is located not in a root folder, it's in pages folder.
Which right .htaccess rules could solve the problem in order to redirect requests to pages folder?
UPDATE
the screenshot with folder structure:
On the face of it, this just looks a standard front-controller pattern. Whether the front-controller is located inside a subdirectory or directly in the document root is largely irrelevant - the process is the same.
Assuming you are using the .htaccess file in the document root and there is no discernable pattern to the page URLs...
For example, using mod_dir FallbackResource:
FallbackResource /pages/index.php
Or, using mod_rewrite:
DirectoryIndex /pages/index.php
RewriteEngine On
RewriteRule (^|/)index\.php - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . pages/index.php [L]
UPDATE#1:
It's "onepage" website format with plenty of JS and CSS. There are only local URLs pointing to sections (href tag) and AJAX call to specific PHP files
In that case, it just looks like you need to change the DirectoryIndex - you don't need a front-controller pattern (as discussed above) at all.
For example:
DirectoryIndex /pages/index.php
Now, a request for the "homepage", ie the document root https://example.com/ will serve /pages/index.php.
UPDATE#2:
From your screenshot, it looks like directory listings (mod_autoindex) are enabled. These should be disabled at the top of the .htaccess file:
Options -Indexes
UPDATE#3:
From your screenshot, it would seem that what you have called "root" in your file structure is not actually your website's "document root", since you are accessing this location via a /test subdirectory, ie. localhost/test/. The directives above are assuming these files are located in the "document root", ie. localhost/ and there is no /test subdirectory. (Which I expect is how it is structured on your "live" environment?)
If your .htaccess file is located in the /test subdirectory and you are requesting localhost/test/ (as per your screenshot) then you will need to adjust this accordingly:
For example:
DirectoryIndex /test/pages/index.php
However, that will not work on the live site (assuming you don't have a /test subdirectory on live). Instead, you can simply omit the slash prefix, to make it relative.
For example:
DirectoryIndex pages/index.php
This should work OK in your case since you have a SPA (just a homepage URL).

.htaccess redirect from subfolder to folder level up

My website's basic URL is https://website.com/catalog - the application is in /catalog folder.
What I'd like to do is to allow users from different countries to access my website with: https://website.com/catalog/de, https://website.com/catalog/fr etc (just 5 or six languages).
For example, when a user fires https://website.com/catalog/fr/abc.php I want him to get https://website.com/catalog/abc.php content while keeping https://website.com/catalog/fr/abc.php in the browsers URL bar.
I've tried putting this code in .htaccess located at website.com/catalog/ but it doesn't work:
RewriteRule ^fr/(.*)$ /$1 [L,NC,R]
Please keep your htaccess Rules file inside catalog folder and have it following way.
RewriteEngine ON
RewriteBase /catalog/
RewriteRule ^(?:en|fr|de)/([\w-]+\.php)/?$ $1 [NC,L]
In first non-capturing group I have kept en|fr|de languages, we can put more languages as per your requirement here too.

More than one htaccess rewrite rule

I'm having some trouble understanding .htaccess basically I'm trying to have more than one rewrite rule; for example I have a profile page and then I also want to rewrite the index page so how would this be done; in my previous attempts I could only use one rewrite rule perhaps I was doing something wrong; I have a profile page with the link /profile/profile.php?user=$username and the index page account.php?page=featured how could I get the profile page to look like /account/$username and the account page to look like /account/featured thankyou also how would I then add more later down the line?
the account.php file is in the root directory.
RewriteEngine On
RewriteBase /
RewriteRule ^tag/([^/]+)/([^/]+)$ /tag/index.php?hash=$1&cat=$2
Options All -Indexes
ErrorDocument 403 Denied
that is my current .htaccess which uses the hashtags and shows them like this /tag/$hashtag when I tried to copy and paste this to then use under it it didn't work.
As mentioned in my comment, Apache won't be able to tell which file to rewrite to. So you'll need to change one of the URI structures. As a recommendation, change the one for the profiles.
Here is an example to show you how to do this:
RewriteRule ^tag/([^/]+)/([^/]+)$ /tag/index.php?hash=$1&cat=$2 [L]
RewriteRule ^account/([^/]+) /account.php?page=$1 [L]
RewriteRule ^profile/([^/]+) /profile/profile.php?user=$1 [L]
Remember the [L] flag, which causes rewriting to stop when a match is found.

mod_rewrite rule to redirect specific URL matches

I am using mod_rewrite to redirect long URL's to specific pages. Its for a shop so basically if the URL is one folder deep it takes the user to a specific page, if the URL is two folders it takes them to another etc. I achieved this using the following...
RewriteRule ^([^/\.]+)/?$ shop.php?category=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ brand.php?category=$1&brand=$2 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ handler.php?category=$1&brand=$2&product=$3 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ handler.php?category=$1&brand=$2&product=$3&car=$4 [L]
Notice each rule is one folder deeper than the previous.
Rather than use another rule for the next stage which is the final product page I would rather take the user to http://www.domain.com/PRODUCT/DB/ID so I wrote a rule to check if the first folder was PRODUCT and if so take the user to PRODUCT.PHP?DB=$1&ID=$2...
RewriteRule ^product/([^/\.]+)/([^/\.]+)/?$ /product.php?db=$1&id=$2 [L]
It keeps returning a 404 error though. I placed this new rule just before the others in the hope it would execute this rule before any others (this appears to be 3 folders deep for which there is another rule when the first folder isn't PRODUCT)
The .htaccess and subsequent .php files are at the root level of the site.
Have I wrote the rule correctly? I have tried all sorts and looked everywhere but questions like this are generally related to ignoring a specific folder which I don't actually want to do.
Thanks
Try turning off Multiviews:
Options -Multiviews
Multiviews is part of mod_negotiation which tries to match a request to existing files, including ones that are missing the extension. So it's possible that mod_negotiation sees the request for /product/something and sees the file /product.php and serves up that file using PATH INFO, which will completely bypass mod_rewrite.

htaccess rule - Take the Place of Symlinked Files

I'm working on this legacy project that has a rather odd setup that I'm looking to get rid of but my htaccess skills are a little lacking in this department.
Here's the directory structure.
/index.php
/www
page1.php -> symlink to index.php
page2.php -> symlink to index.php
page3.php -> symlink to index.php
/www is the public directory and people visit http://site/page1.php. However, each of those files with an * actually symlinks to /index.php.
I find this arrangement idiotic and would like to get rid of the symlinks and simply have any /www/*.php request simply point at index.php without the page actually redirecting to index.php.
Any ideas for an htaccess rule(s) that could solve this problem? At its most basic core, I'd like to keep the same functionality without having to have a thousand symlinked files.
It looks like the index.php file is not in your document root (which I'm assuming is www), and because of that, I don't think there's a way you can do this from your .htaccess file. In order to access something outside of your document root, you'll need to setup an alias in either your server config or your vhost config:
# Somewhere in vhost/server config
Alias /index.php /var/www/path/to/index.php
# We need to make sure this path is allowed to be served by apache, otherwise
# you will always get "403 Forbidden" if you try to access "/index.php"
<Directory "/var/www/path/to">
Options None
Order allow,deny
Allow from all
</Directory>
Now you should be able to access /var/www/path/to/index.php. Note that other files in the /var/www/path/to directory is safe as long as you don't create an Alias (or AliasMatch or ScriptAlias) that points to them. Now that you can access index.php via the /index.php URI, you can setup some mod_rewrite rules in the .htaccess file in your document root (www) to point things to index.php:
# Turn on the rewrite engine
RewriteEngine On
# Only apply the rule to URI's that don't map to an existing file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all requests ending with ".php" to "/index.php"
RewriteRule ^(.*)\.php$ /index.php [L]
This will make it so when you request http://site/page1.php, the browser's address bar is unchanged but the server actually serves /index.php, which is aliased to /var/www/path/to/index.php.
You can tweak the regular expression ^(.*)\.php$ to something more appropriate if need be. This just matches anything that ends with a .php, including /blah/bleh/foo/bar/somethingsomething.php. If you want to limit the directory depth, you can tweak the regular expression to ^([^/]+)\.php$, etc.

Resources