GetInfo.Ru – Компьютерная библиотека
Последние поступления
Как выбрать систему управления базы данных
Базы данных03/09/14
Этапы загрузки UNIX (в схеме)
Unix27/03/12
Gatewall Antispam: тотальный контроль электронной почты
Спам21/04/11
Мастер-класс: создаем Интернет-магазин (Часть 1)
Обзоры ПО20/04/11
CorelDRAW Graphics Suite X5: Что нового?
Обзоры ПО20/07/10
Добавить статью
Самые читаемые материалы
Базовая настройка SQUID(115539)
Простая и эффективная система подсчета трафика в ОС FreeBSD(51346)
Совместное использование прозрачного прокси-сервера (Squid) и биллинговой системы UTM(44640)
Настройка Squid(37953)
Настройка VPN и NetUP Radius сервера(35824)
Всего статей: 793Всего авторов: 364Подразделов: 47Добавлено за сутки: 0
Статьи  СТАТЬИ Форум  ФОРУМ Рейтинг  РЕЙТИНГ Поиск  ПОИСК Контакты  КОНТАКТЫ
» Главная » Unix » Модуль Apache mod_rewrite

Модуль Apache mod_rewrite


Александр Егоров
egr@yandex.ru
http://www.egoroff.spb.ru/

Страницы: [ 1 ] [ 2 ]

Резюме

«Главное преимущество даваемое Вам 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 host directory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

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

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

  • RewriteRule обратные_связи: Это обратные связи вида

    $N

    (0 <= N <= 9) предоставляющие доступ к сгруппированным частям (в круглых скобках!) шаблона из соответствующей директивы RewriteRule (единственной, следующей сразу за текущим набором директив RewriteCond).

  • RewriteCond обратные_связи: Это обратные связи вида

    %N

    (1 <= N <= 9) предоставляющие доступ к сгруппированным частям (в круглых скобках!) шаблона из соответствующей директивы RewriteCond в текущем наборе условий.

  • RewriteMap расширения: Это расширения вида

    ${mapname:key|default}

    Смотрите документацию по RewriteMap для получения более подробной информации.

  • Переменные сервера: Это переменные вида

    %{ NAME_OF_VARIABLE}

    где NAME_OF_VARIABLE может быть строкой взятой из следующего списка:

    HTTP заголовки: соединение & запрос:
    HTTP_USER_AGENT
    HTTP_REFERER
    HTTP_COOKIE
    HTTP_FORWARDED
    HTTP_HOST
    HTTP_PROXY_CONNECTION
    HTTP_ACCEPT
    REMOTE_ADDR
    REMOTE_HOST
    REMOTE_USER
    REMOTE_IDENT
    REQUEST_METHOD
    SCRIPT_FILENAME
    PATH_INFO
    QUERY_STRING
    AUTH_TYPE
    внутренние сервера: системные: специальные:
    DOCUMENT_ROOT
    SERVER_ADMIN
    SERVER_NAME
    SERVER_ADDR
    SERVER_PORT
    SERVER_PROTOCOL
    SERVER_SOFTWARE
    TIME_YEAR
    TIME_MON
    TIME_DAY
    TIME_HOUR
    TIME_MIN
    TIME_SEC
    TIME_WDAY
    TIME
    API_VERSION
    THE_REQUEST
    REQUEST_URI
    REQUEST_FILENAME
    IS_SUBREQ

    Эти переменные полностью соответствуют названным похожим образом MIME-заголовкам HTTP, Си переменным сервера Apache или полям struct tm систем Unix. Большинство из них документрованны в других местах руководства или в спецификации CGI. Те, что являются для mod_rewrite специальными включают:

    IS_SUBREQ
    Будет содержать текст «true» если запрос выполняется в текущий момент как подзапрос, «false» в другом случае. Подзапросы могут быть сгенерированны модулями которым нужно иметь дело с дополнительными файлами или URI для того чтобы выполнить собственные задачи.
    API_VERSION
    Это версия API модуля Apache (внутренний интерфейс между сервером и модулем) в текущей сборке сервера, что определено в include/ap_mmn.h. API версия модуля соответствует используемой версии Apache (для версии Apache 1.3.14, к примеру это 19990320:10), однако это в основном интересно авторам модулей.
    THE_REQUEST
    Полная строка HTTP запроса отправленная браузером серверу (т.е., «GET /index.html HTTP/1.1»). Она не включает какие-либо дополнительные заголовки отправляемые браузером.
    REQUEST_URI
    Ресурс, запрошенный в строке HTTP запроса. (В примере выше, это было бы «/index.html».)
    REQUEST_FILENAME
    Полный путь в файловой системе сервера к файлу или скрипту соответствующим этому запросу.

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

  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 список следующих флагов разделенных запятыми:

  • 'nocase|NC' (регистронезависимо)
    Регистр не имеет значение, т.е., нет различий между 'A-Z' и 'a-z' как в дополнении СравниваемаяСтрока так и Условие. Этот флаг эффективен только для сравнений между СравниваемаяСтрока и Условие. Он не работает при проверках в файловой системе и в подзапросах.

  • 'ornext|OR' (либо следующее условие)
    Используйте для комбинирования условий в правилах OR вместо AND. Типичный пример:

    	RewriteCond %{REMOTE_HOST}  ^host1.*  [OR]
    	RewriteCond %{REMOTE_HOST}  ^host2.*  [OR]
    	RewriteCond %{REMOTE_HOST}  ^host3.*
    	RewriteRule ...some special stuff for any of these hosts...
    

    Без этого флага вы должны были бы написать это условие/правило три раза.

