Модуль ngx_stream_js_module

Пример конфигурации
Директивы
     js_access
     js_fetch_ciphers
     js_fetch_protocols
     js_fetch_trusted_certificate
     js_fetch_verify_depth
     js_filter
     js_import
     js_include
     js_preread
     js_path
     js_set
     js_var
Свойства объекта сессии

Модуль 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 можно ссылаться на функцию модуля.

Синтаксис: js_fetch_ciphers шифры;
Умолчание:
js_fetch_ciphers HIGH:!aNULL:!MD5;
Контекст: http, server, location

Эта директива появилась в версии 0.7.0.

Описывает разрешённые шифры для HTTPS-соединений при помощи Fetch API. Шифры задаются в формате, поддерживаемом библиотекой OpenSSL.

Полный список можно посмотреть с помощью команды “openssl ciphers”.

Синтаксис: js_fetch_protocols [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
Умолчание:
js_fetch_protocols TLSv1 TLSv1.1 TLSv1.2;
Контекст: http, server, location

Эта директива появилась в версии 0.7.0.

Разрешает указанные протоколы для HTTPS-соединений при помощи Fetch API.

Синтаксис: js_fetch_trusted_certificate файл;
Умолчание:
Контекст: http, server, location

Эта директива появилась в версии 0.7.0.

Задаёт файл с доверенными сертификатами CA в формате PEM, используемыми при проверке HTTPS-сертификата при помощи Fetch API.

Синтаксис: js_fetch_verify_depth число;
Умолчание:
js_fetch_verify_depth 100;
Контекст: http, server, location

Эта директива появилась в версии 0.7.0.

Устанавливает глубину проверки в цепочке HTTPS-сертификатов при помощи Fetch API.

Синтаксис: js_filter функция | модуль.функция;
Умолчание:
Контекст: stream, server

Задаёт фильтр данных. Начиная с 0.4.0 можно ссылаться на функцию модуля.

Синтаксис: js_import модуль.js | имя_экспорта из модуль.js;
Умолчание:
Контекст: stream

Эта директива появилась в версии 0.4.0.

Импортирует модуль, позволяющий задавать обработчики location и переменных на njs. Имя_экспорта является пространством имён при доступе к функциям модуля. Если имя_экспорта не задано, то пространством имён будет являться имя модуля.

js_import stream.js;

В примере при доступе к экспорту в качестве пространства имён используется имя модуля stream. Если импортируемый модуль экспортирует foo(), то для доступа используется stream.foo.

Директив js_import может быть несколько.

Синтаксис: 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, вместо неё следует использовать директиву js_import.

Синтаксис: js_preread функция | модуль.функция;
Умолчание:
Контекст: stream, server

Задаёт функцию njs, которая будет вызываться в preread-фазе. Начиная с 0.4.0 можно ссылаться на функцию модуля.

Синтаксис: js_path путь;
Умолчание:
Контекст: stream

Эта директива появилась в версии 0.3.0.

Задаёт дополнительный путь для модулей njs.

Синтаксис: js_set $переменная функция | модуль.функция;
Умолчание:
Контекст: stream

Задаёт функцию njs для указанной переменной. Начиная с 0.4.0 можно ссылаться на функцию модуля.

Функция вызывается в момент первого обращения к переменной для данного запроса. Точный момент вызова функции зависит от фазы, в которой происходит обращение к переменной. Это можно использовать для реализации дополнительной логики, не относящейся к вычислению переменной. Например, если переменная указана в директиве log_format, то её обработчик не будет выполняться до фазы записи в лог. Этот обработчик также может использоваться для выполнения процедур непосредственно перед освобождением запроса.

Так как обработчик js_set должен сразу возвращать результат, то поддерживаются только синхронные вызовы. Таким образом, асинхронные вызовы, например ngx.fetch() или setTimeout(), не поддерживаются.

Синтаксис: js_var $переменная [значение];
Умолчание:
Контекст: stream

Эта директива появилась в версии 0.5.3.

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

Свойства объекта сессии

Каждый stream-обработчик njs получает один аргумент, объект stream-сессии.