=encoding utf-8

=head1 NAME

ngx_stream_js_module - Module ngx_stream_js_module




=head1



The C<ngx_stream_js_module> module is used to implement
handlers in L<njs|index> —
a subset of the JavaScript language.





Download and install instructions are available
L<here|install>.




=head1 Example Configuration



The example works since
L<0.4.0|changes>.

    
    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;
            }
        }
    }







The F<stream.js> file:

    
    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};






=head1 Directives

=head2 js_access


B<syntax:> js_access I<I<C<function>> E<verbar> I<C<module.function>>>



B<context:> I<stream>


B<context:> I<server>





Sets an njs function which will be called at the
L<access|stream_processing> phase.
Since L<0.4.0|changes>,
a module function can be referenced.







=head2 js_filter


B<syntax:> js_filter I<I<C<function>> E<verbar> I<C<module.function>>>



B<context:> I<stream>


B<context:> I<server>





Sets a data filter.
Since L<0.4.0|changes>,
a module function can be referenced.







=head2 js_import


B<syntax:> js_import I<I<C<module.js>> E<verbar>
I<C<export_name from module.js>>>



B<context:> I<stream>



This directive appeared in version 0.4.0.





Imports a module that implements location and variable handlers in njs.
The C<export_name> is used as a namespace
to access module functions.
If the C<export_name> is not specified,
the module name will be used as a namespace.

    
    js_import stream.js;


Here, the module name C<stream> is used as a namespace
while accessing exports.
If the imported module exports C<foo()>,
C<stream.foo> is used to refer to it.





Several C<js_import> directives can be specified.







=head2 js_include


B<syntax:> js_include I<I<C<file>>>



B<context:> I<stream>





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







The directive is deprecated since
L<0.4.0|changes>,
the L</js_import> directive should be used instead.







=head2 js_path


B<syntax:> js_path I<
I<C<path>>>



B<context:> I<stream>



This directive appeared in version 0.3.0.





Sets an additional path for njs modules.







=head2 js_preread


B<syntax:> js_preread I<I<C<function>> E<verbar> I<C<module.function>>>



B<context:> I<stream>


B<context:> I<server>





Sets an njs function which will be called at the
L<preread|stream_processing> phase.
Since L<0.4.0|changes>,
a module function can be referenced.







=head2 js_set


B<syntax:> js_set I<
I<C<$variable>> I<C<function>> E<verbar>
I<C<module.function>>>



B<context:> I<stream>





Sets an njs C<function>
for the specified C<variable>.
Since L<0.4.0|changes>,
a module function can be referenced.





The function is called when
the variable is referenced for the first time for a given request.
The exact moment depends on a
L<phase|stream_processing>
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
L<ngx_stream_log_module> 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.






B<NOTE>

As the C<js_set> handler
returns its result immediately, it supports
only synchronous callbacks.
Thus, asynchronous callbacks such as
L<ngx.fetch()|reference>
or
L<setTimeout()|reference>
are not supported.








=head2 js_var


B<syntax:> js_var I<I<C<$variable>> [I<C<value>>]>



B<context:> I<stream>



This directive appeared in version 0.5.3.





Declares
a L<writable|reference>
variable.
The value can contain text, variables, and their combination.







=head1 Session Object Properties



Each stream njs handler receives one argument, a stream session
L<object|reference>.




