<Location> 和部分 non-existing 目录?
<Location> and partially non-existing directory?
在 Apache 2.2 和 2.4 中,<Location /foo>
指令出现奇怪的行为并请求 URL http://example.com/foo/non-existing 不匹配。
假设我的配置是:
<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}:: ^(/.+)/(.*)::$
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>
和DocumentRoot目录/var/www/apache.test
有以下内容:
/var/www/apache.test
├── bar
│ └── baz
├── foo
│ └── qux
└── index.php
请注意,/foo
目录实际存在于 DocumentRoot 中,而目录 /foo/non-existing
不存在。
测试各种 URLs 使用: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 |
我认为 <Location "/foo">
会为 http://apache.test/foo/* 的任何请求添加一个 header。
我得到 <Directory>
用于文件系统项,<Location>
用于动态 URL。所以我也尝试使用 <Directory>
和 <Location>
来涵盖所有情况:
<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}:: ^(/.+)/(.*)::$
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>
我得到以下结果:
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 | |
我也试过只有一个 <Location>
专用于 "/foo/non-existing/":
<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}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]
</Directory>
<Location "/foo/non-existing">
Header set X-FooNonExisting "true"
</Location>
</VirtualHost>
但是http://apache.test/foo/non-existing还是不会return X-FooNonExisting
header.
在我看来,Apache 以某种方式无法将请求与 /foo/non-existing/
匹配,因为请求的资产既针对现有目录 ("/foo") 又针对 virtual-subdir ("non-existing").
我的最终目标是在所有 HTTP 响应(对于这个 VirtualHost
)中设置一个给定的 header,但那些响应请求的
http://example.com/foo/qux/non-existing/*.
这是因为倒数第二个重写不匹配但最后一次重写匹配,导致在 mod_headers 过滤器运行时您的请求不再针对 /foo/ 吗?
在 Apache 2.2 和 2.4 中,<Location /foo>
指令出现奇怪的行为并请求 URL http://example.com/foo/non-existing 不匹配。
假设我的配置是:
<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}:: ^(/.+)/(.*)::$
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>
和DocumentRoot目录/var/www/apache.test
有以下内容:
/var/www/apache.test
├── bar
│ └── baz
├── foo
│ └── qux
└── index.php
请注意,/foo
目录实际存在于 DocumentRoot 中,而目录 /foo/non-existing
不存在。
测试各种 URLs 使用: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 |
我认为 <Location "/foo">
会为 http://apache.test/foo/* 的任何请求添加一个 header。
我得到 <Directory>
用于文件系统项,<Location>
用于动态 URL。所以我也尝试使用 <Directory>
和 <Location>
来涵盖所有情况:
<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}:: ^(/.+)/(.*)::$
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>
我得到以下结果:
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 | |
我也试过只有一个 <Location>
专用于 "/foo/non-existing/":
<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}:: ^(/.+)/(.*)::$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]
</Directory>
<Location "/foo/non-existing">
Header set X-FooNonExisting "true"
</Location>
</VirtualHost>
但是http://apache.test/foo/non-existing还是不会return X-FooNonExisting
header.
在我看来,Apache 以某种方式无法将请求与 /foo/non-existing/
匹配,因为请求的资产既针对现有目录 ("/foo") 又针对 virtual-subdir ("non-existing").
我的最终目标是在所有 HTTP 响应(对于这个 VirtualHost
)中设置一个给定的 header,但那些响应请求的
http://example.com/foo/qux/non-existing/*.
这是因为倒数第二个重写不匹配但最后一次重写匹配,导致在 mod_headers 过滤器运行时您的请求不再针对 /foo/ 吗?