.htaccess not redirecting subfolders - .htaccess

Hello i'd created a htaccess file to pass every petition through a wrapper.php file.
Here's the code:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /wrapper.php?PATH_INFO=$1 [NC,L,QSA]
</IfModule>
My folder structure is this one:
* root
* .htaccess file
* my-folder
* admin
* recover.php
I tried everything in localhost (using xampp) and works perfectly. But the problem is when i upload my site contents to a hosting, don't work.
I'll explain if I access to http://example.com or http://example.com/admin/ my wrapper receive correctly the parameters and is able to handle it, but when I access to http://example.com/admin/recover/, for example, there's a file inside /admin/ called recover.php and the wrapper is not handling anything. I guess it is something with RewriteCond %{REQUEST_FILENAME} !-f. But my question is why in localhost everything pass first through wrapper.php but in my hosting it calls the file (recover.php in this case) first if this exists.
Edit:
I tried to change the wrapper so instead of include a recover.php file, when /admin/recover/ is called, to include recover-password.php
And now works fine, but keep not understanding why in localhost the wrapper is called first instead of the actual file.
I want to make it work without renaming all files inside /admin/
Thanks.

This seems to be a problem is remote host enabling MultiViews option.
Place this line at top of your .htaccess to turn off MultiViews:
Options -MultiViews

Related

Adding .htaccess file shows directory listing instead of redirecting to index.html, plus the directory listing is weird

Before I added a .htaccess file, if I typed in https://example.com/f/myfolder, it would redirect to https://example.com/f/myfolder/ (with a trailing slash). {documentRoot}/f is a symlink to a folder that contains a folder named myfolder, and myfolder contains an index.html file.
I then added the .htaccess file into {documentRoot}/f/myfolder with the contents:
RewriteEngine On
RewriteBase /f/myfolder
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /f/myfolder/index.html [L]
Now if I type https://example.com/f/myfolder I get a directory listing instead of being redirected. If I type https://example.com/f/myfolder/ the rewrites work as expected.
The weird thing is that the directory listing shows the contents of {documentRoot}/f/myfolder, and the title is "Index of f/myfolder" but if I hover over (say) the index.html file, it points to https://example.com/f/index.html instead of https://example.com/f/myfolder/index.html (and if I click it, it takes me to the index.html that is in the parent folder).
I tried prepending
RewriteCond %{REQUEST_URI} !/f/myfolder/$
RewriteRule ^(.*)$ $1/ [L]
to the .htaccess file, to try and add a trailing slash, but it didn't seem to make any difference.
One final tidbit of information. If I change +FollowSymLinks to just FollowSymLinks, I get a 403 forbidden page instead of the directory listing. EDIT: I am changing it in the apache2 config file, in the <Directory> section for the directory. The only other option in that section is AllowOverride All
I am curious as to why the directory listing is weird, but my real question is: How can I make it work both with and without trailing slashes?
Using Apache/2.4.29
EDIT: One more discovery, not sure if it helps. If I have a blank .htaccess file, then https://example.com/f/myfolder gets redirected to https://example.com/f/myfolder/. If I add RewriteEngine On to the .htaccess file and nothing else, the redirect no longer happens.
EDIT 2: It's definitely related to /f being a softlink. If I add an Alias in the apache2 config file so that it's aliased to the correct directory instead of softlinked, then it works fine. I would prefer to fix it in the .htaccess file if possible though!

I need to .htaccess redirect my subfolder to the root folder, except two folders

