Apache2 <;地点>;和部分不存在的目录?

Apache2 <;地点>;和部分不存在的目录?,apache2,Apache2,在Apache2.2和2.4中,我发现指令有奇怪的行为,请求的URL不匹配 假设我的配置是: <VirtualHost *:80> DocumentRoot "/var/www/apache.test" ServerName apache.test <Directory "/var/www/apache.test"> Options Indexes FollowSymLinks AllowOverride None

在Apache2.2和2.4中,我发现指令
有奇怪的行为,请求的URL不匹配

假设我的配置是:

<VirtualHost *:80>
   DocumentRoot "/var/www/apache.test"
   ServerName apache.test

   <Directory "/var/www/apache.test">
       Options Indexes FollowSymLinks
       AllowOverride None
       Order allow,deny
       Allow from all

       # Catch non-existing resources with index.php:
       RewriteEngine On
       RewriteCond %{REQUEST_FILENAME} -s [OR]
       RewriteCond %{REQUEST_FILENAME} -l [OR]
       RewriteCond %{REQUEST_FILENAME} -d
       RewriteRule ^.*$ - [L]
       RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
       RewriteRule ^(.*) - [E=BASE:%1]
       RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]
   </Directory>

   <Location "/">
       Header set X-All "true"
   </Location>

   <Location "/foo">
       Header set X-Foo "true"
   </Location>
</VirtualHost>
请注意,
/foo
目录实际存在于DocumentRoot中,而目录
/foo/不存在的
不存在

使用:
curl-D-http://apache.test/ -o/dev/null-s | grep-F“X-”

我得到以下结果:

URL                    | X-All? | X-Foo?
-----------------------|--------|-------
/                      |      X |
/bar/                  |      X |
/bar/baz/              |      X |
/bar/non-existing/     |      X |
/non-existing/         |      X |
/foo/                  |      X |      X
/foo/qux/              |      X |      X
/foo/non-existing/     |      X |
/foo/qux/non-existing/ |      X |
URL                    | X-AllDir? | X-AllLoc? | X-FooDir? | X-FooLoc?
-----------------------|-----------|-----------|-----------|----------
/                      |         X |         X |           |
/bar/                  |         X |         X |           |
/bar/baz/              |         X |         X |           |
/bar/non-existing/     |         X |         X |           |
/non-existing/         |         X |         X |           |
/foo/                  |         X |         X |         X |         X
/foo/qux/              |         X |         X |         X |         X
/foo/non-existing/     |         X |         X |           |
/foo/qux/non-existing/ |         X |         X |           |
我以为
会为*的任何请求添加一个标题

我得到的
用于文件系统项,
用于动态URL。因此,我也尝试使用
来涵盖所有情况:

<VirtualHost *:80>
   DocumentRoot "/var/www/apache.test"
   ServerName apache.test

   <Directory "/var/www/apache.test">
       Options Indexes FollowSymLinks
       AllowOverride None
       Order allow,deny
       Allow from all

       # Catch non-existing resources with index.php:
       RewriteEngine On
       RewriteCond %{REQUEST_FILENAME} -s [OR]
       RewriteCond %{REQUEST_FILENAME} -l [OR]
       RewriteCond %{REQUEST_FILENAME} -d
       RewriteRule ^.*$ - [L]
       RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
       RewriteRule ^(.*) - [E=BASE:%1]
       RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]

       Header set X-AllDir "true"
   </Directory>
   <Location "/">
       Header set X-AllLoc "true"
   </Location>

   <Directory "/var/www/apache.test/foo">
       Header set X-FooDir "true"
   </Location>
   <Location "/foo">
       Header set X-FooLoc "true"
   </Location>
</VirtualHost>
我还尝试了只将
专用于“/foo/不存在/”:


DocumentRoot“/var/www/apache.test”
ServerName.apache.test
选项索引跟随符号链接
不允许超限
命令允许,拒绝
通融
#使用index.php捕获不存在的资源:
重新启动发动机
RewriteCond%{REQUEST_FILENAME}-s[或]
RewriteCond%{REQUEST_FILENAME}-l[或]
RewriteCond%{REQUEST_FILENAME}-d
重写规则^.*$-[L]
RewriteCond%{REQUEST_URI}:$1^(/.+)/(.*):\2$
重写规则^(.*)-[E=基:%1]
重写规则^(.*)$%{ENV:BASE}/index.php[L]
标题集X-fooon不存在“true”
但是仍然不会返回
X-fooonoexisting

在我看来,Apache在某种程度上无法将请求与
/foo/non-existing/
匹配,因为请求的资产同时用于现有目录(“/foo”)和虚拟子目录(“non-existing”)

我的最终目标是在所有HTTP响应(对于这个
VirtualHost
)中设置一个给定的头,但是那些响应
*.

这是因为您的倒数第二次重写不匹配,但您的最后一次重写不匹配,导致您的请求在mod_header筛选器运行时不再是/foo/。

我可以在Apache失去请求的实际URL跟踪之前运行mod_header吗?您可以打“early”在Header指令的末尾,它运行得更早。另一个修复方法是将您的重写移出每个目录范围,这样您的重写不会隐式地导致服务器处理一个新的URL。我不明白“slap early”是什么意思。重写是针对整个DocumentRoot的,所有请求都需要重写(以使
index.php
处理它们),我可以将它们移动到哪里,以便始终应用它们,而不会妨碍标头?是否有相当于
的指令严格依赖于请求的URL,而不管它是如何重写的?我已经找到了关于
Header
指令的“早期”参数的文档(我不知道您实际上是在告诉我要做的步骤;)。不幸的是,
early
中都不起作用。将其从目录/位置中拉出并使用表达式语法作为条件,如何?这应该让它在mod_重写之前运行。
URL                    | X-AllDir? | X-AllLoc? | X-FooDir? | X-FooLoc?
-----------------------|-----------|-----------|-----------|----------
/                      |         X |         X |           |
/bar/                  |         X |         X |           |
/bar/baz/              |         X |         X |           |
/bar/non-existing/     |         X |         X |           |
/non-existing/         |         X |         X |           |
/foo/                  |         X |         X |         X |         X
/foo/qux/              |         X |         X |         X |         X
/foo/non-existing/     |         X |         X |           |
/foo/qux/non-existing/ |         X |         X |           |
<VirtualHost *:80>
   DocumentRoot "/var/www/apache.test"
   ServerName apache.test

   <Directory "/var/www/apache.test">
       Options Indexes FollowSymLinks
       AllowOverride None
       Order allow,deny
       Allow from all

       # Catch non-existing resources with index.php:
       RewriteEngine On
       RewriteCond %{REQUEST_FILENAME} -s [OR]
       RewriteCond %{REQUEST_FILENAME} -l [OR]
       RewriteCond %{REQUEST_FILENAME} -d
       RewriteRule ^.*$ - [L]
       RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
       RewriteRule ^(.*) - [E=BASE:%1]
       RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]
   </Directory>

   <Location "/foo/non-existing">
       Header set X-FooNonExisting "true"
   </Location>
</VirtualHost>