Spec-Zone.ru › Apache HTTP Server

Выражения в Apache HTTP Server

Исторически существует несколько вариантов синтаксиса выражений, используемых для задания условий в различных модулях Apache HTTP Server. В настоящее время ведётся работа над тем, чтобы использовать во всех директивах конфигурации только один вариант, называемый ap_expr. В этом документе описан анализатор выражений ap_expr.

Выражение ap_expr предназначено для замены большинства других вариантов выражений в HTTPD. Например, устаревшие выражения SSLRequire можно заменить на Require expr.

Грамматика в нотации Бэкуса — Наура

Форма Бэкуса — Наура (BNF) — это способ записи контекстно-свободных грамматик, часто используемый для описания синтаксиса языков программирования. В большинстве случаев выражения используются для задания логических значений. В этом случае начальным символом в BNF является expr. Однако некоторые директивы, например LogMessage, принимают выражения, результатом которых является строковое значение. Для них начальным символом в BNF является string.

expr        ::= "true" | "false"
              | "!" expr
              | expr "&&" expr
              | expr "||" expr
              | "(" expr ")"
              | comp

comp        ::= stringcomp
              | integercomp
              | unaryop word
              | word binaryop word
              | word "in" "{" wordlist "}"
              | word "in" listfunction
              | word "=~" regex
              | word "!~" regex


stringcomp  ::= word "==" word
              | word "!=" word
              | word "<"  word
              | word "<=" word
              | word ">"  word
              | word ">=" word

integercomp ::= word "-eq" word | word "eq" word
              | word "-ne" word | word "ne" word
              | word "-lt" word | word "lt" word
              | word "-le" word | word "le" word
              | word "-gt" word | word "gt" word
              | word "-ge" word | word "ge" word

wordlist    ::= word
              | wordlist "," word

word        ::= word "." word
              | digit
              | "'" string "'"
              | """ string """
              | variable
              | rebackref
              | function

string      ::= stringpart
              | string stringpart

stringpart  ::= cstring
              | variable
              | rebackref

cstring     ::= ...
digit       ::= [0-9]+

variable    ::= "%{" varname "}"
              | "%{" funcname ":" funcargs "}"

rebackref   ::= "$" [0-9]

function     ::= funcname "(" word ")"

listfunction ::= listfuncname "(" word ")"

Переменные

Анализатор выражений предоставляет ряд переменных вида %{HTTP_HOST}. Обратите внимание, что значение переменной может зависеть от этапа обработки запроса, на котором она вычисляется. Например, выражение, используемое в директиве <If >, вычисляется до выполнения аутентификации. Поэтому в этом случае значение %{REMOTE_USER} не будет задано.

Следующие переменные предоставляют значения указанных заголовков HTTP-запроса. Значения других заголовков можно получить с помощью функции req. Использование этих переменных может привести к добавлению имени заголовка в заголовок Vary ответа HTTP, за исключением случаев, отдельно отмеченных для директивы, принимающей выражение. Чтобы избежать такого поведения, можно использовать функцию req_novary.

Имя
HTTP_ACCEPT
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_REFERER
HTTP_USER_AGENT

Другие переменные, связанные с запросом

