RuHttpRewriteModule

= ngx_http_rewrite_module =

Модуль ngx_http_rewrite_module позволяет изменять URI с помощью регулярных выражений, делать редиректы и выбирать конфигурацию в зависимости от переменных. Если директивы этого модуля описаны на уровне сервера, то они выполняются до того, как определяется location для запроса. Если в выбранном location тоже есть директивы модуля ngx_http_rewrite_module, то они также выполняются. Если URI изменился в результате исполнения директив внутри location, то снова определяется location для уже нового URI. Этот цикл может повторяться до 10 раз, после чего nginx возвращает ошибку "Server Internal Error" (500). Содержание

Директивы

 * [#break break]
 * [#if if]
 * [#return return]
 * [#rewrite rewrite]
 * [#set set]
 * [#uninitialized_variable_warn uninitialized_variable_warn]

Внутреннее устройство

break
syntax: break

default: нет

context: server, location, if

Директива завершает обработку текущего набора директив ngx_http_rewrite_module.

Пример использования:
 * if ($slow) {
 * limit_rate 10k;
 * break;
 * }

if
syntax: ''if (условие) { ... }''

default: нет

context: server, location

Директива 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 (!-f $request_filename) {
 * break;
 * proxy_pass http://127.0.0.1;
 * }


 * if ($slow) {
 * limit_rate 10k;
 * }


 * if ($invalid_referer) {
 * return  403;
 * }

Значение встроенной переменной $invalid_referer задаётся директивой valid_referers.

return
syntax: return код

default: нет

context: server, location, if

Директива return завершает исполнение кода и возвращает клиенту указанный код. Можно использовать следующие значения: 204, 400, 402 — 406, 408, 410, 411, 413, 416 и 500 — 504. Кроме того, нестандартный код 444 закрывает соединение без передачи заголовка ответа.

rewrite
syntax: rewrite regex замена флаг

default: нет

context: server, location, if

Директива rewrite изменяет URI в соответствии с регулярным выражением и строкой замены. Директивы выполняются в порядке их следования в конфигурационном файле. С помощью флагов можно досрочно прекратить исполнение директив. Если строка замены начинается с "http://", то клиенту будет возвращён редирект и обработка директив также завершается.

Флаги могут быть следующими:


 * last — завершает обработку текущего набора директив ngx_http_rewrite_module, после чего ищется соответствие URI и location;
 * break — завершает обработку текущего набора директив ngx_http_rewrite_module;
 * redirect — возвращает временный редирект с кодом 302; используется, если заменяющая строка не начинается с "http://";
 * permanent — возвращает постоянный редирект с кодом 301.

Пример использования:
 * 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;

set
syntax: set переменная значение

default: нет

context: server, location, if

Директива устанавливает значение для указанной переменной. В качестве значения можно использовать текст, переменные и их комбинации.

uninitialized_variable_warn
syntax: uninitialized_variable_warn on|off

default: uninitialized_variable_warn on

context: 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 создаётся такая же конфигурация, как и для блока location. Если условие истинно, то запрос получает конфигурацию, соответствующую блоку if, и в этой конфигурации limit_rate равен 10k.

Директиву
 * rewrite ^/(download/.*)/media/(.*)\..*$  /$1/mp3/$2.mp3  break;

можно сделать на один код меньше, если в регулярном выражении включить первый слэш в скобки:
 * rewrite ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  break;

тогда её коды будут выглядеть так:
 * проверка регулярного выражения
 * копирование $1
 * копирование "/mp3/"
 * копирование $2
 * копирование ".mp3"
 * завершение регулярного выражения
 * завершение всего кода