Spec-Zone.ru › Apache HTTP Server

Технические подробности Apache mod_rewrite

В этом документе рассматриваются некоторые технические подробности mod_rewrite и сопоставления URL.

Фазы API

Сервер Apache HTTP Server обрабатывает запросы в несколько фаз. В каждой из этих фаз может вызываться один или несколько модулей для обработки соответствующей части жизненного цикла запроса. К фазам относятся, например, преобразование URL в имя файла, аутентификация, авторизация, обработка содержимого и ведение журнала. (Это не исчерпывающий список.)

mod_rewrite действует в двух из этих фаз (или «хуках», как их часто называют), влияя на то, как могут переписываться URL.

Сначала он использует хук преобразования URL в имя файла, который вызывается после чтения HTTP-запроса, но до начала любой авторизации. Затем он использует хук Fixup, который вызывается после фаз авторизации и после чтения файлов конфигурации для отдельных каталогов (файлов .htaccess), но до вызова обработчика содержимого.

Таким образом, после поступления запроса и определения соответствующего сервера или виртуального хоста механизм переписывания начинает обрабатывать все директивы mod_rewrite, указанные в конфигурации уровня сервера (то есть в основном файле конфигурации сервера и разделах <Virtualhost>). Это происходит на фазе преобразования URL в имя файла.

Через несколько шагов, когда определены конечные каталоги с данными, применяются директивы конфигурации для отдельных каталогов (файлы .htaccess и блоки <Directory>). Это происходит на фазе Fixup.

В каждом из этих случаев mod_rewrite переписывает REQUEST_URI либо в новый URL, либо в имя файла.

В контексте отдельного каталога (то есть внутри файлов .htaccess и блоков Directory) эти правила применяются после того, как URL уже преобразован в имя файла. Поэтому путь URL, с которым mod_rewrite изначально сопоставляет директивы RewriteRule, — это полный путь файловой системы к преобразованному имени файла, у которого в начале удален путь к текущему каталогу (включая завершающую косую черту).

Для иллюстрации: если правила находятся в /var/www/foo/.htaccess, а обрабатывается запрос для /foo/bar/baz, то подойдет выражение ^bar/baz$.

Если в контексте отдельного каталога выполняется подстановка, создается новый внутренний подзапрос с новым URL, и обработка фаз запроса начинается заново. Если подстановка представляет собой относительный путь, директива RewriteBase определяет префикс пути URL, который добавляется перед подстановкой. В контексте отдельного каталога необходимо создавать правила так, чтобы в конечном счете (в одном из следующих «циклов» обработки правил переписывания для отдельного каталога) подстановка не выполнялась — это позволит избежать зацикливания. (Дополнительные сведения об этой проблеме см. в статье RewriteLooping.)

Из-за дополнительных преобразований URL в контексте отдельного каталога правила переписывания в этом контексте нужно составлять иначе. В частности, помните, что начальная часть пути к каталогу будет удалена из URL, который будут видеть ваши правила переписывания. Для пояснения рассмотрите примеры ниже.

Расположение правила Правило
Раздел VirtualHost RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif"
Файл .htaccess в корне документов RewriteRule "^images/(.+)\.jpg" "images/$1.gif"
Файл .htaccess в каталоге images RewriteRule "^(.+)\.jpg" "$1.gif"

Чтобы лучше понять, как mod_rewrite преобразует URL в разных контекстах, изучите записи журнала, созданные в процессе переписывания.

Обработка набора правил

Когда mod_rewrite вызывается на этих двух фазах API, он считывает настроенные наборы правил из своей структуры конфигурации (которая создается либо при запуске для контекста уровня сервера, либо во время обхода каталогов ядром Apache для контекста отдельного каталога). Затем механизм переписывания URL запускается с содержащимся в ней набором правил (одним или несколькими правилами вместе с их условиями). Сам механизм переписывания URL работает совершенно одинаково в обоих контекстах конфигурации. Различается только обработка конечного результата.

Порядок правил в наборе важен, поскольку механизм переписывания обрабатывает их особым (и не вполне очевидным) образом. Правило таково: механизм переписывания проходит по набору правил одно за другим (директивы RewriteRule), а при совпадении конкретного правила по желанию проходит по соответствующим существующим условиям (директивы RewriteCond). По историческим причинам условия указываются первыми, поэтому последовательность выполнения получается несколько громоздкой. Подробнее см. на рисунке 1.

Flow of RewriteRule and RewriteCond matching
Рисунок 1:Порядок выполнения набора правил переписывания

Сначала URL сопоставляется с шаблоном каждого правила. Если совпадения нет, mod_rewrite немедленно прекращает обработку этого правила и переходит к следующему. Если шаблон совпадает, mod_rewrite ищет соответствующие условия правила (директивы RewriteCond, расположенные непосредственно перед RewriteRule в конфигурации). Если таких условий нет, он подставляет вместо URL новое значение, сформированное из строки подстановки, и продолжает обход правил. Если же условия есть, начинается внутренний цикл их обработки в указанном порядке. Для условий логика отличается: мы не сопоставляем шаблон с текущим URL. Вместо этого сначала создается строка тестового значения путем подстановки переменных, обратных ссылок, результатов поиска в таблицах соответствий и т. д., а затем с ней сопоставляется шаблон условия. Если шаблон не совпадает, весь набор условий и соответствующее правило считаются неудачными. Если шаблон совпадает, обрабатывается следующее условие, пока условия не закончатся. Если совпали все условия, обработка продолжается подстановкой вместо URL значения подстановки.

© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/rewrite/tech.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API