使用 和Options Indexes
,LogLevel rewrite:trace6
我看到我的重写规则应用于所列目录中的所有文件。它甚至进入子目录并查找index.html
。这对性能不利。这真的有必要吗?如何禁用它?在实际配置中,我有一个“prg” RewriteMap
,该程序在其 STDIN 上接收所有列出的文件。
使用以下最低配置即可重现此问题:
环境:
- OpenSUSE Tumbleweed
- apache2-2.4.51-1.1.x86_64
配置:
/etc/apache2/conf.d/test.conf
(请参阅下面完整的 httpd.conf)LoadModule rewrite_module /usr/lib64/apache2/mod_rewrite.so LogLevel debug rewrite:trace6 <Directory "/srv/www/htdocs/test"> Options Indexes FollowSymLinks RewriteEngine on RewriteRule badrule neverhappen </Directory>
命令:
mkdir /srv/www/htdocs/test
touch /srv/www/htdocs/test/zzzzzzzzzzzzzzzzzzzzz{a..z}
systemctl restart apache2
tail -F /var/log/apache2/error_log &
curl -s -o /dev/null http://localhost/test/
输出:
[rid#556dab9a2060/initial] [perdir /srv/www/htdocs/test/] strip per-dir prefix: /srv/www/htdocs/test/ ->
[rid#556dab9a2060/initial] [perdir /srv/www/htdocs/test/] applying pattern 'badrule' to uri ''
[rid#556dab9a2060/initial] [perdir /srv/www/htdocs/test/] pass through /srv/www/htdocs/test/
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] strip per-dir prefix: /srv/www/htdocs/test/index.html -> index.html
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] applying pattern 'badrule' to uri 'index.html'
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] pass through /srv/www/htdocs/test/index.html
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] strip per-dir prefix: /srv/www/htdocs/test/index.html.var -> index.html.var
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] applying pattern 'badrule' to uri 'index.html.var'
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] pass through /srv/www/htdocs/test/index.html.var
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] strip per-dir prefix: /srv/www/htdocs/test/HEADER.html -> HEADER.html
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] applying pattern 'badrule' to uri 'HEADER.html'
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] pass through /srv/www/htdocs/test/HEADER.html
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] strip per-dir prefix: /srv/www/htdocs/test/zzzzzzzzzzzzzzzzzzzzza -> zzzzzzzzzzzzzzzzzzzzza
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] applying pattern 'badrule' to uri 'zzzzzzzzzzzzzzzzzzzzza'
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] pass through /srv/www/htdocs/test/zzzzzzzzzzzzzzzzzzzzza
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] strip per-dir prefix: /srv/www/htdocs/test/zzzzzzzzzzzzzzzzzzzzzb -> zzzzzzzzzzzzzzzzzzzzzb
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] applying pattern 'badrule' to uri 'zzzzzzzzzzzzzzzzzzzzzb'
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] pass through /srv/www/htdocs/test/zzzzzzzzzzzzzzzzzzzzzb
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] strip per-dir prefix: /srv/www/htdocs/test/zzzzzzzzzzzzzzzzzzzzzc -> zzzzzzzzzzzzzzzzzzzzzc
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] applying pattern 'badrule' to uri 'zzzzzzzzzzzzzzzzzzzzzc'
[rid#556dab9a8090/subreq] [perdir /srv/www/htdocs/test/] pass through /srv/www/htdocs/test/zzzzzzzzzzzzzzzzzzzzzc
...
满的httpd.conf
:
# sudo -u nobody /sbin/httpd -d /etc/httpd-test -f /etc/httpd-test/httpd.conf -DFOREGROUND
#
# The following is not needed on SUSE
LoadModule mpm_event_module modules/mod_mpm_event.so
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# The following is not needed on SUSE
LoadModule unixd_module modules/mod_unixd.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule rewrite_module modules/mod_rewrite.so
ErrorLog "|/bin/cat"
LogLevel debug rewrite:trace6
PidFile /dev/shm/httpd-test.pid
ServerName localhost
Listen 8080
DocumentRoot "/srv/www/htdocs"
<Directory "/srv/www/htdocs/test">
Require all granted
Options Indexes FollowSymLinks
RewriteEngine on
RewriteRule badrule neverhappen
</Directory>
答案1
使用 mod_autoindex 生成的目录列表,将针对目录中列出的所有项目触发内部子请求。这在日志中用subreq
(而不是initial
)指示。
您可以RewriteRule
使用NS
( nosubreq
) 标志阻止指令被处理为子请求。例如:
RewriteRule badrule neverhappen [NS]
或者,你可以将RewriteRule
指令移出<Directory>
容器,并将其直接放在容器下<VirtualHost>
。请注意,指令可能需要稍微改变,因为它现在在不同的语境(虚拟主机而不是目录)并更早处理。这自然会阻止对目录列表中的每个项目处理该指令(无需包含标志NS
)。但是,它仍然可以为其他子请求调用,例如调用HeaderName
和ReadmeName
与目录列表相关的文件(如果设置了这些指令,无论文件是否存在),所以NS
如果这是一个问题,您仍然可以选择在这些指令中包含标志。
它甚至会进入子目录并寻找
index.html
这是由于 mod_dir 测试DirectoryIndex
文档而导致的。如果不需要,可以禁用它:
DirectoryIndex disabled
参考: