view xml/en/docs/stream/ngx_stream_js_module.xml @ 2882:986e1f930e3b

Documented server, location, if contexts for some js directives.
author Yaroslav Zhuravlev <yar@nginx.com>
date Thu, 18 Aug 2022 15:44:39 +0100
parents fd8ec06ceafa
children 9719a0184a67
line wrap: on
line source

<?xml version="1.0"?>

<!--
  Copyright (C) Nginx, Inc.
  -->

<!DOCTYPE module SYSTEM "../../../../dtd/module.dtd">

<module name="Module ngx_stream_js_module"
        link="/en/docs/stream/ngx_stream_js_module.html"
        lang="en"
        rev="33">

<section id="summary">

<para>
The <literal>ngx_stream_js_module</literal> module is used to implement
handlers in <link doc="../njs/index.xml">njs</link> —
a subset of the JavaScript language.
</para>

<para>
Download and install instructions are available
<link doc="../njs/install.xml">here</link>.
</para>

</section>


<section id="example" name="Example Configuration">

<para>
The example works since
<link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>.
<example>
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;
        }
    }
}
</example>
</para>

<para>
The <path>stream.js</path> file:
<example>
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;
}

// Read HTTP request line.
// Collect bytes in 'req' until
// request line is read.
// Injects HTTP header into a client's request

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};
</example>
</para>

</section>


<section id="directives" name="Directives">

<directive name="js_access">
<syntax><value>function</value> | <value>module.function</value></syntax>
<default/>
<context>stream</context>
<context>server</context>

<para>
Sets an njs function which will be called at the
<link doc="stream_processing.xml" id="access_phase">access</link> phase.
Since <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>,
a module function can be referenced.
</para>

<para>
The function is called once at the moment when the stream session reaches
the <link doc="stream_processing.xml" id="access_phase">access</link> phase
for the first time.
The function is called with the following arguments:

<list type="tag">
<tag-name><literal>s</literal></tag-name>
<tag-desc>
the <link doc="../njs/reference.xml" id="stream">Stream Session</link> object
</tag-desc>

</list>
</para>

<para>
At this phase, it is possible to perform initialization
or register a callback with
the <link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>
method
for each incoming data chunk until one of the following methods are called:
<link doc="../njs/reference.xml" id="s_allow"><literal>s.allow()</literal></link>,
<link doc="../njs/reference.xml" id="s_decline"><literal>s.decline()</literal></link>,
<link doc="../njs/reference.xml" id="s_done"><literal>s.done()</literal></link>.
As soon as one of these methods is called, the stream session processing
switches to the <link doc="stream_processing.xml">next phase</link>
and all current
<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>
callbacks are dropped.
</para>

<para>
<note>
As the <literal>js_access</literal> handler
returns its result immediately, it supports
only synchronous callbacks.
Thus, asynchronous callbacks such as
<link doc="../njs/reference.xml" id="ngx_fetch"><literal>ngx.fetch()</literal></link>
or
<link doc="../njs/reference.xml" id="settimeout"><literal>setTimeout()</literal></link>
are not supported.
</note>
</para>

</directive>


<directive name="js_fetch_buffer_size">
<syntax><value>size</value></syntax>
<default>16k</default>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.4</appeared-in>

<para>
Sets the <value>size</value> of the buffer used for reading and writing
with <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>

</directive>


<directive name="js_fetch_ciphers">
<syntax><value>ciphers</value></syntax>
<default>HIGH:!aNULL:!MD5</default>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.0</appeared-in>

<para>
Specifies the enabled ciphers for HTTPS connections
with <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
The ciphers are specified in the format understood by the OpenSSL library.
</para>

<para>
The full list can be viewed using the
“<command>openssl ciphers</command>” command.
</para>

</directive>


<directive name="js_fetch_max_response_buffer_size">
<syntax><value>size</value></syntax>
<default>1m</default>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.4</appeared-in>

<para>
Sets the maximum <value>size</value> of the response received
with <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>

</directive>


<directive name="js_fetch_protocols">
<syntax>
    [<literal>TLSv1</literal>]
    [<literal>TLSv1.1</literal>]
    [<literal>TLSv1.2</literal>]
    [<literal>TLSv1.3</literal>]</syntax>
<default>TLSv1 TLSv1.1 TLSv1.2</default>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.0</appeared-in>

<para>
Enables the specified protocols for HTTPS connections
with <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>

</directive>


<directive name="js_fetch_timeout">
<syntax><value>time</value></syntax>
<default>60s</default>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.4</appeared-in>

<para>
Defines a timeout for reading and writing
for <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
The timeout is set only between two successive read/write operations,
not for the whole response.
If no data is transmitted within this time, the connection is closed.
</para>

</directive>


<directive name="js_fetch_trusted_certificate">
<syntax><value>file</value></syntax>
<default/>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.0</appeared-in>

<para>
Specifies a <value>file</value> with trusted CA certificates in the PEM format
used to
<link doc="../njs/reference.xml" id="fetch_verify">verify</link>
the HTTPS certificate
with <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>

</directive>


<directive name="js_fetch_verify">
<syntax><literal>on</literal> | <literal>off</literal></syntax>
<default>on</default>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.4</appeared-in>

<para>
Enables or disables verification of the HTTPS server certificate
with <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>

</directive>


<directive name="js_fetch_verify_depth">
<syntax><value>number</value></syntax>
<default>100</default>
<context>stream</context>
<context>server</context>
<appeared-in>0.7.0</appeared-in>

<para>
Sets the verification depth in the HTTPS server certificates chain
with <link doc="../njs/reference.xml" id="ngx_fetch">Fetch API</link>.
</para>

</directive>


<directive name="js_filter">
<syntax><value>function</value> | <value>module.function</value></syntax>
<default/>
<context>stream</context>
<context>server</context>

<para>
Sets a data filter.
Since <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>,
a module function can be referenced.
The filter function is called once at the moment when the stream session reaches
the <link doc="stream_processing.xml" id="content_phase">content</link> phase.
</para>

<para>
The filter function is called with the following arguments:
<list type="tag">
<tag-name><literal>s</literal></tag-name>
<tag-desc>
the <link doc="../njs/reference.xml" id="stream">Stream Session</link> object
</tag-desc>

</list>
</para>

<para>
At this phase, it is possible to perform initialization
or register a callback with
the <link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>
method for each incoming data chunk.
The
<link doc="../njs/reference.xml" id="s_off"><literal>s.off()</literal></link>
method may be used to unregister a callback and stop filtering.
</para>

<para>
<note>
As the <literal>js_filter</literal> handler
returns its result immediately, it supports
only synchronous operations.
Thus, asynchronous operations such as
<link doc="../njs/reference.xml" id="ngx_fetch"><literal>ngx.fetch()</literal></link>
or
<link doc="../njs/reference.xml" id="settimeout"><literal>setTimeout()</literal></link>
are not supported.
</note>
</para>

</directive>


<directive name="js_import">
<syntax><value>module.js</value> |
<value>export_name from module.js</value></syntax>
<default/>
<context>stream</context>
<context>server</context>
<appeared-in>0.4.0</appeared-in>

<para>
Imports a module that implements location and variable handlers in njs.
The <literal>export_name</literal> is used as a namespace
to access module functions.
If the <literal>export_name</literal> is not specified,
the module name will be used as a namespace.
<example>
js_import stream.js;
</example>
Here, the module name <literal>stream</literal> is used as a namespace
while accessing exports.
If the imported module exports <literal>foo()</literal>,
<literal>stream.foo</literal> is used to refer to it.
</para>

<para>
Several <literal>js_import</literal> directives can be specified.
</para>

<para>
<note>
The directive can be specified on the
<literal>server</literal> level
since <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>

</directive>


<directive name="js_include">
<syntax><value>file</value></syntax>
<default/>
<context>stream</context>

<para>
Specifies a file that implements server and variable handlers in njs:
<example>
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;
}
</example>
</para>

<para>
The directive was made obsolete in version
<link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>
and was removed in version
<link doc="../njs/changes.xml" id="njs0.7.1">0.7.1</link>.
The <link id="js_import"/> directive should be used instead.
</para>

</directive>


<directive name="js_path">
<syntax>
<value>path</value></syntax>
<default/>
<context>stream</context>
<context>server</context>
<appeared-in>0.3.0</appeared-in>

<para>
Sets an additional path for njs modules.
</para>

