Модуль ngx_stream_js_module
Этот перевод может быть устаревшим. Смотрите английскую версию для ознакомления с последними изменениями.
Модуль ngx_stream_js_module
позволяет задавать
обработчики на njs —
подмножестве языка JavaScript.
Инструкция по сборке и установке доступны здесь.
Пример конфигурации
Пример работает начиная с версии 0.4.0.
stream { js_import stream.js; js_set $bar stream.bar; js_set $req_line stream.req_line; server { listen 12345; js_preread stream.preread; return $req_line; } server { listen 12346; js_access stream.access; proxy_pass 127.0.0.1:8000; js_filter stream.header_inject; } } http { server { listen 8000; location / { return 200 $http_foo\n; } } }
Файл stream.js
:
var line = ''; function bar(s) { var v = s.variables; s.log("hello from bar() handler!"); return "bar-var" + v.remote_port + "; pid=" + v.pid; } function preread(s) { s.on('upload', function (data, flags) { var n = data.indexOf('\n'); if (n != -1) { line = data.substr(0, n); s.done(); } }); } function req_line(s) { return line; } // Чтение строки HTTP-запроса. // Получение байт в 'req' до того как // будет прочитана строка запроса. // Добавление HTTP-заголовка в запрос клиента var my_header = 'Foo: foo'; function header_inject(s) { var req = ''; s.on('upload', function(data, flags) { req += data; var n = req.search('\n'); if (n != -1) { var rest = req.substr(n + 1); req = req.substr(0, n + 1); s.send(req + my_header + '\r\n' + rest, flags); s.off('upload'); } }); } function access(s) { if (s.remoteAddress.match('^192.*')) { s.deny(); return; } s.allow(); } export default {bar, preread, req_line, header_inject, access};
Директивы
Синтаксис: |
js_access |
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Задаёт функцию njs, которая будет вызываться в access-фазе. Начиная с 0.4.0 можно ссылаться на функцию модуля.
Функция вызывается однократно при первом достижении сессией access-фазы. Функция вызывается со следующими аргументами:
s
- объект stream-сессии
В этой фазе может происходить инициализация,
также при помощи метода
s.on()
может регистрироваться вызов
для каждого входящего блока данных пока не будет вызван один из методов:
s.done()
s.decline()
,
s.allow()
.
При вызове любого из этих методов обработка сессии
переходит на следующую фазу
и все текущие вызовы
s.on()
сбрасываются.
Синтаксис: |
js_context_reuse |
---|---|
Умолчание: |
js_context_reuse 128; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.8.6.
Задаёт максимальное число контекстов JS для повторного использования движке QuickJS. Каждый контекст используется для одной stream-сессии. Завершённый контекст помещается в пул повторно используемых контекстов. Если пул заполнен, контекст уничтожается.
Синтаксис: |
js_engine |
---|---|
Умолчание: |
js_engine njs; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.8.6.
Задаёт движок JavaScript
для использования в сценариях njs.
Параметр njs
задаёт использование движка njs,
также используемого по умолчанию.
Параметр qjs
задаёт использование движка QuickJS.
Синтаксис: |
js_fetch_buffer_size |
---|---|
Умолчание: |
js_fetch_buffer_size 16k; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.4.
Задаёт размер
буфера, который будет использоваться
для чтения и записи для
Fetch API.
Синтаксис: |
js_fetch_ciphers |
---|---|
Умолчание: |
js_fetch_ciphers HIGH:!aNULL:!MD5; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.0.
Описывает разрешённые шифры для HTTPS-соединений при помощи Fetch API. Шифры задаются в формате, поддерживаемом библиотекой OpenSSL.
Полный список можно посмотреть с помощью команды
“openssl ciphers
”.
Синтаксис: |
js_fetch_max_response_buffer_size |
---|---|
Умолчание: |
js_fetch_max_response_buffer_size 1m; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.4.
Задаёт максимальный размер
ответа, полученного
при помощи Fetch API.
Синтаксис: |
js_fetch_protocols
[ |
---|---|
Умолчание: |
js_fetch_protocols TLSv1 TLSv1.1 TLSv1.2; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.0.
Разрешает указанные протоколы для HTTPS-соединений при помощи Fetch API.
Синтаксис: |
js_fetch_timeout |
---|---|
Умолчание: |
js_fetch_timeout 60s; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.4.
Задаёт таймаут при чтении и записи при помощи Fetch API. Таймаут устанавливается не на всю передачу ответа, а только между двумя операциями чтения. Если по истечении этого времени данные не передавались, соединение закрывается.
Синтаксис: |
js_fetch_trusted_certificate |
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.0.
Задаёт файл
с доверенными сертификатами CA в формате PEM,
используемыми при
проверке
HTTPS-сертификата
при помощи Fetch API.
Синтаксис: |
js_fetch_verify |
---|---|
Умолчание: |
js_fetch_verify on; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.4.
Разрешает или запрещает проверку сертификата HTTPS-сервера при помощи Fetch API.
Синтаксис: |
js_fetch_verify_depth |
---|---|
Умолчание: |
js_fetch_verify_depth 100; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.0.
Устанавливает глубину проверки в цепочке HTTPS-сертификатов при помощи Fetch API.
Синтаксис: |
js_fetch_keepalive |
---|---|
Умолчание: |
js_fetch_keepalive 0; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.9.2.
Активирует кэш для соединений с серверами назначения.
Если значение больше 0
,
включает keepalive-соединения для
Fetch API.
Параметр соединения
задаёт максимальное количество
неактивных keepalive-соединений с серверами назначения,
которые сохраняются в кэше каждого рабочего процесса.
Если это количество превышено, наименее недавно использованные соединения закрываются.
Пример:
server { listen 12345; js_fetch_keepalive 32; js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem; js_preread main.fetch_handler; }
Синтаксис: |
js_fetch_keepalive_requests |
---|---|
Умолчание: |
js_fetch_keepalive_requests 1000; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.9.2.
Задаёт максимальное количество запросов, которые могут быть обслужены через одно keepalive-соединение при помощи Fetch API. После выполнения максимального количества запросов соединение закрывается.
Периодическое закрытие соединений необходимо для освобождения выделенной под соединение памяти. Поэтому использование слишком большого максимального количества запросов может привести к чрезмерному потреблению памяти и не рекомендуется.
Синтаксис: |
js_fetch_keepalive_time |
---|---|
Умолчание: |
js_fetch_keepalive_time 1h; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.9.2.
Ограничивает максимальное время, в течение которого запросы могут обрабатываться через одно keepalive-соединение при помощи Fetch API. По истечении этого времени соединение закрывается после обработки очередного запроса.
Синтаксис: |
js_fetch_keepalive_timeout |
---|---|
Умолчание: |
js_fetch_keepalive_timeout 60s; |
Контекст: |
stream , server |
Эта директива появилась в версии 0.9.2.
Задаёт таймаут, в течение которого неактивное keepalive-соединение с сервером назначения остается открытым при помощи Fetch API.
Синтаксис: |
js_filter |
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Задаёт фильтр данных. Начиная с 0.4.0 можно ссылаться на функцию модуля. Функция фильтра вызывается однократно при первом достижении сессией content-фазы.
Функция фильтра вызывается со следующими аргументами:
s
- объект stream-сессии
В этой фазе может происходить инициализация,
также при помощи метода
s.on()
может регистрироваться вызов
для каждого входящего блока данных.
Для отмены регистрации вызова и отмены фильтра
можно использовать метод
s.off()
.
Так как обработчикjs_filter
должен сразу возвращать результат, то поддерживаются только синхронные операции. Таким образом, асинхронные операции, напримерngx.fetch()
илиsetTimeout()
, не поддерживаются.
Синтаксис: |
js_import |
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Эта директива появилась в версии 0.4.0.
Импортирует модуль, позволяющий задавать обработчики location и переменных
на njs.
Имя_экспорта
является пространством имён
при доступе к функциям модуля.
Если имя_экспорта
не задано,
то пространством имён будет являться имя модуля.
js_import stream.js;
В примере при доступе к экспорту в качестве
пространства имён используется имя модуля stream
.
Если импортируемый модуль экспортирует foo()
,
то для доступа используется stream.foo
.
Директив js_import
может быть несколько.
Директива может быть указана
на уровне server
начиная с 0.7.7.
Синтаксис: |
js_include |
---|---|
Умолчание: | — |
Контекст: |
stream |
Задаёт файл, который позволяет задавать обработчики server и переменных на njs:
nginx.conf: js_include stream.js; js_set $js_addr address; server { listen 127.0.0.1:12345; return $js_addr; } stream.js: function address(s) { return s.remoteAddress; }
Директива устарела в версии 0.4.0 и была удалена в версии 0.7.1. Вместо неё следует использовать директиву js_import.
Синтаксис: |
js_preload_object |
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Эта директива появилась в версии 0.7.8.
Предварительно загружает
неизменяемый объект
во время конфигурации.
Имя
используется в качестве имени глобальной переменной,
через которую объект доступен в коде njs.
Если имя
не указано,
то будет использоваться имя файла.
js_preload_object map.json;
В примере map
используется в качестве имени
во время доступа к предварительно загруженному объекту.
Директив js_preload_object
может быть несколько.
Синтаксис: |
js_preread |
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Задаёт функцию njs, которая будет вызываться в preread-фазе. Начиная с 0.4.0 можно ссылаться на функцию модуля.
Функция вызывается однократно при первом достижении сессией preread-фазы. Функция вызывается со следующими аргументами:
s
- объект stream-сессии
В этой фазе может происходить инициализация,
также при помощи метода
s.on()
может регистрироваться вызов
для каждого входящего блока данных пока не будет вызван один из методов:
s.done()
s.decline()
,
s.allow()
.
При вызове любого из этих методов обработка сессии
переходит на следующую фазу
и все текущие вызовы
s.on()
сбрасываются.
Так как обработчикjs_preread
должен сразу возвращать результат, то поддерживаются только синхронные операции. Таким образом, асинхронные операции, напримерngx.fetch()
илиsetTimeout()
, не поддерживаются. Тем не менее асинхронные операции поддерживаются в вызовахs.on()
в preread-фазе. Подробнее см. пример.
Синтаксис: |
js_path
|
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Эта директива появилась в версии 0.3.0.
Задаёт дополнительный путь для модулей njs.
Директива может быть указана
на уровне server
начиная с 0.7.7.
Синтаксис: |
js_periodic |
---|---|
Умолчание: | — |
Контекст: |
server |
Эта директива появилась в версии 0.8.1.
Задаёт периодичность запуска обработчика содержимого. В качестве первого аргумента обработчик получает объект сессии, также у обработчика есть доступ к глобальным объектам таким как ngx.
Необязательный параметр interval
задаёт интервал между двумя последовательными запусками,
по умолчанию 5 секунд.
Необязательный параметр jitter
задаёт время, в пределах которого
случайным образом задерживается каждый запуск,
по умолчанию задержки нет.
По умолчанию js_handler
выполняется для рабочего процесса 0.
Необязательный параметр worker_affinity
позволяет указать рабочий процесс,
для которого будет выполняться обработчик содержимого location.
Рабочие процессы задаются битовой маской разрешённых к использованию рабочих
процессов.
Маска all
позволяет обработчику выполняться
для всех рабочих процессов.
Пример:
example.conf: location @periodics { # интервал выполнения 1 минута для рабочего процесса 0 js_periodic main.handler interval=60s; # интервал выполнения 1 минута для всех рабочих процессов js_periodic main.handler interval=60s worker_affinity=all; # интервал выполнения 1 минута для рабочих процессов 1 и 3 js_periodic main.handler interval=60s worker_affinity=0101; resolver 10.0.0.1; js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem; } example.js: async function handler(s) { let reply = await ngx.fetch('https://nginx.org/en/docs/njs/'); let body = await reply.text(); ngx.log(ngx.INFO, body); }
Синтаксис: |
js_set
|
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Задаёт функцию
njs
для указанной переменной
.
Начиная с 0.4.0
можно ссылаться на функцию модуля.
Функция вызывается в момент первого обращения к переменной для данного запроса. Точный момент вызова функции зависит от фазы, в которой происходит обращение к переменной. Это можно использовать для реализации дополнительной логики, не относящейся к вычислению переменной. Например, если переменная указана в директиве log_format, то её обработчик не будет выполняться до фазы записи в лог. Этот обработчик также может использоваться для выполнения процедур непосредственно перед освобождением запроса.
Начиная с 0.8.6,
если указан необязательный параметр nocache
, то
обработчик выполняется каждый раз при обращении к переменной.
Из-за ограничения модуля rewrite
при обращении к nocache
-переменной при помощи
директивы set,
обработчик должен возвращать значение фиксированной длины.
Так как обработчикjs_set
должен сразу возвращать результат, то поддерживаются только синхронные операции. Таким образом, асинхронные операции, напримерngx.fetch()
илиsetTimeout()
, не поддерживаются.
Директива может быть указана
на уровне server
начиная с 0.7.7.
Синтаксис: |
js_shared_dict_zone
|
---|---|
Умолчание: | — |
Контекст: |
stream |
Эта директива появилась в версии 0.8.0.
Задаёт имя
и размер
зоны разделяемой памяти,
в которой хранится
словарь ключей и значений,
разделяемый между рабочими процессами.
По умолчанию в качестве ключа и значения используется строка.
Необязательный параметр type
позволяет изменить тип значения на число.
Необязательный параметр timeout
задаёт время в миллисекундах,
по завершении которого все записи в словаре удаляются из зоны.
Если для части записей требуется другое время удаления,
его можно задать при помощи аргумента timeout
методов
add,
incr и
set
(0.8.5).
Необязательный параметр evict
удаляет самую старую
пару ключ-значение при переполнении зоны.
Пример:
example.conf: # Создаётся словарь размером 1Мб со строковыми значениями, # пары ключ-значение удаляются при отсутствии активности в течение 60 секунд: js_shared_dict_zone zone=foo:1M timeout=60s; # Создаётся словарь размером 512Кб со строковыми значениями, # удаляется самая старая пара ключ-значение при переполнении зоны: js_shared_dict_zone zone=bar:512K timeout=30s evict; # Создаётся постоянный словарь размером 32Кб с числовыми значениями: js_shared_dict_zone zone=num:32k type=number; example.js: function get(r) { r.return(200, ngx.shared.foo.get(r.args.key)); } function set(r) { r.return(200, ngx.shared.foo.set(r.args.key, r.args.value)); } function del(r) { r.return(200, ngx.shared.bar.delete(r.args.key)); } function increment(r) { r.return(200, ngx.shared.num.incr(r.args.key, 2)); }
Синтаксис: |
js_var |
---|---|
Умолчание: | — |
Контекст: |
stream , server |
Эта директива появилась в версии 0.5.3.
Объявляет перезаписываемую переменную. В качестве значения можно использовать текст, переменные и их комбинации.
Директива может быть указана
на уровне server
начиная с 0.7.7.
Свойства объекта сессии
Каждый stream-обработчик njs получает один аргумент, объект stream-сессии.