view xml/en/docs/http/ngx_http_js_module.xml @ 2846:fdf1464e1977

Moved banner to the external file to make partial rollout possible. An idea is to have several banners and show them with different probability specified by split directive in the nginx.conf
author Sergey Budnevitch <sb@waeme.net>
date Tue, 10 May 2022 18:07:27 +0400
parents a3aee2697d4e
children 986e1f930e3b
line wrap: on
line source

<?xml version="1.0"?>

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

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

<module name="Module ngx_http_js_module"
        link="/en/docs/http/ngx_http_js_module.html"
        lang="en"
        rev="35">

<section id="summary">

<para>
The <literal>ngx_http_js_module</literal> module is used to implement
location and variable 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>
http {
    js_import http.js;

    js_set $foo     http.foo;
    js_set $summary http.summary;
    js_set $hash    http.hash;

    resolver 10.0.0.1;

    server {
        listen 8000;

        location / {
            add_header X-Foo $foo;
            js_content http.baz;
        }

        location = /summary {
            return 200 $summary;
        }

        location = /hello {
            js_content http.hello;
        }

        # since 0.7.0
        location = /fetch {
            js_content                   http.fetch;
            js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
        }

        # since 0.7.0
        location = /crypto {
            add_header Hash $hash;
            return     200;
        }
    }
}
</example>
</para>

<para>
The <path>http.js</path> file:
<example>
function foo(r) {
    r.log("hello from foo() handler");
    return "foo";
}

function summary(r) {
    var a, s, h;

    s = "JS summary\n\n";

    s += "Method: " + r.method + "\n";
    s += "HTTP version: " + r.httpVersion + "\n";
    s += "Host: " + r.headersIn.host + "\n";
    s += "Remote Address: " + r.remoteAddress + "\n";
    s += "URI: " + r.uri + "\n";

    s += "Headers:\n";
    for (h in r.headersIn) {
        s += "  header '" + h + "' is '" + r.headersIn[h] + "'\n";
    }

    s += "Args:\n";
    for (a in r.args) {
        s += "  arg '" + a + "' is '" + r.args[a] + "'\n";
    }

    return s;
}

function baz(r) {
    r.status = 200;
    r.headersOut.foo = 1234;
    r.headersOut['Content-Type'] = "text/plain; charset=utf-8";
    r.headersOut['Content-Length'] = 15;
    r.sendHeader();
    r.send("nginx");
    r.send("java");
    r.send("script");

    r.finish();
}

function hello(r) {
    r.return(200, "Hello world!");
}

// since 0.7.0
async function fetch(r) {
    let results = await Promise.all([ngx.fetch('https://nginx.org/'),
                                     ngx.fetch('https://nginx.org/en/')]);

    r.return(200, JSON.stringify(results, undefined, 4));
}

// since 0.7.0
async function hash(r) {
    let hash = await crypto.subtle.digest('SHA-512', r.headersIn.host);
    r.setReturnValue(Buffer.from(hash).toString('hex'));
}

export default {foo, summary, baz, hello, fetch, hash};
</example>
</para>

</section>


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

<directive name="js_body_filter">
<syntax><value>function</value> | <value>module.function</value>
[<value>buffer_type</value>=<value>string</value> | <value>buffer</value>]</syntax>
<default/>
<context>location</context>
<context>limit_except</context>
<appeared-in>0.5.2</appeared-in>

<para>
Sets an njs function as a response body filter.
The filter function is called for each data chunk of a response body
with the following arguments:

<list type="tag">
<tag-name><literal>r</literal></tag-name>
<tag-desc>
the <link doc="../njs/reference.xml" id="http">HTTP request</link> object
</tag-desc>

<tag-name><literal>data</literal></tag-name>
<tag-desc>
the incoming data chunk,
may be a string or Buffer
depending on the <literal>buffer_type</literal> value,
by default is a string.
</tag-desc>