Имя Описание
REQUEST_METHOD Метод входящего запроса HTTP (например, GET)
REQUEST_SCHEME Схема URI запроса
REQUEST_URI Путь URI запроса
DOCUMENT_URI То же, что и REQUEST_URI
REQUEST_FILENAME Полный путь в локальной файловой системе к файлу или скрипту, соответствующему запросу, если сервер уже определил его к моменту обращения к REQUEST_FILENAME. В противном случае, например при использовании в контексте виртуального хоста, значение совпадает с REQUEST_URI
SCRIPT_FILENAME То же, что и REQUEST_FILENAME
LAST_MODIFIED Дата и время последнего изменения файла в формате 20101231235959, если сервер уже определил их к моменту обращения к LAST_MODIFIED.
SCRIPT_USER Имя пользователя — владельца скрипта.
SCRIPT_GROUP Имя группы, к которой относится скрипт.
PATH_INFO Хвостовая часть пути; см. AcceptPathInfo
QUERY_STRING Строка запроса текущего запроса
IS_SUBREQ "true", если текущий запрос является подзапросом, и "false" в противном случае
THE_REQUEST Полная строка запроса (например, "GET /index.html HTTP/1.1")
REMOTE_ADDR IP-адрес удалённого хоста
REMOTE_PORT Порт удалённого хоста (версия 2.4.26 и новее)
REMOTE_HOST Имя удалённого хоста
REMOTE_USER Имя аутентифицированного пользователя, если он есть (недоступно во время <If>)
REMOTE_IDENT Имя пользователя, заданное директивой mod_ident
SERVER_NAME ServerName текущего виртуального хоста
SERVER_PORT Порт сервера текущего виртуального хоста; см. ServerName
SERVER_ADMIN ServerAdmin текущего виртуального хоста
SERVER_PROTOCOL Протокол, используемый запросом
DOCUMENT_ROOT DocumentRoot текущего виртуального хоста
AUTH_TYPE Настроенный AuthType (например, "basic")
CONTENT_TYPE Тип содержимого ответа (недоступно во время <If>)
HANDLER Имя обработчика, создающего ответ
HTTP2 "on", если запрос использует http/2, и "off" в противном случае
HTTPS "on", если запрос использует https, и "off" в противном случае
IPV6 "on", если соединение использует IPv6, и "off" в противном случае
REQUEST_STATUS Код ошибки HTTP для запроса (недоступно во время <If>)
REQUEST_LOG_ID Идентификатор ошибки запроса в журнале ошибок (см. ErrorLogFormat)
CONN_LOG_ID Идентификатор ошибки соединения в журнале ошибок (см. ErrorLogFormat)
CONN_REMOTE_ADDR IP-адрес узла-партнёра соединения (см. модуль mod_remoteip)
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT

Прочие переменные

Имя Описание
TIME_YEAR Текущий год (например, 2010)
TIME_MON Текущий месяц (01, ..., 12)
TIME_DAY Текущий день месяца (01, ...)
TIME_HOUR Часовая часть текущего времени (00, ..., 23)
TIME_MIN Минутная часть текущего времени
TIME_SEC Секундная часть текущего времени
TIME_WDAY День недели (нумерация начинается с 0 для воскресенья)
TIME Дата и время в формате 20101231235959
SERVER_SOFTWARE Строка версии сервера
API_VERSION Дата версии API (магическое число модуля)

Некоторые модули регистрируют дополнительные переменные; см., например, mod_ssl.

Бинарные операторы

За исключением некоторых встроенных операторов сравнения, бинарные операторы имеют вид "-[a-zA-Z][a-zA-Z0-9_]+", то есть состоят из дефиса и как минимум двух символов. Регистр букв в имени не учитывается. Модули могут регистрировать дополнительные бинарные операторы.

Операторы сравнения

Имя Альтернатива Описание
== = Равенство строк
!= Неравенство строк
< Строка меньше
<= Строка меньше или равна
> Строка больше
>= Строка больше или равна
=~ Строка соответствует регулярному выражению
!~ Строка не соответствует регулярному выражению
-eq eq Равенство целых чисел
-ne ne Неравенство целых чисел
-lt lt Меньше (целые числа)
-le le Меньше или равно (целые числа)
-gt gt Больше (целые числа)
-ge ge Больше или равно (целые числа)

Другие бинарные операторы

Имя Описание
-ipmatch IP-адрес соответствует адресу/маске подсети
-strmatch левая строка соответствует шаблону, заданному правой строкой (содержащей подстановочные символы *, ?, [])
-strcmatch то же, что и -strmatch, но без учёта регистра
-fnmatch то же, что и -strmatch, но подстановочные символы не соответствуют косым чертам

Унарные операторы

Унарные операторы принимают один аргумент и имеют вид "-[a-zA-Z]", то есть состоят из дефиса и одного символа. Регистр букв в имени имеет значение. Модули могут регистрировать дополнительные унарные операторы.

