Отладка mod_rewrite показывает непредвиденный порядок событий REWRITE_COND - PullRequest
1 голос
/ 02 февраля 2020

Я заметил нечто неожиданное при отладке правил перезаписи: кажется, что порядок событий таков, что Apache обрабатывает правило, а затем задним числом применяет к нему предыдущие условия. Это как-либо разработано, или я что-то неправильно понимаю?

Вот простой пример правила перезаписи в моем файле .htaccess. На самом деле он ничего полезного не делает - это всего лишь пример.

    RewriteEngine on
    Options FollowSymLinks
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . / [L]

А вот и полученная трассировка (сильно отредактированная для удобства чтения)

[...redacted...] init rewrite engine with requested uri /test.html
[...redacted...] pass through /test.html
[...redacted...] [perdir /var/www/html/] strip per-dir prefix: /var/www/html/test.html -> test.html
[...redacted...] [perdir /var/www/html/] applying pattern '.' to uri 'test.html'
[...redacted...] [perdir /var/www/html/] RewriteCond: input='/var/www/html/test.html' pattern='!-f' => not-matched
[...redacted...] [perdir /var/www/html/] pass through /var/www/html/test.html

Обратите внимание, что «RewriteCond» применяется после шаблон применяется. Конечный результат - сквозной, который является правильным (поскольку файл действительно существует), так что это не имеет значения. Я не мог найти ничего об этом в документации.

1 Ответ

1 голос
/ 03 февраля 2020

кажется, что порядок событий таков, что Apache обрабатывает правило, а затем задним числом применяет к нему предыдущие условия. Это как задумано, или я что-то неверно истолковываю?

Да, вот как это работает.

RewriteRule должен сначала совпадать. Только в этом случае RewriteCond-itions оцениваются. Если они совпадают, выполняется перезапись.

Это не так четко указано на странице руководства, где описывается синтаксис RewriteCond и -Rule; https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond просто говорит,

Следующее правило используется только в том случае, если текущее состояние URI соответствует его шаблону, и , если эти условия встречаются.

Теперь вы могли бы подразумевать порядок обработки из этого возможно (если вы читаете его в «логическом» порядке слева направо), но это не очень явно .

Но https://httpd.apache.org/docs/2.4/rewrite/intro.html#regex говорит,

Regex Back-Reference Availability
Здесь следует помнить одну важную вещь: всякий раз, когда вы используете скобки в В шаблоне или в одном из CondPattern создаются внутренние ссылки, которые можно использовать со строками $ N и% N (см. Ниже). Они доступны для создания параметра Substitution для RewriteRule или параметра TestString для RewriteCond.

Захваты в шаблонах RewriteRule (нелогично) доступны для всех предшествующих директив RewriteCond, , поскольку вычисляется выражение RewriteRule перед отдельными условиями.

(выделите в конце мной.)

Так что в этом месте вы обнаружите, что это поведение явно упомянуто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...