Rewrite existing file request to subdirectory - apache

I have a php framework on a shared hosting and this is my directory structure:
root (can't change because of shared hosting; here's the .htaccess)
vendor
web (index.php, assets in subfolders like css, images or js)
My .htaccess looks like this:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ web/index.php [L]
</IfModule>
Now the framework routing works, but I want Apache to search all existing files (${REQUEST_FILENAME} !-f) only in the web folder, not from the root level.
Example:
http://www.domain.tld/hello/world (virtual path) is rewritten to index.php
http://www.domain.tld/css/bootstrap.css is not found, because the file is in the web/css folder.
http://www.domain.tld/web/css/bootstrap.css would match, because of the RewriteCond %{REQUEST_FILENAME} !-f
Is it possible to combine RewriteCond %{REQUEST_FILENAME} !-f with a folder rewrite for existing files only? All other request must be rewritten to the index.php
All in all I want it similar as setting the VirtualHost->DocumentRoot to the web folder.
Thanks!

You can use these rules in site root .htaccess:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^/?$ web/index.php [L]
# if file is found in web/ folder then route it
RewriteCond %{DOCUMENT_ROOT}/web/$1 -f
RewriteRule ^(.+)$ web/$1 [L]
# otherwise route it to web/index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ web/index.php [L]
</IfModule>

Related

Rewriting to subdirectory and then to React's index.html using root .htaccess

I am trying to create .htaccess file that will be located in the root webserver directory. In the root, there will be also directories named backend/ and frontend/ + few more (their names are variable).
Current tree may look like this:
/
.htaccess
frontend/
static/
index.html
manifest.json
backend/
files/
index.php
other/
Since the front-end (React) and back-end (PHP) is done by others and is deployed using CI, I don't have any control over the files and folders in that two directories.
What I am trying to accomplish with the .htaccess file is to:
rewrite (not redirect) everything that goes to /** and does not exist itself to /frontend/**
everything in /frontend/** that does not exists should return /frontend/index.html
Here are some examples:
/ becomes /frontend/ (#1)
/index.html becomes /frontend/index.html (#1)
/manifest.json becomes /frontend/manifest.json (#1)
/static/script.js becomes /frontend/static/script.js (#1)
/module becomes /frontend/index.html (#1 and #2)
/backend/** will not be rewritten as the directory exists
/other/** will not be rewritten as the directory exists
My current file looks like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# Rewrite root directory to frontend
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /frontend/index.html [NC,L,QSA]
# Rewrite non-existent files and folders to frontend
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/frontend/
RewriteRule ^(.*)$ /frontend/$1 [NC,L,QSA]
</IfModule>
which mainly fails to rewrite /module to /frontend/index.html.
How should I continue?
Have it like this:
RewriteEngine on
RewriteBase /
# skip backend/ and other/ directories
RewriteRule ^(?:backend|other)/ - [L,NC]
# forward these known paths to /frontend/
RewriteRule ^(index\.html)$ /frontend/$1 [L,NC]
# rewrite an alphanumeric URI that is non-file/dir to /frontend/index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^\w+/?$ /frontend/index.html [L]
# Rewrite non-existent files and folders to frontend
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/frontend/ [NC]
RewriteRule ^(.*)$ /frontend/$1 [L]

.htaccess file wont redirect to /public folder (laravel issue)

I have folder /var/www/html/project/himp and there is my laravel installation.
In /var/www/html/project is my landing page index.html and some css files.
Inside /himp folder I have .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
also in /himp/public folder I have also .htaccess:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Now when I go to the domain.com/himp/public I get Laravel installation and startup screen but when I go to the domain.com/himp I get just folder views, so there is no redirection to public folder ...
Why? What can be a problem here? Please help.
Contrary to the pattern in RewriteRule (see "What is matched?"), the variable REQUEST_URI contains the full path, including /himp. So the condition should be either
RewriteCond %{REQUEST_URI} !/public
without a beginning of string anchor ^, or you must include the full path
RewriteCond %{REQUEST_URI} !^/himp/public

.htaccess the requested url /public/index was not found on this server

Hello there i just finished setting up my server and all my code files but im having a problem. Whenever i go to https://www.frindse.com/index it gives me a error that says that the /public/index file is not found.
The way my site is setup is all the requests goes to the public folder which holds my index.php file that routes all of my pages. Not on my local server everything works flawlessly but on my digitalocean server whenever i go to the index page it doesn't works. But if i go to https://www.frindse.com/login the pages loads perfectly. So this is how my .htaccess file looks in my public folder which routes all my pages and requests:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
Also here is the .htaccess file thats in the root of my website. It routes all the calls to the public folder:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
</IfModule>
Also keep in mind that i have mod_rewrite activated on my server and also i have set AllowOverride set to All in my digitaloceans erver.
Try adding a rewritebase to your .htaccess in public folder. And turn off multiviews for good measure.
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /public/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
Actually, why do you even need an .htaccess file in public folder? Just route the request directly to the index file like this .htaccess file in your root and remove the the one in public folder.
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
RewriteRule ^$ public/ [L]
RewriteRule ^(.*)$ /public/index.php?url=$1 [QSA,L]
</IfModule>

Make php files under a certain directory unaccessible using htaccess

I have a .htaccess file in place to redirect all requests that does not hit an existing file or directory to be parsed by my index.php file like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# Our app bootstrap file is index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
This is working fine, But I'd like also to add another rule to prevent any direct access to php files under a certain directory, routing those calls to the same index.php file.
Like so:
request for example.com/something.php -> ok
request for example.com/themes/(anythinggoeshere)/somefile.php -> not
ok, route trough index.php
request for example.com/themes/(anythinggoeshere)/banner.png -> ok
I'm looking for a way to make those "rules" work to everything under the "themes" folder without breaking my current ones.
Thanks!
You can have a new rule to handle those .php requests:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# handle .php requests via index.php
RewriteCond %{REQUEST_URI} !^/themes/ [NC]
RewriteRule ^[^/]+/.+?\.php$ index.php?/$1 [L,NC]
# Our app bootstrap file is index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>

Prevent RewriteCond from kicking in when trying to access a non-existing file from a folder

I have the current setup in my .htaccess file:
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !index
RewriteRule ^ index.html [QSA,L]
</ifModule>
It redirects any trafic to unexisting files or folders to index.html.
However, I would like to make an exception to the rule:
Any request made to locales/non-existing.file should return proper 404.
How can I do that?