URL中使用反斜杠有什么用?

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 separator So requesting 'http://localhost/\' on a windows system will be caught by the RewriteCond %{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 404

Remove 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 CGI Apache 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":

AllowEncodedSlashes On

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 the vhost config and restart the apache server.