Rewrite#
Позволяет изменять URI запроса с помощью регулярных выражений PCRE, делать перенаправления и выбирать конфигурацию по условию.
Директивы break, if, return, rewrite и set обрабатываются в следующем порядке:
последовательно выполняются директивы этого модуля, описанные на уровне server;
-
в цикле:
Директивы#
break#
Завершает обработку текущего набора директив модуля http_rewrite.
Если директива указана внутри location, дальнейшая обработка запроса продолжается в этом location.
Пример:
if ($slow) {
limit_rate 10k;
break;
}
if#
Проверяется указанное условие. Если оно истинно, то выполняются указанные в фигурных скобках директивы этого модуля и запросу назначается конфигурация, указанная внутри директивы if. Конфигурации внутри директив if наследуются с предыдущего уровня конфигурации.
В качестве условия могут быть заданы:
имя переменной; ложными значениями переменной являются пустая строка или "0";
сравнение переменной со строкой с помощью операторов "=" и "!=";
соответствие переменной регулярному выражению с учетом регистра символов — "~" и без него — "~*". В регулярных выражениях можно использовать выделения, которые затем доступны в виде переменных $1..$9. Также можно использовать отрицательные операторы "!~" и "!~*". Если в регулярном выражении встречаются символы "}" или ";", то все выражение следует заключить в одинарные или двойные кавычки.
проверка существования файла с помощью операторов "-f" и "!-f";
проверка существования каталога с помощью операторов "-d" и "!-d";
проверка существования файла, каталога или символической ссылки с помощью операторов "-e" и "!-e";
проверка исполняемости файла с помощью операторов "-x" и "!-x".
Примеры:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) {
return 405;
}
if ($slow) {
limit_rate 10k;
}
if ($invalid_referer) {
return 403;
}
Примечание
Значение встроенной переменной $invalid_referer задается директивой valid_referers.
return#
|
|
По умолчанию |
— |
server, location, if |
Завершает обработку и возвращает клиенту указанный код
. Нестандартный
код 444 закрывает соединение без передачи заголовка ответа.
Можно задать либо URL перенаправления (для кодов 301, 302, 303, 307 и 308) либо текст тела ответа (для остальных кодов). В тексте тела ответа и URL перенаправления можно использовать переменные. Как частный случай, URL перенаправления может быть задан как URI, локальный для данного сервера, при этом полный URL перенаправления формируется согласно схеме запроса ($scheme) и директивам server_name_in_redirect и port_in_redirect.
Кроме того, в качестве единственного параметра можно указать URL для временного перенаправления с кодом 302. Такой параметр должен начинаться со строк "http://", "https://" или "$scheme". В URL можно использовать переменные.
См. также директиву error_page.
rewrite#
Если указанное регулярное выражение regex
соответствует URI запроса, URI
изменяется в соответствии со строкой замены
. Директивы rewrite
выполняются последовательно, в порядке их следования в конфигурационном файле. С
помощью флага
можно прекратить дальнейшую обработку директив. Если
строка замены
начинается с "http://", "https://" или "$scheme", то
обработка завершается и клиенту возвращается перенаправление.
Необязательный параметр флаг
может быть одним из:
|
завершает обработку текущего набора директив модуля http_rewrite, после чего ищется новый location, соответствующий измененному URI; |
|
завершает обработку текущего набора директив модуля http_rewrite аналогично директиве break; |
|
возвращает временное перенаправление с кодом 302; используется, если
строка |
|
возвращает постоянное перенаправление с кодом 301. |
Полный URL перенаправлений формируется согласно схеме запроса ($scheme) и директив server_name_in_redirect и port_in_redirect.
Пример:
server {
# ...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
# ...
}
Если же эти директивы поместить в location "/download/", то нужно заменить флаг last
на break
, иначе Angie сделает 10 циклов и вернет ошибку 500:
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
Если в строке замены
указаны новые аргументы запроса, то предыдущие
аргументы запроса добавляются после них. Если такое поведение нежелательно,
можно отказаться от этого добавления, указав в конце строки замены знак вопроса,
например:
rewrite ^/users/(.*)$ /show?user=$1? last;
Если в регулярном выражении встречаются символы "}" или ";", то все выражение следует заключить в одинарные или двойные кавычки.
rewrite_log#
Разрешает или запрещает записывать в error_log на уровне notice результаты обработки директив модуля http_rewrite.
set#
Устанавливает значение указанной переменной. В качестве значения можно использовать текст, переменные и их комбинации.
uninitialized_variable_warn#
|
|
По умолчанию |
|
http, server, location, if |
Определяет, нужно ли писать в лог предупреждения о неинициализированных переменных.
Внутреннее устройство#
Директивы модуля http_rewrite компилируются на стадии конфигурации во внутренние инструкции, интерпретируемые во время обработки запроса. Интерпретатор представляет из себя простую стековую виртуальную машину.
Например, директивы
location /download/ {
if ($forbidden) {
return 403;
}
if ($slow) {
limit_rate 10k;
}
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
}
будут транслированы в такие инструкции:
переменная $forbidden
проверка на ноль
возврат 403
завершение всего кода
переменная $slow
проверка на ноль
проверка регулярного выражения
копирование "/"
копирование $1
копирование "/mp3/"
копирование $2
копирование ".mp3"
завершение регулярного выражения
завершение всего кода
Обратите внимание, что инструкций для директивы limit_rate нет, поскольку она не имеет отношения к модулю http_rewrite. Для блока if создается отдельная конфигурация. Если условие истинно, запрос получает эту конфигурацию, и в ней limit_rate равен 10k.
Директиву
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
можно сделать на одну инструкцию меньше, если в регулярном выражении перенести первую косую черту внутрь скобок:
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
Тогда соответствующие инструкции будут выглядеть так:
проверка регулярного выражения
копирование $1
копирование "/mp3/"
копирование $2
копирование ".mp3"
завершение регулярного выражения
завершение всего кода