Персональный
сайт
Игоря
Сысоева


 
english
 
sysoev.ru
 
nginx
 поехали!    
 документация    
 поддержка    
 изменения    
 скачать    
 ссылки    
 
mod_accel
mod_realip
mod_deflate
программирование
всякая всячина
windows
freebsd
apache
pppd
unix
web
 
обо мне
для писем
для денег
 

Директивы модуля ngx_http_rewrite_module

 

09.01.2007

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

Содержание

Директивы
break
if
return
rewrite
set
uninitialized_variable_warn
Внутреннее устройство

Директивы


syntax: break
default: нет
context: server, location, if

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

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

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


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.


syntax: return код
default: нет
context: server, location, if

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


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;

Если в регулярном выражении встречаются символы "}" или ";", то всё выражение нужно заключить в одинарные или двойные кавычки.


syntax: set переменная значение
default: нет
context: server, location, if

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


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

(C) Игорь Сысоев
http://sysoev.ru