У меня проблема с операцией тестирования файла в записи mod_rewrite RewriteCond, которая проверяет, %{REQUEST_FILENAME}
существуют. Кажется, что скорее, чем %{REQUEST_FILENAME}
будучи абсолютным путем, я получаю путь, уходящий корнями в DocumentRoot
вместо.
У меня это внутри <VirtualHost>
блок в моей конфигурации apache 2.2.9:
RewriteEngine on
RewriteLog /tmp/rewrite.log
RewriteLogLevel 5
#push virtually everything through our dispatcher script
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([^/]*)/?([^/]*) /dispatch.php?_c=$1&_m=$2 [qsa,L]
Это правило является достаточно распространенной идиомой для маршрутизации запросов к несуществующим файлам или каталогам через скрипт. Проблема в том, что он срабатывает, даже если файл делает существует.
Если я удалю правило, я могу запросить обычные файлы. Но при наличии правила эти запросы направляются на dispatch.php.
Вот что я вижу в rewrite.log
init rewrite engine with requested uri /test.txt
applying pattern '^/([^/]*)/?([^/]*)' to uri '/test.txt'
RewriteCond: input='/test.txt' pattern='!-f' => matched
RewriteCond: input='/test.txt' pattern='!-d' => matched
rewrite '/test.txt' -> '/dispatch.php?_c=test.txt&_m='
split uri=/dispatch.php?_c=test.txt&_m= -> uri=/dispatch.php, args=_c=test.txt&_m=
local path result: /dispatch.php
prefixed with document_root to /path/to/my/public_html/dispatch.php
go-ahead with /path/to/my/public_html/dispatch.php [OK]
Итак, мне кажется, что REQUEST_FILENAME представляется как путь от корня документа, а не от корня файловой системы, что, вероятно, является причиной сбоя оператора проверки файла.
Любые указатели на решение этой проблемы с благодарностью получены ...
Мне тоже потребовалось время, чтобы узнать, но причина указана в документация по mod_rewrite:
"REQUEST_FILENAME
Полный путь локальной файловой системы к файлу или сценарию, соответствующему запросу, если он уже был определен сервером в то время REQUEST_FILENAME
упоминается. В противном случае, например, при использовании в контекст виртуального хоста, то же значение, что и REQUEST_URI
. "
Вот почему это работает в .htaccess
но не в файле conf vhost. (И именно поэтому добавление DOCUMENT_ROOT помогает обойти проблему).
Я решил это, явно записав корень документа в условие
RewriteCond /path/to/my/public_html%{REQUEST_FILENAME} !-f
RewriteCond /path/to/my/public_html%{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(/pathinfo/|/pathinfo)(.*)$
RewriteRule .* %{DOCUMENT_ROOT}%{REQUEST_URI} [L]