Модуль ngx_http_rewrite_module
| Директивы break if return rewrite rewrite_log set uninitialized_variable_warn Внутреннее устройство | 
Модуль ngx_http_rewrite_module позволяет
изменять URI запроса с помощью регулярных выражений PCRE, делать перенаправления
и выбирать конфигурацию по условию.
Директивы break, if, return, rewrite и set обрабатываются в следующем порядке:
- последовательно выполняются директивы этого модуля, описанные на уровне server;
- в цикле:
Директивы
| Синтаксис: | break; | 
|---|---|
| Умолчание: | — | 
| Контекст: | server,location,if | 
Завершает обработку текущего набора директив модуля
ngx_http_rewrite_module.
Если директива указана внутри location, дальнейшая обработка запроса продолжается в этом location.
Пример:
if ($slow) {
    limit_rate 10k;
    break;
}
| Синтаксис: | if ( | 
|---|---|
| Умолчание: | — | 
| Контекст: | server,location | 
Проверяется указанное условие.
Если оно истинно, то выполняются указанные в фигурных скобках директивы
этого модуля и запросу назначается конфигурация, указанная внутри
директивы if.
Конфигурации внутри директив if наследуются с
предыдущего уровня конфигурации.
В качестве условия могут быть заданы:
- 
имя переменной; ложными значениями переменной являются пустая строка
или “0”;До версии 1.0.1 ложным значением также являлась любая строка, начинающаяся на “ 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 return return  | 
|---|---|
| Умолчание: | — | 
| Контекст: | server,location,if | 
Завершает обработку и возвращает клиенту указанный код.
Нестандартный код 444 закрывает соединение без передачи
заголовка ответа.
Начиная с версии 0.8.42 можно задать
либо URL перенаправления (для кодов 301, 302, 303, 307 и 308)
либо текст тела ответа (для остальных кодов).
В тексте тела ответа и URL перенаправления можно использовать переменные.
Как частный случай, URL перенаправления может быть задан как URI,
локальный для данного сервера, при этом полный URL перенаправления
формируется согласно схеме запроса ($scheme) и директивам
server_name_in_redirect и
port_in_redirect.
Кроме того, в качестве единственного параметра можно указать
URL для временного перенаправления с кодом 302.
Такой параметр должен начинаться со строк “http://”,
“https://” или “$scheme”.
В URL можно использовать переменные.
До версии 0.7.51 можно было возвращать только следующие коды: 204, 400, 402 — 406, 408, 410, 411, 413, 416 и 500 — 504.
До версий 1.1.16 и 1.0.13 код 307 не обрабатывался как перенаправление.
До версии 1.13.0 код 308 не обрабатывался как перенаправление.
См. также директиву error_page.
| Синтаксис: | rewrite 
     | 
|---|---|
| Умолчание: | — | 
| Контекст: | server,location,if | 
Если указанное регулярное выражение соответствует URI запроса, URI изменяется
в соответствии со строкой замены.
Директивы rewrite выполняются последовательно,
в порядке их следования в конфигурационном файле.
С помощью флагов можно прекратить дальнейшую обработку директив.
Если строка замены начинается с “http://”,
“https://” или “$scheme”,
то обработка завершается и клиенту возвращается перенаправление.
Необязательный параметр флаг может быть одним из:
- last
- 
завершает обработку текущего набора директив модуля
ngx_http_rewrite_module, после чего ищется новый location, соответствующий изменённому URI;
- break
- 
завершает обработку текущего набора директив модуля
ngx_http_rewrite_moduleаналогично директиве break;
- redirect
- 
возвращает временное перенаправление с кодом 302;
используется, если заменяющая строка не начинается с
“http://”, “https://” или “$scheme”;
- permanent
- возвращает постоянное перенаправление с кодом 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,
иначе nginx сделает 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  | 
|---|---|
| Умолчание: | rewrite_log off; | 
| Контекст: | http,server,location,if | 
Разрешает или запрещает записывать в
error_log
на уровне notice
результаты обработки директив модуля ngx_http_rewrite_module.
| Синтаксис: | set  | 
|---|---|
| Умолчание: | — | 
| Контекст: | server,location,if | 
Устанавливает значение указанной переменной. В качестве значения можно использовать текст, переменные и их комбинации.
| Синтаксис: | uninitialized_variable_warn  | 
|---|---|
| Умолчание: | uninitialized_variable_warn on; | 
| Контекст: | http,server,location,if | 
Определяет, нужно ли писать в лог предупреждения о неинициализированных переменных.
Внутреннее устройство
Директивы модуля ngx_http_rewrite_module
компилируются на стадии конфигурации во внутренние инструкции,
интерпретируемые во время обработки запроса.
Интерпретатор представляет из себя простую стековую виртуальную машину.
Например, директивы
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
нет, поскольку она не имеет отношения к модулю
ngx_http_rewrite_module.
Для блока if создаётся отдельная конфигурация.
Если условие истинно, запрос получает эту конфигурацию,
и в ней limit_rate равен 10k.
Директиву
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
можно сделать на одну инструкцию меньше, если в регулярном выражении перенести первый слэш внутрь скобок:
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
Тогда соответствующие инструкции будут выглядеть так:
проверка регулярного выражения копирование $1 копирование "/mp3/" копирование $2 копирование ".mp3" завершение регулярного выражения завершение всего кода