<tag-name><literal>flags</literal></tag-name>
<tag-desc>
an object with the following properties:
<list type="tag">
<tag-name><literal>last</literal></tag-name>
<tag-desc>
a boolean value, true if data is a last buffer.
</tag-desc>

</list>
</tag-desc>

</list>
</para>

<para>
The filter function can pass its own modified version
of the input data chunk to the next body filter by calling
<link doc="../njs/reference.xml" id="r_sendbuffer"><literal>r.sendBuffer()</literal></link>.
For example, to transform all the lowercase letters in the response body:
<example>
function filter(r, data, flags) {
    r.sendBuffer(data.toLowerCase(), flags);
}
</example>
To stop filtering (following data chunks will be passed to client
without calling <literal>js_body_filter</literal>),
<link doc="../njs/reference.xml" id="r_done"><literal>r.done()</literal></link>
can be used.
</para>

<para>
If the filter function changes the length of the response body, then
it is required to clear out the <header>Content-Length</header> response header
(if any) in
<link id="js_header_filter"><literal>js_header_filter</literal></link>
to enforce chunked transfer encoding.
</para>

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

</directive>


<directive name="js_content">
<syntax><value>function</value> | <value>module.function</value></syntax>
<default/>
<context>location</context>
<context>limit_except</context>

<para>
Sets an njs function as a location content handler.
Since <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>,
a module function can be referenced.
</para>

</directive>


<directive name="js_fetch_buffer_size">
<syntax><value>size</value></syntax>
<default>16k</default>
<context>http</context>
<context>server</context>
<context>location</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>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.0</appeared-in>

<para>
Specifies the enabled ciphers for HTTPS requests
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>http</context>
<context>server</context>
<context>location</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>http</context>
<context>server</context>
<context>location</context>
<appeared-in>0.7.0</appeared-in>

<para>
Enables the specified protocols for HTTPS requests
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>http</context>
<context>server</context>
<context>location</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>http</context>
<context>server</context>
<context>location</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>http</context>
<context>server</context>
<context>location</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>http</context>
<context>server</context>
<context>location</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_header_filter">
<syntax><value>function</value> | <value>module.function</value></syntax>
<default/>
<context>location</context>
<context>limit_except</context>
<appeared-in>0.5.1</appeared-in>

<para>
Sets an njs function as a response header filter.
The directive allows changing arbitrary header fields of a response header.
</para>

<para>
<note>
As the <literal>js_header_filter</literal> handler
returns its result immediately, it supports
only synchronous operations.
Thus, asynchronous operations such as
<link doc="../njs/reference.xml" id="r_subrequest">r.subrequest()</link>
or
<link doc="../njs/reference.xml" id="settimeout">setTimeout()</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>http</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 http.js;
</example>
Here, the module name <literal>http</literal> is used as a namespace
while accessing exports.
If the imported module exports <literal>foo()</literal>,
<literal>http.foo</literal> is used to refer to it.
</para>

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

</directive>


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

<para>
Specifies a file that implements location and variable handlers in njs:
<example>
nginx.conf:
js_include http.js;
location   /version {
    js_content version;
}

http.js:
function version(r) {
    r.return(200, njs.version);
}
</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>http</context>
<appeared-in>0.3.0</appeared-in>

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

</directive>


<directive name="js_set">
<syntax>
<value>$variable</value> <value>function</value> |
<value>module.function</value></syntax>
<default/>
<context>http</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="../dev/development_guide.xml" id="http_phases">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_http_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 operations.
Thus, asynchronous operations such as
<link doc="../njs/reference.xml" id="r_subrequest">r.subrequest()</link>
or
<link doc="../njs/reference.xml" id="settimeout">setTimeout()</link>
are not supported.
</note>
</para>

</directive>


<directive name="js_var">
<syntax><value>$variable</value> [<value>value</value>]</syntax>
<default/>
<context>http</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.
The variable is not overwritten after a redirect
unlike variables created with the
<link doc="ngx_http_rewrite_module.xml" id="set"/> directive.
</para>

</directive>

</section>


<section id="arguments" name="Request Argument">

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

</section>

</module>