Назад | Перейти на главную страницу

mod_rewrite REQUEST_FILENAME не содержит абсолютного пути

У меня проблема с операцией тестирования файла в записи 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]