L: P:
Морда: СтандартнаяСераяЗеленая

Модуль Apache mod_rewrite

Последняя редакция:

Резюме

"Главное преимущество даваемое Вам mod_rewrite═≈ это возможности конфигурирования и═гибкость присущие Sendmail. Обратная сторона mod_rewrite═≈ это возможности конфигурирования и═гибкость присущие Sendmail".

-- Brian Behlendorf
Apache Group

"Несмотря на═тонны примеров и═документацию, mod_rewrite это Вуду. Чертовски кл╦вый Вуду, но═все-таки Вуду."

-- Brian Moore
bem@news.cmc.net

Добро пожаловать в═мир mod_rewrite, швейцарский нож URL преобразований!

Этот модуль использует механизм основанный на═правилах (синтаксический анализатор основанный на═регулярных выражениях) для преобразований URL на═ лету. Он═поддерживает неограниченное количество правил и═ неограниченное количество связанных с═правилом условий для реализации действительно гибкого и═мощного механизма для URL преобразований. URL преобразования могут зависеть от═разных критериев, например переменных сервера, переменных окружения, HTTP заголовков, времени и═даже запросы к═внешним базам данных в═ разных форматах, могут быть использованы для достижения действительно точного соответствия вашим ожиданиям, преобразованных URL.

Этот модуль оперирует с═полными URL (включая path-info) и═в═контексте сервера (httpd.conf) и═в═контексте каталога (.htaccess) и═даже может генерировать части строки запроса в═качестве результата. Преобразованный результат может приводить к═внутренней обработке, внешнему перенаправлению запроса или даже к═прохождению через внутренний прокси модуль.

Однако вся эта функциональность и═гибкость имеет свой недостаток: сложность. Поэтому не═ожидайте что вы═поймете весь этот модуль за═один день.

Этот модуль был придуман и═написан в═апреле 1996═и═эксклюзивно подарен The Apache Group в═июле 1997═

Ralf S. Engelschall
rse@engelschall.com
www.engelschall.com

Директивы

Темы

Внутренние процессы

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

Фазы API

Сначала вы═должны понять, что обработку какого-либо HTTP запроса, сервер Apache делает в═фазах. Перехватчик для каждой из═этих фаз представлен в═Apache API. Mod_rewrite использует 2═из═ этих перехватчиков: перехватчик трансляции из═URL в═имя файла который используется после считывания HTTP запроса однако перед тем как началась какая-либо авторизация и═перехватчик адресной привязки который начинает работать после фаз авторизации и═считывания конфигурационных файлов каталога (.htaccess), но═перед активизацией обработчика содержания.

Поэтому, после поступления запроса и═определения Apache'ем соответствующего сервера (или виртуального сервера) механизм преобразований начинает обработку всех директив mod_rewrite из═ конфигурационного файла сервера в═фазе трансляции из═URL в═имя файла. Несколько шагов спустя когда находятся каталоги с═конечными данными, конфигурационные директивы mod_rewrite запускаются в═фазе Fixup. В═обоих этих ситуациях mod_rewrite преобразует URL, либо в═новые URL, либо в═имена файлов, хотя между ними нет объективных различий. При создании API не═предполагалось его использование таким образом, однако что касается Apache 1.x это единственный возможный способ работы mod_rewrite. Чтобы внести больше ясности запомните 2═вещи:

  1. Хотя mod_rewrite и═преобразует URL в═URL, URL в═ имена файлов и═даже имена файлов в═имена файлов, в═настоящий момент API предоставляет только перехватчик для преобразования URL в═имя файла. Во═2-м Apache будут добавлены 2═отсутствующих перехватчика для того, чтобы сделать этот процесс более логичным. Однако это никак не═влияет на═пользователя,═≈ просто этот факт надо запомнить: Apache в═перехватчике URL имя файла делает больше нежели чем это подразумевается в═API.
  2. Бесподобный mod_rewrite проделывает URL преобразования в═ контексте каталога, т.е., в═файлах .htaccess, хотя они и═обрабатываются намного позже трансляции URL в═имена файлов. Так должно быть, потому что .htaccess файлы находятся в═файловой системе, и═поэтому обработка уже дошла до═этой стадии. Другими словами: Согласно фазам API в═это время уже слишком поздно делать любые манипуляции с═URL. Чтобы победить эту курицу и═снести яйчко(решить эту проблему) mod_rewrite использует трюк: когда вы═ манипулируете URL/именем файла в═контексте каталога, mod_rewrite сначала преобразует имя файла обратно к═соответствующему ему URL (что обычно невозможно, однако смотрите директиву RewriteBase ниже, где написано как сделать подобный трюк) и═затем инициирует новый внутренний подзапрос с═этим новым URL. Это перезапускает процесс обработки API фаз.

    И═снова mod_rewrite упорно пытается сделать этот сложный шаг полностью прозрачным для пользователя, однако здесь вам следует запомнить: в═то═время как манипуляции с═URL контексте сервера действительно быстры и═эффективны, манипуляции в═контексте каталога медленны и═неэффективны из-за проблемы курицы и═яйца. Однако с═другой стороны это единственный возможный путь работы mod_rewrite (локально ограниченный) для URL преобразований, доступный обычному пользователю.

