Spec-Zone.ru › Apache HTTP Server

Введение в Apache mod_rewrite

Этот документ дополняет mod_rewrite справочную документацию. В нём описаны основные понятия, необходимые для использования mod_rewrite. В других документах эта тема рассматривается подробнее, но этот документ поможет новичкам сделать первые шаги.

Введение

Модуль Apache mod_rewrite — очень мощный и сложный модуль, позволяющий изменять URL. С его помощью можно выполнять практически любые необходимые преобразования URL. Однако он довольно сложен и может отпугнуть новичков. Кроме того, правила переписывания нередко воспринимают как магические заклинания и используют, не понимая, что именно они делают.

Этот документ призван дать достаточно базовых знаний, чтобы вы понимали дальнейшее изложение, а не просто слепо копировали примеры.

Помните, что для многих распространённых задач по изменению URL не нужны все возможности и сложность mod_rewrite. Для простых задач см. mod_alias и документацию о сопоставлении URL с файловой системой.

Наконец, прежде чем продолжить, настройте уровень ведения журнала mod_rewrite на один из уровней трассировки с помощью директивы LogLevel. Хотя при этом может выводиться огромный объём информации, она незаменима при отладке проблем с конфигурацией mod_rewrite, поскольку позволяет точно увидеть, как обрабатывается каждое правило.

Регулярные выражения

В mod_rewrite используется синтаксис регулярных выражений, совместимых с Perl. В этом документе мы не пытаемся подробно описать регулярные выражения. Для этого рекомендуем обратиться к справочным страницам PCRE, справочной странице регулярных выражений Perl и книге «Mastering Regular Expressions» Джеффри Фридла.

В этом документе мы постараемся дать достаточно знаний о регулярных выражениях, чтобы вы могли начать работу, не перегружая вас информацией. Надеемся, что RewriteRule будут для вас научными формулами, а не магическими заклинаниями.

Синтаксис регулярных выражений

Ниже приведены минимальные элементы, необходимые для составления регулярных выражений и RewriteRule. Это, конечно, не полный перечень синтаксических конструкций регулярных выражений, но с него удобно начать: он поможет читать простые регулярные выражения и составлять собственные.

Символ Значение Пример
. Соответствует любому одиночному символу c.t соответствует cat, cot, cut и т. д.
+ Повторяет предыдущее совпадение один или несколько раз a+ соответствует a, aa, aaa и т. д.
* Повторяет предыдущее совпадение ноль или более раз a* соответствует всему тому же, что и a+, но также соответствует пустой строке
? Делает совпадение необязательным colou?r соответствует color и colour
\ Экранирует следующий символ \. соответствует . (точке), а не любому одиночному символу, как объяснялось выше
^ Так называемый якорь, соответствует началу строки ^a соответствует строке, начинающейся с a
$ Другой якорь, соответствует концу строки a$ соответствует строке, заканчивающейся на a
( )
Объединяет несколько символов в одну группу и захватывает совпадение для использования в обратной ссылке (ab)+ соответствует ababab — то есть + применяется к группе. Подробнее об обратных ссылках см. ниже
[ ]
Класс символов — соответствует одному из указанных символов c[uoa]t соответствует cut, cot или cat
[^ ]
Отрицательный класс символов — соответствует любому символу, который не указан c[^/]t соответствует cat или c=t, но не c/t

В mod_rewrite символ ! можно поставить перед регулярным выражением, чтобы инвертировать его. Иными словами, строка будет считаться совпавшей, только если она не соответствует остальной части выражения.

Доступность обратных ссылок регулярных выражений

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

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

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

Flow of RewriteRule and RewriteCond matching
Рисунок 1: Передача обратных ссылок через правило.
В этом примере запрос /test/1234 преобразуется в /admin.foo?page=test&id=1234&host=admin.example.com.

Основы RewriteRule

Директива RewriteRule состоит из трёх аргументов, разделённых пробелами:

  1. Pattern: какие входящие URL должны обрабатываться правилом;
  2. Substitution: куда следует перенаправить соответствующие запросы;
  3. [flags]: параметры, влияющие на переписанный запрос.

