Перейти к содержанию

array-var: Переменные типа массив для NGINX

Установка

Вы можете установить этот модуль в любой дистрибутив, основанный на RHEL, включая, но не ограничиваясь:

  • RedHat Enterprise Linux 7, 8, 9 и 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-array-var
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-array-var

Включите модуль, добавив следующее в начало /etc/nginx/nginx.conf:

load_module modules/ngx_http_array_var_module.so;

Этот документ описывает nginx-module-array-var v0.6, выпущенный 23 мая 2022 года.


location /foo {
    array_split ',' $arg_files to=$array;

    # используйте директиву set_quote_sql_str в модуле ngx_set_misc
    # для отображения на каждый элемент массива $array:
    array_map_op set_quote_sql_str $array;

    array_map "name = $array_it" $array;

    array_join ' or ' $array to=$sql_condition;

    # ну, мы могли бы передать это в ngx_drizzle для общения с MySQL, например ;)
    echo "select * from files where $sql_condition";
}

Описание

Этот модуль предоставляет переменные типа массив для nginx.conf.

Под капотом этот модуль просто "злоупотребляет" строковыми значениями nginx, чтобы хранить бинарные указатели на структуры данных C (структура ngx_array_t ядра NGINX).

Тип массива дает nginx.conf замечательные возможности для обработки списков значений. В настоящее время, однако, настоятельно рекомендуется использовать модуль ngx_lua, чтобы получить всю мощь сценариев, предоставляемую языком Lua в nginx.

Директивы

array_split

синтаксис: array_split <разделитель> <объект> to=$target_variable

по умолчанию: нет

контекст: http, server, server if, location, location if

Разделяет строковое значение в аргументе subject с помощью строкового разделителя, указанного в аргументе separator. Результат — значение типа массив, сохраненное в переменной nginx, указанной опцией to=VAR.

Например,

array_split "," $arg_names to=$names;

разделит строковые значения в аргументе запроса URI names на значение типа массив, сохраненное в пользовательской переменной nginx $names.

Эта директива создает переменную типа массив. Переменные типа массив не могут использоваться вне директив, предлагаемых этим модулем. Если вы хотите использовать значения в переменной типа массив в других контекстах, вы должны использовать директиву array_join, чтобы получить нормальное строковое значение.

array_join

синтаксис: array_join <разделитель> $array_var

по умолчанию: нет

контекст: http, server, server if, location, location if

Объединяет элементы в переменной nginx типа массив ($array_var) в одно строковое значение с разделителем, указанным первым аргументом.

Например,

location /foo {
    array_split ',' $arg_names to=$names;
    array_join '+' $names;
    echo $names;
}

Тогда запрос GET /foo?names=Bob,Marry,John даст тело ответа

Bob+Marry+John

В приведенном выше примере мы используем директиву echo модуля ngx_echo для вывода конечного результата.

array_map

синтаксис: array_map <шаблон> $array_var

синтаксис: array_map <шаблон> $array_var to=$new_array_var

по умолчанию: нет

контекст: http, server, server if, location, location if

Отображает строковый шаблон на каждый элемент в указанной переменной nginx типа массив. Внутри строкового шаблона вы можете использовать специальную переменную итератора $array_it, чтобы ссылаться на текущий элемент массива, который отображается.

Например,

array_map "[$array_it]" $names;

изменит каждый элемент в массивной переменной $names, обрамляя строковое значение каждого элемента квадратными скобками. Модификация происходит на месте в этом случае.

Если вы не хотите модификаций на месте, вы можете использовать опцию to=$var, чтобы указать новую переменную nginx для хранения результатов. Например,

array_map "[$array_it]" $names to=$new_names;

где результаты сохраняются в другой (типа массив) переменной nginx с именем $new_names, в то время как переменная $names остается неизменной.

Ниже приведен полный пример для этого:

location /foo {
    array_split ',' $arg_names to=$names;
    array_map '[$array_it]' $names;
    array_join '+' $names;
    echo "$names";
}

Тогда запрос GET /foo?names=bob,marry,nomas даст тело ответа

[bob]+[marry]+[nomas]

array_map_op

синтаксис: array_map_op <директива> $array_var

синтаксис: array_map_op <директива> $array_var to=$new_array_var

по умолчанию: нет

контекст: http, server, server if, location, location if

Похоже на директиву array_map, но отображает указанную директиву конфигурации nginx вместо строкового шаблона на каждый элемент в указанной переменной nginx типа массив. Результат применения указанной директивы конфигурации становится результатом отображения.

Директива конфигурации nginx, используемая в качестве итератора, должна быть реализована в подмодуле set_var Nginx Devel Kit (NDK) с помощью ndk_set_var_value. Например, следующие директивы set-misc-nginx-module могут быть вызваны таким образом:

Это операция высшего порядка, где другие директивы конфигурации nginx могут использоваться в качестве аргументов для этой директивы map_array_op.

Рассмотрим следующий пример,

array_map_op set_quote_sql_str $names;

Эта строка изменяет каждый элемент в переменной nginx типа массив $names, применяя директиву set_quote_sql_str, предоставляемую модулем ngx_set_misc, по одному. Результат заключается в том, что каждый элемент массива $names был экранирован как литеральные значения строк SQL.

Вы также можете указать опцию to=$var, если вы не хотите модификаций на месте входных массивов. Например,

array_map_op set_quote_sql_str $names to=$quoted_names;

сохранит экранированные элементы в новой (типа массив) переменной nginx с именем $quoted_names, оставив $names неизменным.

Следующий пример является относительно полным:

location /foo {
    array_split ',' $arg_names to=$names;
    array_map_op set_quote_sql_str $names;
    array_join '+' $names to=$res;
    echo $res;
}

Тогда запрос GET /foo?names=bob,marry,nomas даст тело ответа

'bob'+'marry'+'nomas'

Довольно круто, не так ли?

Здесь мы предполагаем, что вы установите nginx в /opt/nginx/.

./configure --prefix=/opt/nginx \ --add-module=/path/to/ngx_devel_kit \ --add-module=/path/to/array-var-nginx-module

make -j2 make install ```

Скачайте последнюю версию релиза этого модуля из array-var-nginx-module file list, и последний архив для ngx_devel_kit из его file list.

Кроме того, этот модуль включен и включен по умолчанию в пакет OpenResty.

См. также

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-array-var.