Не═забывайте 2═эти вещи!

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

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

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

Последовательность выполнения комад при обработке набора правил
Рисунок 1:Последовательность выполнения комад при обработке набора правил

Как вы═можете видеть, сначала URL проверяется на═соответствие Шаблон каждого из═правил. При неудаче mod_rewrite сразу же═останавливает обработку этого правила и═продолжает используя следующее. Если Шаблон совпадает, mod_rewrite ищет соответствующие этому правилу условия. Если их═нет, он═ просто заменяет URL новой величиной полученной из═строки Подстановка и═продолжает дальше обрабатывать правила. Однако если существуют условия, запускается внутренний цикл для их═обработки в═том порядке в═котором они перечислены. Для условий эта логика другая: мы═не═сравниваем URL на═соответствие какому-либо шаблону. Вместо этого мы═сначала создаем строку СравниваемаяСтрока дополняя е╦═переменными, обратными ссылками, запросами к═карте, и═т.д. и═затем пытаемся проверять на═соответствие с═Условие. Если шаблон не═соответствует, весь набор условий и═соответствующих правил считается несоответствующим условию. Если есть соответствие шаблону, в═этом случае производится обработка следующего условия до═тех пор пока они будут не═ исчерпаны. Если все условия совпадают, процесс обработки продолжается с═использованием для URL подстановки из═ Подстановка.

Экранирование специальных символов