The subfolder i want to redirect to the root folder is www.example.com/subfolder
So I need to redirect everything in that subfolder to the url adress https://www.example.com except for these two folders (which are placed in the subfolder): www.example.com/subfolder/folder1 and www.example.com/subfolder/folder2
I spent like 4 hours trying to find the exact code but I could not solve that. Nothing worked for me.
I've tried many codes, but nothing worked for me. For example:
RewriteEngine On
RewriteCond %{REQUEST_URI}!^/subfolder/folder1/
RewriteCond %{REQUEST_URI}!^/subfolder/folder2/
RewriteRule ^(.*)$ /$1 [R=301,L]
and
RewriteEngine on
Options +FollowSymlinks
RewriteCond %{REQUEST_URI}!^/subfolder/folder1/
RewriteCond %{REQUEST_URI}!^/subfolder/folder2/
#RewriteRule (.*) http://www.example.com/subfolder/ [R=301,QSA,L]
RewriteRule (.*) https://www.example.com [R]
Could someone help me with that?
I'd prefer to place the .htaccess file in the subfolder.
Thank you so much.
I'd say that your first attempt looks pretty good. Just make a slight modification since you say you want to redirect to the root path, not something inside the root path:
RewriteEngine On
RewriteCond %{REQUEST_URI}!^/subfolder/folder1/
RewriteCond %{REQUEST_URI}!^/subfolder/folder2/
RewriteRule ^(.*)$ / [R=301,QSD,L]
Since you want to use a distributed configuration file (as opposed to the preferred central configuration for the http host) that rule is meant to be used inside a ".htaccess" file inside the "subfolder".
It is a good idea to start out using a R=302 temporary redirection and to only change that to a R=301 permanent redirection once everything works as intended. Also you need to make sure that you always test using a fresh anonymous browser window to prevent client side caching effects.
And you also need to make sure that such distributed configuration files are considered at all by the http server for that location (see the documentation of the AllowOverride directive).

htaccess rewrite stopped working properly

I have the following code block in my .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(.*)2021layout(.*)$
[other directories to omit, like assets and admin]
RewriteRule ^(.*) RESThandler.php
Basically I want certain directories to be processed normally, like 2021layout, while others use the REST handler. In the 2021layout directory, the member area is in the directory 2021layout/myaccount, and all css/js files are in 2021layout/assets/[whatever directory]. Both the assets and myaccount directories have permissions 0755.
On Friday, everything was working fine. Today, having changed nothing, pages in the 2021layout directory are working, and css and js files loaded by those pages are fine, but pages in the 2021layout/myaccount directory are trying to use the REST handler and getting redirected to my 404 page.
I have tried renaming both the 2021layout and myaccount directories, which didn't work. I have tried adding !^(.*)2021layout/myaccount(.*)$ as a RewriteCond, and that didn't work.
Why would this one specific directory suddenly stop obeying my htaccess instructions? Can I fix this?
Again, to reiterate: I didn't change anything to make this happen. It worked one day, and the next day it didn't, seemingly on its own.
EDIT: I have gotten the directory to work again by renaming the newly-created file settings.php to mysettings.php. So apparently the mere existence of settings.php within the directory was preventing it from loading correctly. Does anyone have any insight into this?
You may try this rule with THE_REQUEST:
RewriteCond %{THE_REQUEST} !\s/2021layout/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ RESThandler.php [L]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. Example value of this variable is GET /index.php?id=123 HTTP/1.1
Make sure to clear your browser cache before testing this change.
So apparently the mere existence of settings.php within the directory was preventing it from loading correctly. Does anyone have any insight into this
I am guessing that you have option MultiViews turned on in your Apache config. To turn it off use this directive at top of your .htaccess:
Option -MultiViews
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.

Laravel project in subfolder of public_html gives trouble with .htaccess redirect