Pattern — это регулярное выражение. Изначально (для первого правила переписывания или до выполнения подстановки) оно сопоставляется с путём URL входящего запроса (частью после имени хоста, но до вопросительного знака, обозначающего начало строки запроса) или, в контексте каталога, с путём запроса относительно каталога, для которого задано правило. После выполнения подстановки последующие правила сопоставляются с подставленным значением.

Syntax of the RewriteRule directive
Рисунок 2: Синтаксис директивы RewriteRule.

Substitution может принимать один из трёх видов:

1. Полный путь в файловой системе к ресурсу
RewriteRule "^/games" "/usr/local/games/web/puzzles.html"

Это сопоставляет запрос с произвольным расположением в файловой системе, примерно так же, как директива Alias.

2. Веб-путь к ресурсу
RewriteRule "^/games$" "/puzzles.html"

Если для DocumentRoot задано значение /usr/local/apache2/htdocs, эта директива сопоставит запросы к http://example.com/games с путём /usr/local/apache2/htdocs/puzzles.html.

3. Абсолютный URL
RewriteRule "^/product/view$" "http://site2.example.com/seeproduct.html" [R]

Это указывает клиенту отправить новый запрос по указанному URL.

Обратите внимание: 1 и 2 имеют совершенно одинаковый синтаксис. Разница заключается в том, что в случае 1 верхний уровень целевого пути (то есть /usr/) существует в файловой системе, а в случае 2 — нет (то есть в файловой системе нет /bar/ в качестве каталога верхнего уровня).

Substitution также может содержать обратные ссылки на части входящего URL-пути, соответствующие Pattern. Рассмотрим следующий пример:

RewriteRule "^/product/(.*)/view$" "/var/web/productdb/$1"

Переменная $1 будет заменена текстом, соответствующим выражению в скобках в Pattern. Например, запрос http://example.com/product/r14df/view будет сопоставлен с путём /var/web/productdb/r14df.

Если выражений в скобках несколько, они доступны по порядку в переменных $1, $2, $3 и так далее.

Флаги Rewrite

Поведение директивы RewriteRule можно изменить, добавив в конец правила один или несколько флагов. Например, можно сделать сопоставление правила нечувствительным к регистру, добавив флаг [NC]:

RewriteRule "^puppy.html" "smalldog.html" [NC]

Подробнее о доступных флагах, их значениях и примерах см. в документе Флаги Rewrite.

Условия Rewrite

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

Syntax of the RewriteCond directive
Рисунок 3: Синтаксис директивы RewriteCond

Например, чтобы отправлять все запросы из определённого диапазона IP-адресов на другой сервер, можно использовать:

RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
RewriteRule "(.*)"           "http://intranet.example.com$1"

Если задано несколько директив RewriteCond, все они должны соответствовать, чтобы применить RewriteRule. Например, чтобы отклонять запросы, в строке запроса которых есть слово «hack», если только они не содержат cookie со словом «go», можно использовать:

RewriteCond "%{QUERY_STRING}" "hack"
RewriteCond "%{HTTP_COOKIE}"  !go
RewriteRule "."               "-"   [F]

Обратите внимание: восклицательный знак указывает на отрицательное совпадение, поэтому правило применяется только в том случае, если cookie не содержит «go».

Совпадения в регулярных выражениях, содержащихся в директивах RewriteCond, можно использовать в качестве части Substitution директивы RewriteRule с помощью переменных %1, %2 и т. д. Например, этот пример направляет запрос в другой каталог в зависимости от имени хоста, используемого для доступа к сайту:

RewriteCond "%{HTTP_HOST}" "(.*)"
RewriteRule "^/(.*)"       "/sites/%1/$1"

Если запрос был направлен к http://example.com/foo/bar, то %1 будет содержать example.com, а $1 — foo/bar.

Карты Rewrite

Директива RewriteMap позволяет, так сказать, вызвать внешнюю функцию, которая выполнит переписывание за вас. Подробнее это рассматривается в дополнительной документации по RewriteMap.

Файлы .htaccess

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

Главное отличие от правил переписывания на уровне сервера состоит в том, что перед сопоставлением с шаблоном RewriteRule из пути удаляется префикс каталога, содержащего файл .htaccess. Кроме того, следует использовать RewriteBase, чтобы обеспечить правильное сопоставление запроса.

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

Spec-Zone.ru

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