NJS#

The module provides integration of the JavaScript programming language into Angie's event processing model and allows extending server functionality using JavaScript scripts. It consists of two modules:

  • HTTP JS — for processing HTTP traffic;

  • Stream JS — for processing TCP/UDP traffic.

Installation#

To install the module, use one of the following packages:

  • Angie: angie-module-njs or angie-module-njs-light;

  • Angie PRO: angie-pro-module-njs or angie-pro-module-njs-light.

Features#

The module extends server functionality using scripts written in njs, a subset of JavaScript, enabling implementation of custom server-side logic and much more:

  • Complex access control and security checks before the request reaches the proxied server.

  • Response header manipulation.

  • Writing flexible asynchronous handlers and content filters.

Also available is a standalone command-line utility that can be used independently of the server for developing and debugging njs scripts.

Loading the Module#

Loading modules in the main{} context:

load_module modules/ngx_http_js_module.so;    # for HTTP
load_module modules/ngx_stream_js_module.so;  # for Stream

Usage#

Detailed documentation is available in the sections for individual modules:

Security#

The module does not execute dynamic code, especially code received from the network. The only way to execute such code using njs is to configure the js_import directive in the server configuration. JavaScript code is loaded once at server startup.

In the module's threat model, JavaScript code is considered a trusted source just like the configuration file and site certificates. In practice, this means the following:

  • disclosure of memory contents and other security issues caused by modification of JavaScript code are not considered security issues, but are treated as regular bugs;

  • measures must be taken to protect the JavaScript code used by the module;

  • if there are no js_import directives in the configuration file, the server is protected from vulnerabilities related to JavaScript.

Command-Line Utility#

The njs command-line utility helps develop and debug njs scripts and is installed along with the modules. Unlike the situation when the module is running as part of Angie, Angie objects (HTTP and Stream) are not available when using the utility.

Examples of using the utility:

$ echo "2**3" | njs -q
8

$ njs

>> globalThis
global {
 njs: njs {
  version: '0.3.9'
 },
 global: [Circular],
 process: process {
  argv: [
   '/usr/bin/njs'
  ],
...

Preloaded Objects#

For each incoming request, the module creates a separate virtual machine. This provides many benefits, such as predictable memory consumption and request isolation. However, since all requests are isolated, if a request handler needs to access any data, it must read it itself. This is inefficient, especially when the data volume is large.

To solve this problem, a mechanism for preloaded shared objects was introduced. Such objects are created as immutable and have no prototype chains: their values cannot be changed, properties cannot be added or removed.

Here are a few examples of working with preloaded objects in njs:

  • Accessing properties by name:

    preloaded_object.prop_name
    preloaded_object[prop_name]
    
  • Enumerating properties:

    for (i in preloaded_object_name) {
          // ...
    }
    
  • Applying non-modifying built-in methods using call():

    Array.prototype.filter.call(preloaded_object_name, ...)
    

API Reference#

For a complete reference of all njs objects, methods, and properties, see:

Additional Information#