RewriteRule 在目录列表期间应用于所有文件

RewriteRule 在目录列表期间应用于所有文件

使用 和Options IndexesLogLevel 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)。但是,它仍然可以为其他子请求调用,例如调用HeaderNameReadmeName与目录列表相关的文件(如果设置了这些指令,无论文件是否存在),所以NS如果这是一个问题,您仍然可以选择在这些指令中包含标志。

它甚至会进入子目录并寻找index.html

这是由于 mod_dir 测试DirectoryIndex文档而导致的。如果不需要,可以禁用它:

DirectoryIndex disabled

参考:

相关内容