I am trying to catch ALL requests to files in a directory and it's subdirectories and to route them to one single file in a subdirectory. Here is what the htaccess directives look like:
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
# Excluding one directory
RewriteRule ^(excludedfolder)($|/).*\.(php)$ - [L]
# Redirect everything that is html or php to magicscript
RewriteRule \.(php|html|phps)$ /excludedfolder/magicscript.php [L]
RewriteRule ^/?$ /excludedfolder/magicscript.php [L]
RewriteRule ^/?index.php$ /excludedfolder/magicscript.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . excludedfolder/magicscript.php [L]
</IfModule>
This works on the mostpart of systems.
If i call someserver.com/testfile.php, it is properly routed to magicfile.php. If i call someserver.com/testfile, it also is properly routed to magicfile.php. The same for subfolders: If i call someserver.com/somefolder/testfile.php or someserver.com/somefolder/testfile, it is properly routed to magicfile.php.
But on some servers, it is not allowed to set the Options -MultiViews which causes the server to completely fail. If I remove the option, it still works, but it doesn't if I don't add the file extension.
How to redirect non existing files to magicfiles.php without having to use Options -MultiViews? Or how to detect if it is allowed to set the option in php?
Thanks for your help!
Maybe the server do not support Options -MultiViews http://httpd.apache.org/docs/2.2/mod/core.html#options
Related
I am trying to implement SEO friendly URLs using .htaccess and PHP.
I have achieved 90% of my goal and struggling with just one use case.
Here is what happing, when I access the following url
http://somesite.com/cms/movies/tarzan
it lands on
my-handler.php?the_url=movies/tarzan
This is perfect and that is what I want because then I manage it myself. The real problem is when I don't provide any slugs, then it lists the directory (means show all files and folders in it)
http://somesite.com/cms/
Can someone please help me fix following .htaccess content, so that even if I don't provide slug it should still be handled by my-handler.php instead of lisiting full directory?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /cms/
RewriteCond %{REQUEST_FILENAME} !/(admin|css|fonts|ico|include|js)/
RewriteRule ^my-handler\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /cms/my-handler.php?the_url=$1 [L,QSA]
</IfModule>
Solved
As per #Roman suggestion, I added the following to the above listing and it solved my problem. Plus I do not have to compromise on accessing physical directories RewriteCond %{REQUEST_FILENAME} !-d
DirectoryIndex my-handler.php
At first you have to set the DirectoryIndex to handle every request which points to / with your my-handler.php. This can be done by adding the line to your .htaccess
DirectoryIndex my-handler.php
To disable the directory listing, you have to forbid the listing by adding the following line to your .htaccess
Options -Indexes
Remember that this configuration is per .htaccess and just for the directory you are placing the file in. If you want to make changes for your whole webserver, you can edit the httpd.conf and search for
Options Indexes
and remove the Indexes option.
Documentation
The listing is provided by the mod_autoindex module.
Nice side-fact
If you just want to disable the listing of specific file-types like .env or .php files, you can add the option IndexIgnore *.php to you .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /cms/
RewriteCond %{REQUEST_FILENAME} !/(admin|css|fonts|ico|include|js)/
RewriteRule ^my-handler\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css|json|woff|ttf)
RewriteRule ^(.*)$ /cms/my-handler.php?the_url=$1 [L,QSA]
</IfModule>
I have done my project using laravel. I want to upload my project on 1and1. I set my directory structure on 1and1 is as '/directory' which contains index.html file which links to the other page in /directory/EngageV1/public/auth/login. but when I visits this page I am getting the error page as,
Multiple Choices
The document name you requested (/index.php) could not be found on this server. However, we found documents with names similar to the one you requested.
Available documents:
/index.html (common basename)
Please consider informing the owner of the referring page about the broken link.
My .htaccess file looks like,
<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>
If enter url as /directory/EngageV1/public/ then it shows me the welcome page which I have set in routes.php file for route as '/'. Only this page works fine,I don't know what to do, Please give any suggestion.
Replace default contents in your .htaccess file under your the public
folder with the following.
RewriteBase /
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
If you still have problems look at this tutorial about how to deploy a Laravel webapp to 1and1
I know this is is an very old topic, but it took us some time today to find out what's going wrong on an old 1and1 (now Ionos) server. Turned out, the "multiple choices" page doesn't com from Option +MultiViews / mod_negotiation, but from a module called mod_speling that's running there by default. You can disable it in the .htaccess file:
<IfModule mod_speling.c>
CheckSpelling off
</IfModule>
In the past, I have got this working no problems at all, but for some reason on my new server I just can't get it to work.
I have the following .htaccess file in the root of my application
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
I have also enabled mod_rewrite and have confirmed this with php_info()
my site is located at /var/www/html/test
Is it possible that although mod_rewrite is enabled that it is not working and if so, how can I test it?
On some server implementations, you'll need to wrap it within <IfModule> tags.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
Also check your httpd.conf file to ensure it has:
Options FollowSymLinks
AllowOverride All
It'd also be worth checking to makesure the .htaccess file isn't being overridden by another .htaccess file.
A simple way to test if .htaccess is working
Simply put the following in your .htaccess file:
deny from All
What this does is deny access to your site from everyone. If you are presented with a 403 forbidden when trying to access the site - the .htaccess file is being included. If not - see above.
I use this on my codeigniter setup
RewriteEngine on
# prevent these directories from hitting CI
RewriteCond $1 !^(index\.php|images|assets|robots\.txt|crossdomain\.xml)
# route everything else to the index.php
RewriteRule ^/(.*)$ /index.php/$1 [QSA]
(my setup is done in the virtualhost of .conf and not in .htaccess, though they are usually about the same configuration)
I try to make a site using Laravel. When I put Laravel to "www" folder and browse
localhost/laravel/public
then I get a internal server error.
In error log display the following message.
/var/www/laravel/public/.htaccess: Options not allowed here
before put a post I saw similar problem here https://stackoverflow.com/questions/21097240/ and I didn't see any solution.
This is my .htaccess file
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
You have a .htaccess file in the directory /var/www/laravel/public with an Options directive in the wrong place.
You can only use the Options directive in a <directory> block.
You need to remove it, move it to the correct place or otherwise edit the file to correct the error.
See the Apache reference here
.htaccess looks like this:
Options +FollowSymLinks +ExecCGI
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.bmp|\.ico)$
RewriteRule ^(.*)$ entryPoint.php [QSA]
</IfModule>
this enforces all request running though entryPoint.php. This processes all files, redirects, etc. Images are free to go, there can be direct references to them. But what about CSS, JS files? I cant add exceptions - because it would reveal the directory structure. All I want is:
script src="ds.jss" while they can be at "js/" or "module/x/js/". Same with CSS.
I understand I can do it with entryPoint.php: file_get_contents and outputs. It does work, but its too slow. First we tried it with pictures too.
How to enable a "direct access"?
Options +FollowSymLinks +ExecCGI
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ entryPoint.php [QSA]
</IfModule>
Try adding these rewrite conditions...
If you don't want to do that within the php file, you need to add a rule:
Options +FollowSymLinks +ExecCGI
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^ds\.jss$ module/x/ds.jss [L]
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.bmp|\.ico)$
RewriteRule ^(.*)$ entryPoint.php [QSA]
</IfModule>
The important part is the L flag which stands for Last Docs. It will prevent the other rules to run.
If you want to resolve the filename dynamically but you don't want to use PHP to provide the actual file but your apache server, you can still use PHP to resolve the filename by creating a dynamic rewrite map Docs, search for External Rewriting Program.