Что касается Apache 1.3.20, специальные символы в═ СравниваемаяСтрока и═Подстановка строках могут быть экранированы (имеется ввиду, отношение к═ним как к═нормальным символам без их═ обычного специального значения) путем предшествующего им═символа слеша ('\'). Другими словами, вы═можете включать символ═доллара в═строку Подстановка используя '\$'; это не═позволит mod_rewrite относиться к═нему как к═обратной ссылке.

Наличие обратных связей в═регулярных выражениях

Здесь нужно запомнить одну важную вещь: Всякий раз когда вы═ ипользуете круглые скобки в═Pattern или в═одном из═ Условие, создаются внутренние обратные связи которые могут быть использованы со═строками $N и═ %N (см. ниже). Они полезны при создании строк Подстановка и═СравниваемаяСтрока. Рисунок 2═показывает в═какие места при дополнении (строк Подстановка и═СравниваемаяСтрока) перемещаются обратные связи.

Движение обратных связей в═правиле.
Рисунок 2: Движение обратных связей в═правиле.

Мы═знаем что это был тяжелый курс по═внутренним механизмам mod_rewrite, однако вы═получите выгоду из═этих знаний при чтении последующей документации о═доступных директивах.

Переменные окружения

Этот модуль отслеживает две дополнительные (нестандартные) переменные окружения CGI/SSI называемые SCRIPT_URL и═SCRIPT_URI. Они содержат логическое веб-отображение текущего ресурса, в═то═время как стандартные переменные CGI/SSI SCRIPT_NAME и═ SCRIPT_FILENAME содержат физическое системное отображение.

Замечание: эти переменные содержат URI/URL в═том виде, в═котором они были первоначально запрошены, т.е., перед тем как были сделаные какие-либо преобразования. Это важно потому что процесс преобразования в═первую очередь используется для преобразования логических URL в═физические пути к═конкретным файлам.

Пример

SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/

Практические решения

У═нас также есть Руководство по═преобразованиям URL, в═котором приведена коллекция практических решений для проблем основанных на═URL. Там вы═можете найти наборы правил взятые из═реальной жизни и═дополнительную информацию о═ mod_rewrite.

RewriteBase Директива

Описание: Устанавливает базовый URL для преобразований в═контексте каталога
Синтаксис: RewriteBase URL-path
Значение по умолчанию: Смотри использование для более подробной информации.
Контекст: directory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteBase устанавливает конкретный, базовый URL для преобразований в═контексте каталога. Как вы═увидите ниже, RewriteRule может быть использовано в═конфигурационных файлах каталогов (.htaccess). Это будет работать локально, т.е., префикс локального каталога отбрасывается на═этом этапе обработки и═ваши правила преобразований работают только в═ оставшейся части. В═конце он═автоматически добавляется обратно к═пути. Настройка по-умолчанию; RewriteBase physical-directory-path

Когда, для какого-нибудь нового URL происходит подстановка(преобразование), этот модуль должен заново вовлечь этот URL в═обработку. Для того чтобы иметь возможность сделать это, нужно знать какие у═него префикс или база URL. По-умолчанию этот префикс равен самому пути. Однако на═большинстве сайтов URL'ы НЕ═прямо соответствуют физическим путям, поэтому это допущение обычно окажется неверным! В═этом случае вы═должны использовать директиву RewriteBase для указания правильного префикса URL.

Если URL вашего сервера не соответствуют физическим путям к═файлам, вы═должны использовать RewriteBase в═каждом из═.htaccess файлов где вы═хотите использовать директивы RewriteRule.

Например, предположим следующий конфигурационный файл каталога:

#
#  /abc/def/.htaccess -- конфигурационный файл каталога /abc/def
#  Помните: /abc/def это физический путь /xyz, т.е., у сервера есть
#            директива 'Alias /xyz /abc/def' к примеру
#

RewriteEngine On

#  даем серверу знать что мы работаем через /xyz а не
#  через префикс физического пути /abc/def
RewriteBase   /xyz

#  теперь правила преобразований
RewriteRule   ^oldstuff\.html$  newstuff.html

В═примере выше, запрос к═ /xyz/oldstuff.html корректно преобразуется в═ физический файл /abc/def/newstuff.html.

Для любителей поковыряться в═Apache

Следующий список дает подробную информацию об═ этапах внутренней работы:

Запрос:
  /xyz/oldstuff.html

Внутренняя работа:
  /xyz/oldstuff.html     -> /abc/def/oldstuff.html  (per-server Alias)
  /abc/def/oldstuff.html -> /abc/def/newstuff.html  (per-dir    RewriteRule)
  /abc/def/newstuff.html -> /xyz/newstuff.html      (per-dir    RewriteBase)
  /xyz/newstuff.html     -> /abc/def/newstuff.html  (per-server Alias)

Результат:
  /abc/def/newstuff.html

Это кажется очень сложным однако это корректная внутренняя работа Apache, из-за того что преобразования в═контексте каталога происходят слишком поздно в═ этом процессе. Поэтому, когда это происходит (преобразование), запрос должен быть возвращен обратно ядру Apache! НО: В═то═время как это кажется серъ╦зным накладным расходом, в═действительности это не═так, потому что этот возврат происходит целиком внутри сервера Apache и═та═же═самая процедура используется многими другими операциями внутри Apache. Поэтому, вы═можете быть уверены что дизайн и═реализация правильные.

RewriteCond Директива

Описание: Определяет условие при котором происходит преобразование
Синтаксис: RewriteCond СравниваемаяСтрокаУсловие
Значение по умолчанию: None
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

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

СравниваемаяСтрока строка которая может содержать следующие дополнительные конструкции в═дополении к═простому тексту:

Специальные примечания:

  1. Переменные SCRIPT_FILENAME и═REQUEST_FILENAME содержат одинаковые значения, т.е., значение поля filename внутренней структуры request_rec сервера Apache. Первое имя это просто широко известное имя переменной CGI в═то═время как второе это постоянная копия REQUEST_URI (содержащая значение поля uri структуры request_rec).
  2. Есть специальный формат: %{ENV:переменная} где переменная может быть любой переменной окружения. Это ищется во═внутренних структурах Apache и═(если там нет) с═помощью вызова getenv() из═процесса Apache сервера.
  3. Есть специальный формат: %{HTTP:заголовок} где заголовок может быть любым именем HTTP MIME-заголовка. Это ищется в═HTTP запросе. Пример: %{HTTP:Proxy-Connection} значение HTTP заголовка "Proxy-Connection:".
  4. Есть специальный формат %{LA-U:переменная} опережающих запросов которые производятся внутренним (основанном на═URL) подзапросом для определения конечного значения переменной. Используйте это когда вы═хотите использовать переменную для преобразований, которая реально определяется позднее, в═ какой-либо фазе API, и═таким образом недоступна на═данном этапе. Для примера когда вы═хотите преобразовать соответственно переменной REMOTE_USER из═контекста сервера (файл httpd.conf) вы═должны использовать %{LA-U:REMOTE_USER} потому что эта переменная устанавливается в═фазах авторизации которые идут после фазы трансляции URL в═которой и═работает mod_rewrite. С═другой стороны, по═причине реализации работы mod_rewrite в═ контексте каталога (файл .htaccess) через Fixup фазу API и═из-за того, фазы авторизации идут до этой фазы, вы═просто можете там использовать %{REMOTE_USER}.
  5. Есть специальный формат: %{LA-F:переменная} который создает внутренний (основанный на═имени файла) подзапрос для определения конечного значения переменной. В═основном это то═же═самое что и═формат LA-U приведенный выше.

Условие это шаблон условия, т.е., какое-либо регулярное выражение применяемое к═текущему экземпляру СравниваемаяСтрока, т.е., СравниваемаяСтрока просматривается на═поиск соответствия Условие.

Помните: Условие это perl совместимое регулярное выражение с═некоторыми дополнениями:

  1. Вы═можете предварять строку шаблона префиксом '!' (восклицательный знак) для указания несоответствия шаблону.
  2. Есть некоторые специальные варианты Условиеs. Вместо обычных строк с═регулярными выражениями можно также использовать один из═следующих вариантов:
    • '<Условие' (лексически меньше)
      Условие считается простой строкой и═ лексически сравнивается с═СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически меньше чем Условие.
    • '>Условие' (лексически больше)
      Условие считается простой строкой и═ лексически сравнивается с═СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически больше чем Условие.
    • '=Условие' (лексически равно)
      Условие считается простой строкой и═лексически сравнивается с═СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически равно Условие, т.е. эти две строки полностью одинаковы (символ в═символ). Если Условие имеет вид "" (два знака дюйма идущих подряд) это сравнивает СравниваемаяСтрока с═пустой строкой.
    • '-d' (является ли═каталогом)
      СравниваемаяСтрока считается путем, проверяется существование этого пути и═то═что этот путь является каталогом.
    • '-f' (является ли═обычным файлом)
      СравниваемаяСтрока считается путем, проверяется существование этого пути и═то═что этот путь является обычным файлом.
    • '-s' (является ли═обычным файлом с═ненулевым размером)
      СравниваемаяСтрока считается путем, проверяется существование этого пути и═то═что этот путь является обычным файлом, размер которого больше нуля.
    • '-l' (является ли═символической ссылкой)
      СравниваемаяСтрока считается путем, проверяется существование этого пути и═то═что этот путь является символической ссылкой.
    • '-F' (проверка существования файла через подзапрос)
      Проверяет через все списки контроля доступа сервера, существующие в═настоящий момент, является ли═СравниваемаяСтрока существующим файлом, доступным по═этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с═осторожностью ═≈ это отрицательно сказывается на═производительности сервера!
    • '-U' (проверка существования URL через подзапрос)
      Проверяет через все списки контроля доступа сервера, существующие в═настоящий момент, является ли═СравниваемаяСтрока существующим URL, доступным по═этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с═осторожностью ═≈ это отрицательно сказывается на═производительности сервера!

    Замечание

    Все эти проверки также могут быть предварены префиксом восклицательный знак ('!') для инвертирования их═значения.

Дополнительно вы═можете устанавливать специальные флаги для Условие добавляя

[flags]

третьим аргументом в═директиву RewriteCond. Flags список следующих флагов разделенных запятыми:

Пример:

Для выдачи главной страницы какого-либо сайта согласно "User-Agent:" заголовку запроса, вы═можете использовать следующие директивы:

RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/$                 /homepage.max.html  [L]

RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
RewriteRule  ^/$                 /homepage.min.html  [L]

RewriteRule  ^/$                 /homepage.std.html  [L]

Интерпретация: Если у═вас Netscape Navigator (который идентифицируется как 'Mozilla'), вы═выдаете максимально навороченную страницу, с═фреймами, и═т.д. Если у═вас Lynx (текстовый браузер), вы═выдаете наименее навороченную страницу, без рисунков, таблиц и═т.д. Если любой другой браузер, выдаете стандартную страницу.

RewriteEngine Директива

Описание: Включает или выключает работу механизма преобразования
Синтаксис: RewriteEngine on|off
Значение по умолчанию: RewriteEngine off
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteEngine включает или выключает работу механизма преобразований. Если она установлена в═положение off этот модуль совсем не═работает. Он═даже не═обновляет переменные окружения SCRIPT_URx.

Используйте эту директиву для выключения этого модуля вместо простого закомментирования директив RewriteRule!

Отметьте, что по-умолчанию, настройки преобразований не═ наследуются. Это означает что вы═должны иметь RewriteEngine on директиву для каждого виртуального хоста в═котором вы═хотите использовать этот модуль.

RewriteLock Директива

Описание: Устанавливает имя файла используемого для RewriteMap синхронизации
Синтаксис: RewriteLock file-path
Значение по умолчанию: None
Контекст: server config
Статус: Расширение
Модуль: mod_rewrite

Эта директива определяет имя файла синхронизации который нужен mod_rewrite для связи с═RewriteMap программами. Сделайте этот файл локальным (размещенным не═на═ NFS-смонтированном ресурсе) когда вы═хотите использовать программу для создания ассоциативного массива преобразований. Это не═является обязательным для других типов таких массивов.

RewriteLog Директива

Описание: Устанавливает имя файла используемое для ведения журнала механизма преобразования
Синтаксис: RewriteLog file-path
Контекст: server configvirtual host
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteLog устанавливает имя файла а═котором сервер ведет журнал любых происходящих действий по═преобразованиям URL. Если это имя не═начинается со═слэша ('/') в═этом случае путь считается от═ Server Root. В═конфигурационном файле сервера эта директива должна встерчаться только один раз.

Для отключения ведения журнала преобразований не═рекомендуется устанавливать Filename в═/dev/null, потому что хотя механизм преобразований и═не═производит вывод в═файл журнала в═этом случае, внутри он═все ещ╦ ведет журнализацию. Это замедлит сервер без каких-либо преимуществ для администратора! Для отключения ведения журнала либо удалите либо закомментируйте директиву RewriteLog либо используйте RewriteLogLevel 0!

Безопасность

Смотрите документ Apache Security Tips для более подробной информации о═том почему вы═можете быть уязвимы если в═каталоги где хранятся файлы журналов разрешена запись кому угодно кроме пользователя от═имени которого запускается сервер.

Пример

RewriteLog "/usr/local/var/apache/logs/rewrite.log"

RewriteLogLevel Директива

Описание: Устанавливает уровень детализации при журнализации действий механизма преобразований
Синтаксис: RewriteLogLevel Level
Значение по умолчанию: RewriteLogLevel 0
Контекст: server configvirtual host
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteLogLevel устанавливает уровень детализации журнала механизма преобразований. По-умолчанию уровень 0═ означающий что журнализация не═ведется, в═то═время как 9═или более означает что записываются практически все действия.

Для отключения журнализации действий механизма преобразований просто установите уровень на═0.═Это отключает ведение журнала для всех действий по═преобразованиям.

Использование больших значений уровня очень сильно замедлит ваш сервер Apache! Используйте журнал преобразований на═ уровне большем чем 2═только для отладочных целей!

Пример

RewriteLogLevel 3

RewriteMap Директива

Описание: Определяет функцию создания ассоциативного массива для поиска по═ключу
Синтаксис: RewriteMap MapNameMapType:MapSource
Значение по умолчанию: нет
Контекст: server configvirtual host
Статус: Расширение
Модуль: mod_rewrite
Совместимость: Выбор разных типов dbm доступен в═Apache 2.0.41═и═более поздних версиях

Директива RewriteMap ассоциативный массив преобразований, который может быть использован в═правилах преобразований и═использующий соответствующие функции для вставки/извлечения элементов, для поиска по═ключу соответствующих значений. Источник этого поиска может иметь различный тип.

MapName это имя массива которое будет использоваться для поиска соответствующего значения из═массива в═правиле преобразования через один из═следующих конструкторов:

${MapName:LookupKey}
${MapName:LookupKey|DefaultValue}

Когда встречается подобная конструкция, происходит обращение к═ массиву MapName и═поиск значения сопоставленного ключу LookupKey. Если найдено искомое значение ключа, происходит извлечение значения SubstValue с═помощью соответствующей функции. Если ключ не═найден тогда происходит подстановка DefaultValue или пустой строки если не═указана DefaultValue.

Могут быть использованы следующие комбинации типа функции═≈ MapType для вставки/извлечения элементов массива и═ MapSource═≈ самого ассоциативного массива:

Директива RewriteMap может встречаться более одного раза. Для каждого массива используйте одну RewriteMap директиву для объявления файла с═массивом преобразований. В═то═время как вы═не═можете определять массив в═контексте каталога, его использование в═этом контексте конечно же═возможно.

Замечание

Для простого текстового и═DBM файлов ключи поиска кэшируются ядром до═тех пор пока не═изменится тип mtime файла с═массивом или пока не═произойдет рестарт сервера. Таким образом, вы═можете использовать ассоциативные массивы в═правилах которые используются для каждого запроса. Это не═проблема, потому что внешний поиск происходит только один раз!

RewriteOptions Директива

Описание: Устанавливает кое-какие специальные опции для механизма преобразований
Синтаксис: RewriteOptions Options
Значение по умолчанию: None
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteOptions устанавливает некоторые специальные опции для текущей конфигурации в═контексте сервера или каталога. Строки Option могут иметь следующий вид:

RewriteRule Директива

Описание: Определяет правила для механизма преобразований
Синтаксис: RewriteRule ШаблонПодстановка
Значение по умолчанию: None
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite
Совместимость: Флаг cookie доступен в═Apache 2.0.40═и═более поздних.

Директива RewriteRule и═есть настоящая рабочая лошадка преобразований. Эта директива может встречаться более одного раза. Каждая директива, в═этом случае, определяет одно правило преобразования. Порядок определений этих правил важен, потому что этот порядок используется при обработке правил во═время работы.

Шаблон это perl совместимое регулярное выражение которое применяется к═текущему URL. Здесь под "текущим" подразумевается значение URL когда применяется это правило. Этот URL не═обязательно совпадает с═первоначально запрошенным URL, потому что любое количество правил возможно уже были применены к═нему и═ соответственно преобразовали его.

Некоторые указания по═синтаксису регулярных выражений:

Текст:
  .           Любой одиночный символ
  [chars]     Класс симвлолв: Один из символов
  [^chars]    Класс симвлолв: Ни один из символов
  text1|text2 Альтернатива: text1 или text2

Кванторы (символы для обозначения количественных отношений):
  ?           0 или 1 из предшествующего текста
  *           0 или N из предшествующего текста (N > 0)
  +           1 или N из предшествующего текста (N > 1)

Группировка:
  (text)      Группировка текста
              (либо установка границ альтернативы или
              для создания обратных связей где N группа, которая 
              может быть использована в RHS директивы RewriteRule с $N)

Маркеры:
  ^           Маркер начала строки
  $           Маркер конца строки

Экранирование:
  \char       экранирование конкретного символа
              (к примеру для указания символов ".[]()" и т.д.)

Более подробную информацию о═регулярных выражениях, смотрите в═ документации по═регулярным выражениям Perl ("perldoc perlre"). Если вы═заинтересованы в═ещ╦ более детальной информации о═регулярных выражениях и═их═диалектах (POSIX и═т.д.), смотрите следующую, специально написанную по═этой теме книгу:

Mastering Regular Expressions
Jeffrey E.F. Friedl
Nutshell Handbook Series
O'Reilly & Associates, Inc. 1997
ISBN 1-56592-257-3

Кроме того, в═mod_rewrite символ отрицания (NOT) ('!')═≈ допускаемый префикс в═шаблоне. Это да╦т вам возможность инвертировать действие шаблона; ну═к═примеру скажем: "если текущий URLне совпадает с═этим шаблоном". Это может быть использовано в═особых случаях, когда проще найти шаблон для несоответствия, или в═качестве последнего правила, работающего по═умолчанию.

Примечание

При использовании символа NOT (не) для инвертирования действия шаблона вы═не═можете иметь сгруппированные части групповых символов в═шаблоне. Это невозможно потому что когда нет соответствия шаблону, для групп нет никакого содержимого. В═результате, если используются шаблоны с═отрицанием, вы═ не═можете использовать $N в═строках подстановок!

Подстановка в═правиле преобразования это строка будет подставляться (или будет заменять) вместо оригинального URL, для которого естьсовпадение Шаблону. Кроме простого текста вы═можете использовать

  1. обратные связи $N на═шаблоны в═RewriteRule
  2. обратные связи %N на═последний соответствующий шаблон в═ RewriteCond
  3. переменные сервера в═качестве проверяемых строк в═условиях правил (%{VARNAME})
  4. вызовы запросов к═массиву (${mapname:key|default})

Обратные связи это $N (N=0..9) идентификаторы которые заменяются содержимым N-й группы подходящего Шаблона. Переменные сервера Это тоже самое что и═СравниваемаяСтрока директивы RewriteCond. Запросы к═массиву пришли из═директивы RewriteMap там они и═объяснены. Эти три типа переменных рассматриваются в═порядке, в═котором они идут в═ вышеприведенном списке.

Как уже было упомянуто выше, все правила преобразований применяются с═использованием Подстановки (в порядке, в═котором они определены в═конфигурационном файле). URL полностью заменяется Подстановкой и═процесс преобразования идет до═тех пор, пока не═останется больше никаких правил, если только он═не═прерван специально, с═помощью флага L═≈ см. ниже.

Существует специальная строка подстановки вида '-' которая означает: НЕТ подстановки! Звучит глупо? Нет, это полезно для правил преобразования которые только проверяют некоторые URL однако не═производят подстановок, т.е., в═ связке с═флагом C (цепочка) возможно иметь более чем один шаблон, применяемый перед проведением непосредственно самой подстановки.

Ещ╦ одно замечание: Вы═даже можете создавать URL, содержащие строку запроса, в═строке подстановки. Просто используйте вопросительный знак внутри строки подстановки для указания того, следующее за═ним содержимое должно быть преобразовано в═ QUERY_STRING (строку запроса). Когда вы═хотите убрать существующую строку запроса, завершайте строку подстановки просто вопросительным знаком.

Примечание

Есть одна особенность: Когда вы═предваряете поле подстановки строкой http://thishost[:thisport],═≈ mod_rewrite отрезает е╦═автоматически. Это автоматическое усечение подразумеваемое при внешнем редиректе URL полезная и═важная особенность при использовании в═ связке с═запросами к═массивам преобразований генерирующих имя хоста. Взгляните на═первый пример, в═ разделе примеров ниже, чтобы понять это.

Помните

Безусловный внешний редирект на═ваш собственный сервер не═будет работать с═префиксом http://thishost из-за этой особенности. Чтобы использовать такой саморедирект, Вы═должны использовать флаг R(см. ниже).

В═подстановке вы═можете использовать, в═том числе, и═специальные флаги путем добавления следующей конструкции:

[флаги]

в═качестве третьего аргумента директивы RewriteRule. Флаги═≈ это раздел╦нный запятыми, следующий список флагов:

Примечание

Никогда не═забыва╦те что Шаблон применяется ко═всему URL в═конфигурационных файла сервера. Однако в═конфигурационных файлах каталогов, префикс каталога (который всегда одинаков для конкретного каталога !), автоматически удаляется при соответствии шаблону и═автоматически добавляется после завершения подстановки. Эта особенность, основа для многих видов преобразований, потому что без удаления префикса для родительского каталога тоже должно быть соответствие, что не═всегда возможно.

Есть одно исключение: Если строка подстановки начинается с═"http://" в═этом случае префикс каталога не добавляется и═происходит либо внешний редирект либо пропускание через прокси (если используется флаг P!)!

Примечание

Для того чтобы включить механизм преобразований в═ конфигурационных файлах каталогов вам нужно написать "RewriteEngine On" в═этих самых файлах и, кроме того, должна быть разрешена конфигурационная директива "Options FollowSymLinks". Если ваш администратор запретил перегрузку конфигурационной директивы FollowSymLinks в═пользовательских каталогах, в═этом случае вы═не═сможете использовать механизм преобразований. Это ограничение нужно по═соображениям безопасности.

Вот все возможные комбинации подстановок с═расшифровкой их═значений:

В═конфигурационных файлах контекста сервера (httpd.conf)
для запроса вида "GET /somepath/pathinfo":

Правило                                         Подстановка
----------------------------------------------  ----------------------------------
^/somepath(.*) otherpath$1                      не поддерживается, т.к. неверно!

^/somepath(.*) otherpath$1  [R]                 не поддерживается, т.к. неверно!

^/somepath(.*) otherpath$1  [P]                 не поддерживается, т.к. неверно!
----------------------------------------------  ----------------------------------
^/somepath(.*) /otherpath$1                     /otherpath/pathinfo

^/somepath(.*) /otherpath$1 [R]                 http://thishost/otherpath/pathinfo
                                                через внешний редирект

^/somepath(.*) /otherpath$1 [P]                 не поддерживается, - глупо!
----------------------------------------------  ----------------------------------
^/somepath(.*) http://thishost/otherpath$1      /otherpath/pathinfo

^/somepath(.*) http://thishost/otherpath$1 [R]  http://thishost/otherpath/pathinfo
                                                через внешний редирект

^/somepath(.*) http://thishost/otherpath$1 [P]  не поддерживается, - глупо!
----------------------------------------------  ----------------------------------
^/somepath(.*) http://otherhost/otherpath$1     http://otherhost/otherpath/pathinfo
                                                через внешний редирект

^/somepath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
                                                через внешний редирект
                                                (флаг [R] избыточен)

^/somepath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
                                                через внутренний прокси

Внутри конфигурационного файла каталога, для /somepath
(т.е., файл .htaccess в═каталоге /physical/path/to/somepath содержит RewriteBase /somepath)
для запроса "GET /somepath/localpath/pathinfo":

Правило                                         Подстановка
----------------------------------------------  ----------------------------------
^localpath(.*) otherpath$1                      /somepath/otherpath/pathinfo

^localpath(.*) otherpath$1  [R]                 http://thishost/somepath/otherpath/pathinfo
                                                через внешний редирект

^localpath(.*) otherpath$1  [P]                 не поддерживается, - глупо!
----------------------------------------------  ----------------------------------
^localpath(.*) /otherpath$1                     /otherpath/pathinfo

^localpath(.*) /otherpath$1 [R]                 http://thishost/otherpath/pathinfo
                                                через внешний редирект

^localpath(.*) /otherpath$1 [P]                 не поддерживается, - глупо!
----------------------------------------------  ----------------------------------
^localpath(.*) http://thishost/otherpath$1      /otherpath/pathinfo

^localpath(.*) http://thishost/otherpath$1 [R]  http://thishost/otherpath/pathinfo
                                                через внешний редирект

^localpath(.*) http://thishost/otherpath$1 [P]  не поддерживается, - глупо!
----------------------------------------------  ----------------------------------
^localpath(.*) http://otherhost/otherpath$1     http://otherhost/otherpath/pathinfo
                                                через внешний редирект

^localpath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo
                                                через внешний редирект
                                                (флаг [R] избыточен)

^localpath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo
                                                через внутренний прокси

Пример:

Мы═хотим преобразовать URL вида

/ Language /~ Realname /.../ File

в═

/u/ Username /.../ File . Language

Мы═берем файл, содержащий ассоциативный массив для преобразований, привед╦нный выше и═сохраняем его под именем /path/to/file/map.txt. Затем, нам нужно только добавить следующие строчки в═конфигурационный файл сервера Apache:

RewriteLog   /path/to/file/rewrite.log
RewriteMap   real-to-user               txt:/path/to/file/map.txt
RewriteRule  ^/([^/]+)/~([^/]+)/(.*)$   /u/${real-to-user:$2|nobody}/$3.$1
Valid XHTML 1.0!Valid CSS!

HIVE: All information for read only. Please respect copyright!
Hosted by hive йца: йХЕБЯЙЮЪ ЦНПНДЯЙЮЪ АХАКХНРЕЙЮ