<para>
<note>
The directive can be specified on the
<literal>server</literal> level
since <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>

</directive>


<directive name="js_preread">
<syntax><value>function</value> | <value>module.function</value></syntax>
<default/>
<context>stream</context>
<context>server</context>

<para>
Sets an njs function which will be called at the
<link doc="stream_processing.xml" id="preread_phase">preread</link> phase.
Since <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>,
a module function can be referenced.
</para>

<para>
The function is called once
at the moment when the stream session reaches the
<link doc="stream_processing.xml" id="preread_phase">preread</link> phase
for the first time.
The function is called with the following arguments:

<list type="tag">
<tag-name><literal>s</literal></tag-name>
<tag-desc>
the <link doc="../njs/reference.xml" id="stream">Stream Session</link> object
</tag-desc>

</list>
</para>

<para>
At this phase, it is possible to perform initialization
or register a callback with
the <link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>
method
for each incoming data chunk until one of the following methods are called:
<link doc="../njs/reference.xml" id="s_allow"><literal>s.allow()</literal></link>,
<link doc="../njs/reference.xml" id="s_decline"><literal>s.decline()</literal></link>,
<link doc="../njs/reference.xml" id="s_done"><literal>s.done()</literal></link>.
When one of these methods is called,
the stream session switches to the
<link doc="stream_processing.xml">next phase</link>
and all current
<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>
callbacks are dropped.
</para>

<para>
<note>
As the <literal>js_preread</literal> handler
returns its result immediately, it supports
only synchronous callbacks.
Thus, asynchronous callbacks such as
<link doc="../njs/reference.xml" id="ngx_fetch"><literal>ngx.fetch()</literal></link>
or
<link doc="../njs/reference.xml" id="settimeout"><literal>setTimeout()</literal></link>
are not supported.
Nevertheless, asynchronous operations are supported in
<link doc="../njs/reference.xml" id="s_on"><literal>s.on()</literal></link>
callbacks in the
<link doc="stream_processing.xml" id="preread_phase">preread</link> phase.
See
<link url="https://github.com/nginx/njs-examples#authorizing-connections-using-ngx-fetch-as-auth-request-stream-auth-request">this example</link> for more information.
</note>
</para>

</directive>


<directive name="js_set">
<syntax>
<value>$variable</value> <value>function</value> |
<value>module.function</value></syntax>
<default/>
<context>stream</context>
<context>server</context>

<para>
Sets an njs <literal>function</literal>
for the specified <literal>variable</literal>.
Since <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>,
a module function can be referenced.
</para>

<para>
The function is called when
the variable is referenced for the first time for a given request.
The exact moment depends on a
<link doc="stream_processing.xml">phase</link>
at which the variable is referenced.
This can be used to perform some logic
not related to variable evaluation.
For example, if the variable is referenced only in the
<link doc="ngx_stream_log_module.xml" id="log_format"/> directive,
its handler will not be executed until the log phase.
This handler can be used to do some cleanup
right before the request is freed.
</para>

<para>
<note>
As the <literal>js_set</literal> handler
returns its result immediately, it supports
only synchronous callbacks.
Thus, asynchronous callbacks such as
<link doc="../njs/reference.xml" id="ngx_fetch">ngx.fetch()</link>
or
<link doc="../njs/reference.xml" id="settimeout">setTimeout()</link>
are not supported.
</note>
</para>

<para>
<note>
The directive can be specified on the
<literal>server</literal> level
since <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>

</directive>


<directive name="js_var">
<syntax><value>$variable</value> [<value>value</value>]</syntax>
<default/>
<context>stream</context>
<context>server</context>
<appeared-in>0.5.3</appeared-in>

<para>
Declares
a <link doc="../njs/reference.xml" id="r_variables">writable</link>
variable.
The value can contain text, variables, and their combination.
</para>

<para>
<note>
The directive can be specified on the
<literal>server</literal> level
since <link doc="../njs/changes.xml" id="njs0.7.7">0.7.7</link>.
</note>
</para>

</directive>

</section>


<section id="properties" name="Session Object Properties">

<para>
Each stream njs handler receives one argument, a stream session
<link doc="../njs/reference.xml" id="stream">object</link>.
</para>

</section>

</module>