Apache-2.4

RewriteRule 在目錄列表期間應用於所有文件

  • October 16, 2021

我看到我的重寫規則適用於列出的目錄中的所有文件Options IndexesLogLevel rewrite:trace6它甚至進入子目錄並查找index.html. 這對性能不利。這真的有必要嗎?如何禁用它?在實際配置中,我有一個“prg” RewriteMap,該程序在其 STDIN 上接收所有列出的文件。

使用此最低配置可以重現該問題:

環境:

  • OpenSUSE 風滾草
  • 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>

使用 mod_autoindex 生成的目錄列表,會為目錄中的所有列出的項目觸發內部子請求。這在日誌中用subreq(而不是initial)表示。

您可以RewriteRule使用NS( nosubreq) 標誌防止為子請求處理指令。例如:

RewriteRule badrule neverhappen [NS]

或者,您可以將RewriteRule指令移出<Directory>容器並將其直接放在容器下方<VirtualHost>。請注意,該指令可能需要稍作更改,因為它現在在不同的上下文中工作(virtualhost而不是directory)並且更早處理。這自然會阻止為目錄列表中的每個項目處理指令(無需包含NS標誌)。但是,它仍然可以為其他子請求呼叫,例如HeaderNameReadmeName目錄列表關聯的文件的呼叫(如果設置了這些指令,則無論文件是否存在),因此您仍然可以選擇包含NS如果這是一個問題,請在這些指令上標記。

它甚至進入子目錄並尋找index.html

這是由 mod_dir 測試DirectoryIndex文件引起的。如果不需要,則可以禁用它:

DirectoryIndex disabled

參考:

引用自:https://serverfault.com/questions/1080518