unit icon indicating copy to clipboard operation
unit copied to clipboard

NJS module preview.

Open hongzhidao opened this issue 3 years ago • 2 comments

Hi, we are glad that the njs module development is nearly complete. It's for extending Unit configuration. You are highly welcome to discuss.

Prerequisites

The patch can only be applied to the unit source code checked out from our mercurial repository. To build Unit from source make sure you have all tools and software installed as described on our webiste. To use mercurial simply install it using your favorite package managers like yum or apt.

apt install mercurial

Installation:

  1. njs

To build Unit with njs support, you need njs source code. If you'd like to use Mercurial,

$ hg clone https://hg.nginx.org/njs

If you prefer Git,

$ git clone https://github.com/nginx/njs

Next, point to the resulting directory using the option --with-njs when configuring Unit's source code.

  1. Download the patch
wget -O unit-njs-module.patch https://gist.githubusercontent.com/tippexs/b6d167102f0bb06adcde304970e3a757/raw/37b67016a57578d0344737a5f7eec0f1bf194732/hg-unit-njs.patch
  1. Apply to patch
cd unit
hg import ../unit-njs-module.patch
  1. Configure
./configure --openssl --with-njs=../njs/
  1. Make
make

Document

The same options that accept variables can use template literals based on the njs scripting language. The following example composes a share path using two built-in Unit variables in an njs template:

{
    "listeners": {
        "*:8080": {
            "pass": "routes"
        }
    },
    "routes": [
        {
            "action": {
                "share": "`/www/html/${vars.host + vars.uri}`"
            }
        }
    ]
}      

Unit uses the njs library to evaluate the template expression and substitute the result at runtime. As the snippet above suggests, templates can refer to built-ins, custom variables, and other request properties:

args.* Query string arguments Color=Blue is args.Color, and so on.

headers.* Request header fields Content-Encoding is headers.Content-Encoding, and so on.

vars.* Built-in and custom variables $host is vars.host, and so on.

Unit also provides a storage space for njs scripts to be used in your templates. Suppose you have a module saved as hellonjs.js:

var hellonjs = {}

hellonjs.hello = function(vars) {
    if ('unitvar' in vars) {
        return vars.unitvar;

    } else {
        return 'default';
    }
}

export default hellonjs

To use it with Unit, first upload it to the script storage at /scripts/:

# curl -X PUT --data-binary @hellonjs.js --unix-socket
   /path/to/control.unit.sock http://localhost/scripts/hellonjs

Next, add the uploaded script's name to /config/settings/auto_module for Unit to load the script:

# curl -X PUT -d '"hellonjs"' --unix-socket
   /path/to/control.unit.sock http://localhost/config/settings/auto_module

Now, the module can be used in njs templates. The following snippet creates a native Unit variable called unitvar and passes the vars object with the variable to the hello() function from the uploaded module:

{
    "match": {
        "uri": "~(?<unitvar>.*)"
    },
    "action": {
        "share": "`/www/html${hellonjs.hello(vars)}`"
    }
}

The function checks if unitvar exists and returns it; if it doesn't exist, the default value is used. Therefore, a request for a /test/ URI yields a share path of /www/html/test/.

For further reference, see the njs documentation.

hongzhidao avatar Feb 23 '22 07:02 hongzhidao

Hi @hongzhidao, i followed you instructions to install unit-njs-module.patch. Importing the patch (hg import ../unit-njs-module.patch) with last unit version present in mercury repo i got this error:

applying ../unit-njs-module.patch
patching file src/nxt_http.h
Hunk #1 succeeded at 215 with fuzz 1 (offset 16 lines).
Hunk #2 succeeded at 345 with fuzz 2 (offset 23 lines).
patching file src/nxt_http_request.c
Hunk #1 succeeded at 45 with fuzz 2 (offset 19 lines).
patching file src/nxt_http_route.c
Hunk #1 FAILED at 91
Hunk #2 FAILED at 240
Hunk #3 FAILED at 252
Hunk #4 FAILED at 2033
Hunk #5 FAILED at 2042
Hunk #6 FAILED at 2234
Hunk #7 FAILED at 2249
Hunk #8 FAILED at 2258
8 out of 8 hunks FAILED -- saving rejects to file src/nxt_http_route.c.rej

Can you help me?

lucatacconi avatar Jun 07 '22 10:06 lucatacconi

Hi @lucatacconi Since I didn't keep it up to date, this is a bit old. But I can update it in a few days.

hongzhidao avatar Jun 07 '22 11:06 hongzhidao