JS#
Позволяет задавать обработчики на njs — подмножестве языка JavaScript.
В наших репозиториях модуль собран динамически и доступен отдельным пакетом angie-module-njs; подключить его можно с помощью директивы load_module.
Пример конфигурации#
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#
Задает функцию njs, которая будет вызываться в access-фазе. Можно ссылаться на функцию модуля.
Функция вызывается однократно при первом достижении сессией access-фазе. Функция вызывается со следующими аргументами:
|
объект stream-сессии |
В этой фазе может происходить инициализация, также при помощи метода s.on() может регистрироваться вызов для каждого входящего блока данных пока не будет вызван один из методов: s.done(), s.decline(), s.allow(). При вызове любого из этих методов обработка сессии переходит на следующую фазу и все текущие вызовы s.on() сбрасываются.
js_fetch_buffer_size#
|
|
По умолчанию |
|
stream, server |
Задает размер буфера, который будет использоваться для чтения и записи для Fetch API.
js_fetch_ciphers#
|
|
По умолчанию |
|
stream, server |
Описывает разрешенные шифры для HTTPS-соединений при помощи Fetch API. Шифры задаются в формате, поддерживаемом библиотекой OpenSSL.
Полный список можно посмотреть с помощью команды "openssl ciphers".
js_fetch_max_response_buffer_size#
|
|
По умолчанию |
|
stream, server |
Задает максимальный размер ответа, полученного при помощи Fetch API.
js_fetch_protocols#
|
|
По умолчанию |
|
stream, server |
Разрешает указанные протоколы для HTTPS-соединений при помощи Fetch API.
js_fetch_timeout#
Задает таймаут при чтении и записи при помощи Fetch API. Таймаут устанавливается не на всю передачу ответа, а только между двумя операциями чтения. Если по истечении этого времени данные не передавались, соединение закрывается.
js_fetch_trusted_certificate#
Задает файл с доверенными сертификатами CA в формате PEM, используемыми при проверке HTTPS-сертификата при помощи Fetch API.
js_fetch_verify#
Разрешает или запрещает проверку сертификата HTTPS-сервера при помощи Fetch API.
js_fetch_verify_depth#
|
|
По умолчанию |
|
stream, server |
Устанавливает глубину проверки в цепочке HTTPS-сертификатов при помощи Fetch API.
js_filter#
Задает фильтр данных. Можно ссылаться на функцию модуля.
Функция фильтра вызывается однократно при первом достижении сессией content-фазы. Функция фильтра вызывается со следующими аргументами:
|
объект stream-сессии |
В этой фазе может происходить инициализация, также при помощи метода s.on() может регистрироваться вызов для каждого входящего блока данных. Для отмены регистрации вызова и отмены фильтра можно использовать метод s.off().
Примечание
Так как обработчик js_filter должен сразу возвращать результат, то поддерживаются только синхронные операции. Таким образом, асинхронные операции, например ngx.fetch() или setTimeout(), не поддерживаются.
js_import#
Импортирует модуль, позволяющий задавать обработчики location и переменных на njs. Имя_экспорта является пространством имен при доступе к функциям модуля. Если имя_экспорта не задано, то пространством имен будет являться имя модуля.
js_import stream.js;
В примере при доступе к экспорту в качестве пространства имен используется имя модуля stream. Если импортируемый модуль экспортирует foo(), то для доступа используется stream.foo.
Директив js_import может быть несколько.
js_path#
Задает дополнительный путь для модулей njs.
js_preload_object#
Предварительно загружает неизменяемый объект во время конфигурации. Имя используется в качестве имени глобальной переменной, через которую объект доступен в коде njs. Если имя не указано, то будет использоваться имя файла.
js_preload_object map.json;
В примере map используется в качестве имени во время доступа к предварительно загруженному объекту.
Директив js_preload_object может быть несколько.
js_preread#
Задает функцию njs, которая будет вызываться в preread-фазе. Можно ссылаться на функцию модуля.
Функция вызывается однократно при первом достижении сессией preread-фазы. Функция вызывается со следующими аргументами:
|
объект stream-сессии |
В этой фазе может происходить инициализация, также при помощи метода s.on() может регистрироваться вызов для каждого входящего блока данных пока не будет вызван один из методов: s.done(), s.decline(), s.allow(). При вызове любого из этих методов обработка сессии переходит на следующую фазу и все текущие вызовы s.on() сбрасываются.
Примечание
Так как обработчик js_preread должен сразу возвращать результат, то поддерживаются только синхронные операции. Таким образом, асинхронные операции, например ngx.fetch() или setTimeout(), не поддерживаются. Тем не менее асинхронные операции поддерживаются в вызовах s.on() в preread-фазе.
js_set#
Задает функцию njs для указанной переменной. Можно ссылаться на функцию модуля.
Функция вызывается в момент первого обращения к переменной для данного запроса. Точный момент вызова функции зависит от фазы, в которой происходит обращение к переменной. Это можно использовать для реализации дополнительной логики, не относящейся к вычислению переменной. Например, если переменная указана в директиве log_format, то ее обработчик не будет выполняться до фазы записи в лог. Этот обработчик также может использоваться для выполнения процедур непосредственно перед освобождением запроса.
Примечание
Так как обработчик js_set должен сразу возвращать результат, то поддерживаются только синхронные операции. Таким образом, асинхронные операции, например ngx.fetch() или setTimeout(), не поддерживаются.
js_var#
Объявляет перезаписываемую переменную. В качестве значения можно использовать текст, переменные и их комбинации.
Свойства объекта сессии#
Каждый stream-обработчик njs получает один аргумент, объект stream-сессии.