I have a front controller in my PHP project. Here is the code;
.htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [PT,L]
</IfModule>
index.php file
<?php
list($url) = explode('?', $_SERVER['REQUEST_URI']);
$url = trim(trim($url), '/');
if(!file_exists('pages/'.$url.'.php')
header('Location: 404.html');
require_once 'inc/head.php';
require_once 'pages/'.$url.'.php';
require_once 'inc/foot.php';
?>
I assumed every requested URL must go through index.php file. But if there is a \ (as %5C) in URL server answer is “Not Found”.
Questions;
- Why there is an exception for
\character? Is there any characters like that? - What is the reqular use of
\character to make Apache search for a file? Why not just ignore? - Where Apache looks and not founds the file?
Note: My system is Windows with Apache 2.2.21 and PHP 5.3.10.
Note2: This is just an example code, so do not offer a better way.
Comment above said it already:On Windows
\is the path separatorSo requesting
'http://localhost/\'on a windows system will be caught by theRewriteCond %{REQUEST_FILENAME} -d, simply your document root, which is a directory.You have inverted the condition, d (
!-d) so apache does not execute the rewrite rule but looks for the default index file, which does not exist, you get a 404Remove the condition “not a existing directory” or add the index.php to the list of defaults
EDIT:
The story I wrote had such a plausible character that I believed it by myself 🙂
Indeed, this is not even Windows but Apache specific.
Because of a
security leak in CGIApache introduced this as a fix many years ago.Instead of processing the request, it immediately returns a
404 Not Found, when you pass either%5C (backslash)or%2F (slash)in the request URL.I was able to reproduce this on a
Apache 2.2.14.If you do not use
CGI( e.g. Perl website ) you can safely disable this “security fix”:This was introduced in Apache 2.0.46, see documentation, setting this variable didn’t work in my
.htaccess, I had to put it into thevhost configandrestart the apacheserver.