Имя Описание Ограниченный
-d Аргумент рассматривается как имя файла. Истина, если файл существует и является каталогом да
-e Аргумент рассматривается как имя файла. Истина, если файл (или каталог, или специальный файл) существует да
-f Аргумент рассматривается как имя файла. Истина, если файл существует и является обычным файлом да
-s Аргумент рассматривается как имя файла. Истина, если файл существует и не пуст да
-L Аргумент рассматривается как имя файла. Истина, если файл существует и является символической ссылкой да
-h Аргумент рассматривается как имя файла. Истина, если файл существует и является символической ссылкой (то же, что и -L) да
-F Истина, если строка задаёт существующий файл, доступный с учётом всех настроенных в данный момент правил контроля доступа сервера для этого пути. Для проверки используется внутренний подзапрос, поэтому применяйте оператор с осторожностью: он может повлиять на производительность сервера!
-U Истина, если строка задаёт допустимый URL, доступный с учётом всех настроенных в данный момент правил контроля доступа сервера для этого пути. Для проверки используется внутренний подзапрос, поэтому применяйте оператор с осторожностью: он может повлиять на производительность сервера!
-A Псевдоним для -U
-n Истина, если строка не пуста
-z Истина, если строка пуста
-T Ложь, если строка пуста, равна "0", "off", "false" или "no" (без учёта регистра). В противном случае — истина.
-R То же, что и "%{REMOTE_ADDR} -ipmatch ...", но работает эффективнее

Операторы, отмеченные как «ограниченные», недоступны в некоторых модулях, например mod_include.

Функции

Обычные функции, возвращающие строковое значение, принимают одну строку в качестве аргумента и возвращают строку. Регистр букв в именах функций не учитывается. Модули могут регистрировать дополнительные функции.

Имя Описание Особые примечания
req, http Получить заголовок HTTP-запроса; имена заголовков могут добавляться в заголовок Vary, см. ниже
req_novary То же, что и req, но имена заголовков не добавляются в заголовок Vary
resp Получить заголовок HTTP-ответа (большинство заголовков ответа ещё не будут установлены во время <If>)
reqenv Получить переменную окружения запроса (для краткости к переменным также можно обращаться с помощью v). порядок выполнения
osenv Получить переменную окружения операционной системы
note Получить заметку запроса порядок выполнения
env Вернуть первое совпадение из note, reqenv, osenv порядок выполнения
tolower Преобразовать строку в нижний регистр
toupper Преобразовать строку в верхний регистр
escape Экранировать специальные символы в кодировке %hex
unescape Снять экранирование строки в кодировке %hex, оставляя закодированные косые черты без изменений; вернуть пустую строку, если найдено %00
base64 Закодировать строку в формате base64
unbase64 Декодировать строку в формате base64; вернуть строку, обрезанную при обнаружении 0x00
md5 Вычислить хеш строки с помощью MD5, затем представить хеш в шестнадцатеричном формате
sha1 Вычислить хеш строки с помощью SHA1, затем представить хеш в шестнадцатеричном формате
file Прочитать содержимое файла (включая символы конца строки, если они есть) ограничена
filesize Вернуть размер файла (или 0, если файл не существует или не является обычным файлом) ограничена
ldap Экранировать символы в соответствии с правилами экранирования отличительных имён LDAP (RFC4514) и фильтров LDAP (RFC4515).
(Доступно в httpd версии 2.4.53 и новее)

Функции, отмеченные как «ограниченные» в последнем столбце, недоступны в некоторых модулях, например mod_include.

При использовании функций, отмеченных как «порядок выполнения» в последнем столбце, следует учитывать порядок выполнения различных компонентов сервера, особенно если функция используется в директиве <If>, которая выполняется на относительно раннем этапе.

Порядок обработки переменных окружения

