FAQ

Page Discussion Edit History

RuHttpRewriteModule

Contents

[edit] 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). Содержание


[edit] Директивы

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

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

Template:Anchor

[edit] break

syntax: break

default: нет

context: server, location, if

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

Пример использования:

: if ($slow) {
: limit_rate  10k;
: break;
: }

Template:Anchor

[edit] 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.

Template:Anchor

[edit] return

syntax: return код

default: нет

context: server, location, if

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

Template:Anchor

[edit] 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;

Template:Anchor

[edit] set

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

default: нет

context: server, location, if

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

Template:Anchor

[edit] 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"
: завершение регулярного выражения
: завершение всего кода