4. Директива RewriteCond
Функции и синтаксис RewriteCond
Директива RewriteCond определяет условие, при котором будет иметь место перезапись. То есть мы ставим в зависимость выполнения правила не только от условия совпадения с Шаблоном, но и от других условий, которые могут не относиться к содержимому строки запроса. Например, правило может срабатывать (или наоборот, не срабатывать) если запрашиваемый адрес указывает на реально существующий в файловой системе файл, правило может быть отключено для определённых клиентских браузеров, либо в определённое время суток. Всё это можно сделать с помощью RewriteCond.
Синтаксис использования:
RewriteCond определяет условие применения правила. Одна или более директив RewriteCond могут предшествовать директиве RewriteRule. Последующее правило будет использоваться только в том случае, если текущее состояние URI соответствует его Шаблону, И если выполняются условия RewriteCond.
Строка тестирования RewriteCond
СтрокаТестирования – это строка, которая может содержать следующие расширенные конструкции в дополнение к простому тексту:
| Переменные | Описание |
|---|---|
| HTTP заголовки | |
| HTTP_ACCEPT | Запрашивает типы контента, выраженные в виде типов MIME, которые клиент может понять. Используя согласование контента, сервер затем выбирает одно из предложений, использует его и информирует клиента о своём выборе заголовком ответа Content-Type. Браузеры устанавливают соответствующие значения для этого заголовка в зависимости от контекста, в котором выполняется запрос: при обработке таблицы стилей CSS для запроса задается другое значение, чем при выборе изображения, видео или сценария. |
| HTTP_COOKIE | Содержит сохраненные HTTP-файлы cookie, ранее отправленные сервером с заголовком Set-Cookie. |
| HTTP_FORWARDED | Содержит информацию с клиентской стороны, которая изменена или потеряна когда в путь запроса вовлечён прокси. |
| HTTP_HOST | Указывает доменное имя сервера (для виртуального хостинга) и (необязательно) номер порта TCP, который прослушивает сервер. |
| HTTP_PROXY_CONNECTION | Определяет, остается ли сетевое соединение открытым после завершения текущей транзакции. Если отправляется keep-alive, соединение является постоянным и не закрытым, что позволяет выполнять последующие запросы на один и тот же сервер. |
| HTTP_REFERER | Содержит адрес предыдущей веб-страницы, с которой была сделана ссылка на запрашиваемую страницу. |
| HTTP_USER_AGENT | Содержит строку-характеристику, которая позволяет сетевым протоколам идентифицировать тип приложения, операционную систему, поставщика программного обеспечения или версию программного обеспечения запрашивающего программного агента. |
| Внутренние сервера | |
| DOCUMENT_ROOT | DocumentRoot текущего vhost. |
| SCRIPT_GROUP | Имя группы скрипта. |
| SCRIPT_USER | Имя пользователя владельца скрипта. |
| SERVER_ADDR | IP-адрес виртуального хоста, обслуживающего запрос. |
| SERVER_ADMIN | ServerAdmin текущего vhost |
| SERVER_NAME | ServerName (включает схему, доменное имя или IP адрес и порт) текущего vhost. |
| SERVER_PORT | Порт сервера текущего vhost, также смотрите ServerName. |
| SERVER_PROTOCOL | Протокол, используемый запросом. |
| SERVER_SOFTWARE | Строка с версией сервера. |
| Подключение и запросы | |
| AUTH_TYPE | Настроенный AuthType (варианты: None|Basic|Digest|Form) |
| CONN_REMOTE_ADDR | С 2.4.8: IP адрес пира соединения (смотрите модуль mod_remoteip). |
| CONTEXT_PREFIX | Префикс URI, который соответствует каталогу CONTEXT_DOCUMENT_ROOT, без конечной косой черты |
| CONTEXT_DOCUMENT_ROOT | Корневой каталог контекста на диске для текущего ресурса, без конечного слэша |
| IPV6 | "on" если подключение использует IPv6, в противном случае "off" |
| PATH_INFO | Завершающая информация имени пути, которая следует после реального расположения файла или несуществующий файл в существующем каталоге независимо от того, является ли запрос принятым или отклонённым, смотрите AcceptPathInfo. Например, допустим расположение /test/ указывает на директорию, которая содержит только один файл here.html. Тогда запрос /test/here.html/more и /test/nothere.html/more оба соберут /more в качестве значения PATH_INFO. |
| QUERY_STRING | Строка запроса (следует после символа ? (знак вопроса)) текущего запроса к серверу. |
| REMOTE_ADDR | IP адрес удалённого хоста. |
| REMOTE_HOST | Имя хоста удалённого хоста. |
| REMOTE_IDENT | Имя пользователя, утсановленное mod_ident. |
| REMOTE_PORT | Порт удалённого хоста (2.4.26 и более поздние) |
| REMOTE_USER | Имя аутентифицированного пользователя, если есть. |
| REQUEST_METHOD | HTTP метод входящего запроса (например, GET, POST, HEAD). |
| SCRIPT_FILENAME | То же самое, что и REQUEST_FILENAME. |
| Дата и время | |
| TIME_YEAR | Текущий год (например, (2018) |
| TIME_MON | Текущий месяц (01, …, 12) |
| TIME_DAY | Текущий день месяца (01, …) |
| TIME_HOUR | Часы текущего времени (00, …, 23) |
| TIME_MIN | Минуты текущего времени |
| TIME_SEC | Секунды текущего времени |
| TIME_WDAY | День недели (начинается с 0 для Воскресенья) |
| TIME | Дата и время в формате 20180924214559 |
| Специальные | |
| API_VERSION | Версия Apache httpd module API (внутреннего интерфейса между сервером и модулем) в текущей сборке httpd, как определена в include/ap_mmn.h. Версия модуля API соответствует версии используемого Apache httpd. Обычно это интересно только для авторов модулей. |
| CONN_REMOTE_ADDR | С 2.4.8: IP адрес пира соединения (смотрите модуль mod_remoteip). |
| HTTPS | Будет содержать текст "on" если соединение использует SSL/TLS, в противном случае - "off". (Эта переменная может безопасно использоваться независимо от того, загружен модуль mod_ssl или нет). |
| IS_SUBREQ | Будет содержать текст "true" если обрабатываемый в данный момент запрос является подзапросом, в противном случае "false". Подзапросы могут генерироваться модулями, которым нужно преобразовать дополнительные файлы или URI чтобы завершить их задачи. |
| REMOTE_ADDR | IP удалённого хоста (смотрите модуль mod_remoteip). |
| REQUEST_FILENAME | Полный путь в локальной файловой системе до файла или скрипта, совпадающего с запросом, если он уже был определён сервером во время упоминания REQUEST_FILENAME. В зависимости от значения AcceptPathInfo, сервер может использовать только некоторые предшествующие компоненты REQUEST_URI для сопоставления запроса с файлом. |
| REQUEST_SCHEME | Будет содержать схему запроса (обычно "http" или "https"). На это значение может влиять ServerName. |
| REQUEST_URI | Компонент пути запрошенного URI, такой как "/index.html". Здесь исключена строка запроса, которая доступна в своей собственной переменной под именем QUERY_STRING. |
| THE_REQUEST | Полная строка запроса HTTP отправленная браузером к серверу (например, "GET /index.html HTTP/1.1"). Она не включает любые дополнительные заголовки, отправленные браузером. Это значение не экранировано (кодировано), в отличии от большинства других переменных. |
Эти переменные все соответствуют названным подобным образом HTTP MIME-заголовкам, переменным C для Apache HTTP сервера или полям struct tm системы Unix.
SERVER_NAME и SERVER_PORT зависят от значений UseCanonicalName и UseCanonicalPhysicalPort соответственно.
Если СтрокаТестирования имеет специальное значение expr, ШаблонУсловия будет обрабатываться как ap_expr. HTTP заголовки, на которые указано в выражении, будут добавлены к заголовку Vary, если не дан флаг novary.
Другие вещи, о которых вы должны знать:
Если случилась подстановка и перезапись продолжается, значение обеих переменных соответственно будет обновлено.
Если используется контекст сервера (то есть до того, как запрос сопоставляется с файловой системой), SCRIPT_FILENAME и REQUEST_FILENAME не могут содержать полный путь к локальной файловой системе, поскольку на этом этапе обработки путь неизвестен. В этом случае изначально обе переменные будут содержать значение REQUEST_URI. Чтобы получить полный путь в локальной файловой системе запроса в контексте сервера, используйте основанный на URL look-ahead %{LA-U:REQUEST_FILENAME}, для определения конечного значение REQUEST_FILENAME.
Если HTTP заголовок используется в условии, этот заголовок добавляется к заголовку Vary ответа в случае, если для данного запроса условие вычисляется как истина. Он не добавляется если условие вычисляется для заголовка как лож. Добавление HTTP заголовка к заголовку Vary ответа необходимо для правильного кэширования.
Следует иметь в виду, что условия соответствуют логике короткого контура в случае флага 'ornext|OR', так что некоторые условия могут вообще не оцениваться.
Например, чтобы переписать в соответствии с переменной REMOTE_USER из контекста сервера (файл httpd.conf), вы должны использовать %{LA-U:REMOTE_USER} - эта переменная задается фазами авторизации, которые появляются после преобразования URL (во время которой работает mod_rewrite).
С другой стороны, поскольку mod_rewrite реализует контекст для каталога (файл .htaccess) через фазу Fixup API и, поскольку фазы авторизации приходят до этого этапа, вы можете использовать %{REMOTE_USER} в этом контексте.
Шаблон условия RewriteCond
ШаблонУсловия – это шаблон условия, регулярное выражение, которое применяется к текущему экземпляру СтрокаТестирования. СтрокаТестирования сначала оценивается перед сопоставлением с ШаблономУсловия.
ШаблонУсловия обычно является регулярным выражением, совместимым с perl, но имеется дополнительный синтаксис для выполнения других полезных тестов в отношении СтрокиТестирования:
Пример правила блокировки всех пользователей с пустым Referer, кроме одного IP адреса (127.0.0.1):
<CondPattern
Лексикографически предшествует
Обрабатывает ШаблонУсловия как обычную строку и сравнивает ее лексикографически со СтрокойТестирования. Истина, если СтрокаТестирования лексикографически предшествует ШаблонуУсловия.
>CondPattern
Лексикографически следует
Обрабатывает ШаблонУсловия как обычную строку и сравнивает ее лексикографически со СтрокойТестирования. Истинно, если СтрокаТестирования лексикографически следует ШаблонуУсловия.
=CondPattern
Лексикографически равный
Обрабатывает ШаблонУсловия как обычную строку и сравнивает ее лексикографически со СтрокойТестирования. Истина, если СтрокаТестирования лексикографически равна ШаблонуУсловия (две строки в точности равны, символ в символ). Если ШаблонУсловия является "" (двумя кавычками), это сравнивает СтрокуТестирования с пустой строкой.
<=CondPattern
Лексикографически меньше или равно
Обрабатывает ШаблонУсловия как обычную строку и сравнивает ее лексикографически со СтрокойТестирования. Истина, если СтрокаТестирования лексикографически предшествует ШаблонуУсловия или равна ШаблонуУсловия (две строки равны, символ в символ).
>=CondPattern
Лексикографически больше или равно
Обрабатывает ШаблонУсловия как обычную строку и сравнивает ее лексикографически со СтрокойТестирования. Истина, если со СтрокаТестирования лексикографически следует за ШаблономУсловия или равна ШаблонуУсловия (две строки равны, символ в символ).
-eq
Численно равна
СтрокаТестирования обрабатывается как целое число и численно сравнивается со СтрокойТестирования. Истина, если они численно равны.
-ge
Численно больше или равно
СтрокаТестирования обрабатывается как целое число и численно сравнивается с ШаблономУсловия. Истинно, если СтрокаТестирования численно больше или равно ШаблонаУсловия.
-gt
Численно больше, чем
СтрокаТестирования обрабатывается как целое число и численно сравнивается с ШаблономУсловия. Истинно, если СтрокаТестирования численно больше, чем ШаблонУсловия.
-le
Численно меньше или равно
СтрокаТестирования обрабатывается как целое число и численно сравнивается с ШаблономУсловия. Истинно, если СтрокаТестирования численно меньше или равно ШаблонуУсловия. Избегайте путаницы с -l, при использовании вариант -L или -h.
-lt
Численно меньше
СтрокаТестирования обрабатывается как целое число и численно сравнивается с ШаблономУсловия. Истинно, если СтрокаТестирования численно меньше ШаблонаУсловия. Избегайте путаницы с -l, используя вариант -L или -h.
-ne
Численно не равна
СтрокаТестирования обрабатывается как целое число и численно сравнивается с ШаблономУсловия. Истинно, если они отличаются друг от друга. Это эквивалентно !-eq.
-d
Является ли это каталогом
Обрабатывает СтрокуТестирования как путь и проверяет, существует ли она или нет, и является ли каталогом.
-f
Является ли это обычным файлом
Обрабатывает СтрокуТестирования как путь и проверяет, существует ли она или нет, и является ли обычным файлом.
-F
Существующий файл, через подзапрос.
Проверяет, является ли СтрокаТестирования допустимым файлом, доступным через все настроенные в данный момент элементы управления доступом для этого пути. Для выполнения проверки используется внутренний подзапрос, поэтому используйте его с осторожностью – это может повлиять на производительность вашего сервера!
-h
Является ли это символической ссылкой, псевдоним для -l.
См. -l.
-l
Является ли это символической ссылкой.
Обрабатывает СтрокуТестирования как путь и проверяет, существует ли она или нет, и является ли символической ссылкой. Можно также использовать -L или -h, если есть вероятность путаницы, например, при использовании тестов -lt или -le.
-L
Является ли символической ссылкой, псевдоним для -l.
См. -l.
-s
Является ли обычным файлом с размером.
Обрабатывает СтрокуТестирования как путь и проверяет, существует ли она или нет, и является ли обычным файлом с размером больше нуля.
-U
Является ли существующим URL-адресом через подзапрос.
Проверяет, является ли СтрокаТестирования допустимым URL-адресом, доступным через все настроенные в данный момент элементы управления доступом для этого пути. Для выполнения проверки используется внутренний подзапрос, поэтому используйте это с осторожностью – это может повлиять на производительность вашего сервера!
Этот флаг возвращает только информацию о таких вещах, как управление доступом, аутентификация и авторизация. Этот флаг не возвращает информацию о коде состояния, который должен был бы вернуть сконфигурированный обработчик (статический файл, CGI, прокси и т. д.).
-x
Имеет ли разрешения на выполнение.
Обрабатывает СтрокуТестирования как путь и проверяет, существует ли она или нет, и имеет ли разрешения на выполнение. Эти разрешения определяются в соответствии с ОС на которой работает сервер.
Например:
В приведенном ниже примере -strmatch используется для сравнения REFERER с именем хоста сайта для блокирования нежелательноого хотлинкинга.
Флаги RewriteCond
Вы также можете установить специальные флаги для CondPattern, добавив [флаги] в качестве третьего аргумента в директиву RewriteCond, где flags – список, разделенный запятыми, из любого из следующих флагов:
Это делает тест нечувствительным к регистру – различия между «A-Z» и «a-z» игнорируются как в расширенной СтрокеТестирования , так и в ШаблонеУсловия. Этот флаг эффективен только для сравнения между СтрокойТестирования и ШаблономУсловия. Он не влияет на проверки файловой системы и подзапросов.
Используйте это, чтобы комбинировать условия правила связкой ИЛИ вместо И, которая подразумевается по умолчанию. Типичный пример:
Если в условии используется HTTP-заголовок, этот флаг предотвращает добавление этого заголовка в заголовок ответа Vary.
Использование этого флага может нарушить правильное кэширование ответа, если представление этого ответа зависит от значения этого заголовка. Поэтому этот флаг должен использоваться только в том случае, если смысл заголовка Vary хорошо понят.
Пример:
Чтобы показать главную страницу сайта в соответствии с заголовком запроса «User-Agent:», вы можете использовать следующее:
Объяснение: Если вы используете браузер, который идентифицирует себя как мобильный браузер (обратите внимание, что пример неполный, так как есть много других мобильных платформ), показывается мобильная версия домашней страницы. В противном случае будет использоваться стандартная страница.
Продолжение: «5. Частые случаи и примеры использования mod_rewrite».