I've set up my VPS server and am trying to set up a Laravel project.
I have a /public_html/ folder with an index.html that's shown when visiting the website URL.
I have a laravel project in: /public_html/project_one/
The original index.php is located in /public_html/project_one/public/index.php
I want the website to show to Laravel project_one by default, but since yesterday I literally googled this for 4 hours, I tried every solution on stackoverflow, nothing worked... I think I've tried over 10 versions of .htaccess I could find.
The question:
Does anyone know how to setup the .htaccess inside /public_html/ so it redirects to my Laravel project?
I though I needed to upload my Laravel folder in: /public_html/project_one/ but is there a better location?
I want the main url to show the Laravel project. So www.mainurl.com is Laravel's project_one/public/index.php file. I do not want /project_one/ to be written in the URL!
Just out of curiosity, if I now visit: www.mainurl.com/project_one I get a 403 forbidden.
Failed solutions
In /public_html/ I tried to add .htaccess with:
DirectoryIndex index.php
#Redirect to /project_one/public if you haven't already and the IP is okay
RewriteCond %{REMOTE_ADDR} ^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} !^/project_one/public
RewriteRule ^(/lucaphoto)?(.+) /project_one/public$2 [L]
#if IP does not match and you ARE in the folder, then Redirect to root
RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4*
RewriteCond %{REQUEST_URI} ^/project_one/public
RewriteRule .? / [R=301,L]
This gives me something really strange:
On Chrome: it redirects me to www.mainurl.com/project_one -> And then gives me a 403 forbidden error.**
On safari: it redirects me nowhere but gives me this error:
Forbidden. You don't have permission to access / on this server.
Additionally, a 404 Not Found error was encountered while trying to
use an ErrorDocument to handle the request.
Laravel's original .htaccess File
By the way, Laravel has an original .htaccess file at /project_one/public/.htaccess. And it looks like this:
<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]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
The actual laravel application ( anything but the public folder ) is not supposed to be public and therefore should not be placed inside the public ( public_html ) folder.
I actually tried severel things to get something similar to your setup running. My conclusion was - that only changing the .htaccess file will net e enough to run laravel inside a public folder.
The most easy solution to quickly setup a laravel application is to use a subdomain which directly points to the public folder.
www.mainurl.com /* points to .../public_html/ */
laravel.mainurl.com /* points to .../laravel/public/ OR ( but not good ) */
/* points to .../public_html/my-project/public/ */
What you actually will need to do then is to change the root of your domain / subdomain to point into another folder - no changes to .htaccess are needed then.
Update
If your site is www.example.com and you want your laravel app to show when opening this site you have two options.
Put the content of laravels public folder to public html and change the references to fit the public_html instead of public folder.
If your Filestructure on the server is like .../var/stuff/.../public_html/ then upload everything to ../var/stuff/my-project and then go to your hosters interface and make an internal redirect to the ../var/stuff/my-project/public folder and everything will be fine without chaning anything in your laravel code. ( anything but .env )
So the actual problem is that your domain points to the folder public_html, instead of the public folder of your app. However please dont put your app into public_html directly, put it parallell to it and change where the domain points to.
if you give us some information about your hoster we might can provide a guide

Make files not accessible via URL

How can I redirect via .htaccess file, that only the index.html can be accessed via URL.
I already got this:
RewriteEngine on
RewriteBase /
Options +FollowSymlinks
RewriteRule ^/?login/?$ /php/login.php [NC,R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html [L,QSA]
It works fine if somebody types in for example "www.mypage.com/skd/lasnd"
but if somebody types in a file which exists on the webserver, e.g. "www.mypage.com/php/login.php", he will be redirected to that page. How to forbid that?
To be more exact: my JavaScript & PHP scripts should be still allowed to access to every file on my webserver.
These lines:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
are conditions "if REQUEST_FILENAME is NOT a file, if REQUEST_FILENAME is not a directory" and if both are met then RewriteRule is taking place. This is usually to allow "friendly urls" to work and at the same time to not rewrite any images, css etc. You can block access to files with many ways, but you have to take care to not block too much (like said images etc). The simplest approach would be to put your files in subdirectory and add another .htaccess file in that directory with line
Deny From All
This will make httpd reny any request to whatever is in that directory and subdirectories (unless another .htaccess overwrite these rules) while your scripts will be able to access them without a problem.
I strongly recommend do read mod_rewrite docs
EDIT
There's no "my javascript" and "their javascript". There's request and that's all you can tell for sure. You cannot tell which access yours and which is not. "i only want to deny request via typing in the browser adress line" - you can't tell that either. You theoretically could check REFERER, and if there's none set then assume it's direct hit, but REFERER comes from browser so it can be faked as well. And I personally block all REFERERS by default, so all my requests are w/o any REFERER even these not direct. You could try cookies, but again - these can be be grabbed by script and sent back too. The only real option is to Deny from all to these files and "tunel" them thru some sort of script (i.e. PHP) that would do i.e. file() on target file only if user authenticated himself previously using login and password. Any other attempts are broken from the start.
try the following
RewriteRule /.* http://www.new-domain.com/index.html

Resources