У меня проблема, которая должна быть простой. Я хочу применить группу директив конфигурации к одному файлу (в данном случае myfile.html
в DocumentRoot). Также могут быть подкаталоги, содержащие myfile.html
, они должны не получать конфигурацию. Я также хочу сделать это без , используя Location
или LocationMatch
.
Я придумал следующее
DocumentRoot "/home/amoe/opt/httpd/htdocs"
<DirectoryMatch "^/home/amoe/opt/httpd/htdocs$">
<Files "myfile.html">
ExpiresActive on
ExpiresDefault A10
</Files>
</DirectoryMatch>
Однако Expires
заголовок не устанавливается при запросе /myfile.html
. Добавление косой черты в конце DirectoryMatch
, кажется, не имеет значения.
Вы можете предположить, что я хочу сделать это без Location
по академическим причинам. (Edit: Также, цитируя документацию, Важно никогда не использовать при попытке ограничить доступ к объектам в файловой системе. )
Я нашел единственный способ выполнить эту работу, используя следующее:
<DirectoryMatch ^/home/amoe/opt/httpd/htdocs/[^/]+$>
<Files "test.html">
ExpiresActive on
ExpiresDefault A10
</Files>
</DirectoryMatch>
Я считаю, что дополнительные [^ /] +
не требуются чтобы заставить это работать, см. ниже полное объяснение того, как я пришел к такому выводу, и поэтому я считаю, что это ошибка в Apache.
Все нижеследующее основано на запущенной среде Ubuntu 16.04.1 LTS. Apache 2.4.23 с тестовыми файлами в следующих местах:
/path/test/test.html
/path/test/noheader-test.html
/path/test/child/test.html
/path/test/child/grandchild/test.html
Сначала я попробовал несколько различных вариантов регулярных выражений, все из которых не соответствовали:
<DirectoryMatch ^/path/test$>
<DirectoryMatch ^/path/test/$>
<DirectoryMatch /path/test/$>
<Directory ~ ^/path/test$>
<Directory ~ ^/path/test/$>
<Directory ~ /path/test/$>
Однако я обнаружил, что если вы опустите привязку EOL ( $
), тогда он соответствует:
<DirectoryMatch ^/path/test/>
<Files "test.html">
ExpiresActive on
ExpiresDefault A10
</Files>
</Directory>
Однако этот, конечно, соответствует файлам test.html
во всех подкаталогах:
/path/test/test.html
- Истекает отправленный заголовок /path/test/noheader-test.html
-нет Отправлен заголовок Expires /path/test/child/test.html
- Expires заголовок отправлен /path/test/child/grandchild/test.html
- Expires заголовок отправлен Как будто в пути было что-то еще, что регулярное выражение не соответствовало, потому что, когда я изменил регулярное выражение на ^ / your / path / test /.+$
, оно совпало.
Чтобы узнать, что это за недостающая часть пути, я использовал группу захвата регулярных выражений и директиву Header
, чтобы Apache сообщал мне, чего не хватает, например:
<DirectoryMatch ^/path/test/(?<MISSINGPART>.+)$>
<Files "test.html">
Header add X-TEST "expr=%{env:MATCH_MISSINGPART}"
</Files>
</DirectoryMatch>
Это дало следующее заголовки:
/path/test/test.html
- x-test: "test.html"
/path/test/noheader-test.html
- заголовок не отправлен /path/test/child/test.html
- x-test: "child / test.html"
/path/test/child/grandchild/test.html
- x-test: "child / grandchild / test.html"
Это говорит о том, что DirectoryMatch
также совпадает с именем файла?!
В системе отслеживания ошибок Apache ошибка 41867 несколько соответствует этому описанию, поэтому могу объяснить это (я также тестировал это без вложенной директивы
, и значения заголовков остались прежними)
Итак, чтобы доказать это, я попробовал заменив test.html
в регулярное выражение следующим образом:
<DirectoryMatch "^/path/test/test.html$">
<Files "test.html">
Header add X-TEST "Match"
</Files>
</DirectoryMatch>
Не был возвращен заголовок X-TEST
.
Однако это означало, что регулярное выражение может соответствовать всему, что не является каталогом после каталога, который мы хотим сопоставить, например:
<DirectoryMatch "^/path/test/[^/]+$">
<Files "test.html">
ExpiresActive on
ExpiresDefault A10
</Files>
</DirectoryMatch>
Это дает заголовок во всех желаемых местах:
/path/test/test.html
- Истекает заголовок отправлен /path/test/noheader-test.html
- заголовок Expires не отправлен /path/test/child/test.html
- заголовок Expires не отправлен / path / test / child / grandchild / test.html
- заголовок Expires не отправлен