При поиске переменных окружения в условии <If> важно учитывать, что разрешение переменных происходит на очень раннем этапе обработки запроса. Как правило, директивы, заданные вне контекста виртуального хоста (в контексте каталога, расположения или htaccess), к этому моменту ещё не успевают выполниться. SetEnvIf в области видимости виртуального хоста — одна из директив, выполняющихся до этого разрешения

Если reqenv используется вне <If>, разрешение обычно происходит позже, но точный момент зависит от директивы, в которой используется выражение.

При использовании функций req или http имя заголовка автоматически добавляется в заголовок Vary ответа HTTP, за исключением случаев, отдельно отмеченных для директивы, принимающей выражение. Чтобы предотвратить добавление имён в заголовок Vary, можно использовать функцию req_novary.

Помимо функций, возвращающих строковое значение, существуют функции, возвращающие списки: они принимают одну строку в качестве аргумента и возвращают список слов, то есть список строк. Список слов можно использовать со специальным оператором -in. Регистр букв в именах функций не учитывается. Модули могут регистрировать дополнительные функции.

Встроенных функций, возвращающих списки, нет. mod_ssl предоставляет PeerExtList. Подробности см. в описании SSLRequire (однако PeerExtList также можно использовать вне SSLRequire).

Примеры выражений

В следующих примерах показано, как можно использовать выражения для проверки запросов:

# Compare the host name to example.com and redirect to www.example.com if it matches
<If "%{HTTP_HOST} == 'example.com'">
    Redirect permanent "/" "http://www.example.com/"
</If>

# Force text/plain if requesting a file with the query string contains 'forcetext'
<If "%{QUERY_STRING} =~ /forcetext/">
    ForceType text/plain
</If>

# Only allow access to this content during business hours
<Directory "/foo/bar/business">
    Require expr %{TIME_HOUR} -gt 9 && %{TIME_HOUR} -lt 17
</Directory>

# Check a HTTP header for a list of values
<If "%{HTTP:X-example-header} in { 'foo', 'bar', 'baz' }">
    Header set matched true
</If>

# Check an environment variable for a regular expression, negated.
<If "! reqenv('REDIRECT_FOO') =~ /bar/">
    Header set matched true
</If>

# Check result of URI mapping by running in Directory context with -f
<Directory "/var/www">
    AddEncoding x-gzip gz
<If "-f '%{REQUEST_FILENAME}.unzipme' && ! %{HTTP:Accept-Encoding} =~ /gzip/">
      SetOutputFilter INFLATE
</If>
</Directory>

# Check against the client IP
<If "-R '192.168.1.0/24'">
    Header set matched true
</If>

# Function example in boolean context
<If "md5('foo') == 'acbd18db4cc2f85cedef654fccc4a4d8'">
  Header set checksum-matched true
</If>

# Function example in string context
Header set foo-checksum "expr=%{md5:foo}"

# This delays the evaluation of the condition clause compared to <If>
Header always set CustomHeader my-value "expr=%{REQUEST_URI} =~ m#^/special_path\.php$#"

# Conditional logging
CustomLog logs/access-errors.log common "expr=%{REQUEST_STATUS} >= 400"
CustomLog logs/access-errors-specific.log common "expr=%{REQUEST_STATUS} -in {'405','410'}"

Прочее

Имя Альтернатива Описание
-in in строка содержится в списке слов
/regexp/ m#regexp# Регулярное выражение (вторая форма позволяет использовать разделители, отличные от /)
/regexp/i m#regexp#i Регулярное выражение без учёта регистра
$0 ... $9
Обратные ссылки регулярных выражений

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

Строки $0 ... $9 позволяют ссылаться на группы захвата из ранее выполненных регулярных выражений, успешно нашедших совпадение. Обычно их можно использовать только в том же выражении, что и соответствующее регулярное выражение, однако некоторые модули допускают особые варианты использования.

Сравнение с SSLRequire

Синтаксис ap_expr в основном является расширением синтаксиса устаревшей директивы SSLRequire. Различия описаны в документации SSLRequire.

История версий

Функция req_novary доступна в версии 2.4.4 и новее.

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

Spec-Zone.ru

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