Пример:
Для выдачи главной страницы какого-либо сайта согласно «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 host directory.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 MapName MapType: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 — самого ассоциативного массива:

  • Простой текст
    MapType: txt, MapSource: Путь к существующему файлу в файловой системе Unix

    Это стандартная опция для создания ассоциативного массива где MapSource это простой текстовый ASCII файл содержащий либо пустый строчки, строчки комментариев (начинающиеся с символа '#') либо пары подобные следующим — одна в строчке:

    MatchingKey SubstValue

    Пример:

    	##
    	##  map.txt -- массив преобразований
    	##
    
    	Ralf.S.Engelschall    rse   # Bastard Operator From Hell
    	Mr.Joe.Average        joe   # Mr. Average
    
    	RewriteMap real-to-user txt:/path/to/file/map.txt
    
  • Произвольный простой текст
    MapType: rnd, MapSource: Путь к существующему файлу в файловой системе Unix

    Этот вариант идентичен варианту с простым текстом приведённом выше но со специальной особенностью пост-обработки: После нахождения какую-либо величину производится её анализ на предмет нахождения символов «|» которые имеют значение логического «или». Другими словами они означают набор альтернативных вариантов и выбор возвращаемой величины из них производится произвольно. Хотя это кажется безумием и абсолютно бесполезным, это в действительности используется для балансировки нагрузки в ситуациях с обратным прокси где происходит поиск имен серверов. Например:

    	##
    	##  map.txt -- массив преобразований
    	##
    
    	static   www1|www2|www3|www4
    	dynamic  www5|www6
    

    RewriteMap servers rnd:/path/to/file/map.txt

  • Хэш файл
    MapType: dbm[=type], MapSource: Путь к существующему файлу в файловой системе Unix

    Здесь, источник — это двоичный файл DBM формата содержащий то же самое содержимое что и простой текстовый файл, однако в специальном виде, оптимизированном для действительно быстрого поиска. Этот тип может быть sdbm, gdbm, ndbm, или db в зависимости от настроек при компиляции. Если тип опущен, выбирается тип установленный по-умолчанию при компиляции. Вы можете создавать такой файл любой утилитой DBM или следующим Perl скриптом. Убедитесь что он настроен для создания требуемого типа DBM файла. Этот пример создает файл NDBM:

    	#!/path/to/bin/perl
    	##
    	##  txt2dbm -- convert txt map to dbm format
    	##
    
    	use NDBM_File;
    	use Fcntl;
    
    	($txtmap, $dbmmap) = @ARGV;
    
    	open(TXT, "<$txtmap") or die "Couldn't open $txtmap!\n";
    	tie (%DB, 'NDBM_File', $dbmmap,O_RDWR|O_TRUNC|O_CREAT, 0644)
    	  or die "Couldn't create $dbmmap!\n";
    
    	while (<TXT>) {
    	  next if (/^\s*#/ or /^\s*$/);
    	  $DB{$1} = $2 if (/^\s*(\S+)\s+(\S+)/);
    	}
    
    	untie %DB;
    	close(TXT);
    

    $ txt2dbm map.txt map.db

  • Внутренняя функция
    MapType: int, MapSource: внутренняя функция Apache

    Здесь, источник — это какая-либо внутренняя функция Apache. В настоящее время вы не можете создавать свои собственные функции, однако уже существуют следующие функции:

    • toupper:
      Преобразует ключ поиска в верхний регистр.

    • tolower:
      Преобразует ключ поиска в нижний регистр.

    • escape:
      Транслирует специальные символы в ключе поиска в их числовые коды.

    • unescape:
      Транслирует числовые коды в ключе поиска обратно в специальные символы.

  • Внешняя программа преобразования
    MapType: prg, MapSource: Путь к существующему файлу в файловой системе Unix

    Здесь, источник — это программа, а не файл с ассоциативным массивом. Для её создания вы можете использовать любой выбранный язык, однако результат должен быть исполняемым файлом (т.е., либо объектным кодом либо скриптом с магической первой строчкой '#!/path/to/interpreter').

    Эта программа запускается один раз при запуске сервера Apache и затем взаимодействует с механизмом преобразований через файловые обработчики stdin(поток ввода) и stdout(поток вывода). Для каждого поиска в массиве, соответствующий ключ для поиска, будет получаться в виде строки, подаваемой на stdin и оканчивающейся символом перевода строки. Затем эта программа должна вернуть значение найденной величины в stdout в виде строки оканчивающейся символом перевода строки либо строкой из четырёх символов «NULL» если поиск неудачен (т.е., для соответствующего значения ключа не найдено никакого значения). Тривиальная программа реализующая массив 1:1 (т.е., ключ == значение) может выглядеть так:

    	#!/usr/bin/perl
    	$| = 1;
    	while (<STDIN>) {
    	    # ...put here any transformations or lookups...
    	    print $_;
    	}
    

    Однако будьте очень осторожны:

    1. «Keep it simple, stupid» (KISS) — делай это проще, дурачок, потому что если эта программа зависнет — это повесит сервер Apache когда встретится правило использующее этот массив (создаваемый внешней программой).

    2. Для избежания распространенной ошибки: никогда не делайте буферизованный ввод/вывод для stdout! Это вызовет бесконечное зацикливание! Отсюда «$|=1» в вышеприведенном примере...

    3. Используйте директиву RewriteLock для определения файла блокировок который mod_rewrite может использовать для синхронизации связи с этой программой. По-умолчанию такая синхронизация не производится.

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

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

 
06.05.2003
Версия для печати Версия для печати Запомнить ссылку Запомнить ссылку
Ваша оценка:  1   2   3   4   5     

 О проектеПерепечаткаАвторамПартнерыО нас пишут
Наверх
©2003—2007. GETINFO.RU. ВСЕ ПРАВА ЗАЩИЩЕНЫ.