Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NJS module preview. #652

Closed
hongzhidao opened this issue Feb 23, 2022 · 3 comments
Closed

NJS module preview. #652

hongzhidao opened this issue Feb 23, 2022 · 3 comments
Assignees
Labels
z-documentation-update-needed This type of issues likely have a link to an issue in the Unit Docs repo

Comments

@hongzhidao
Copy link
Contributor

hongzhidao commented Feb 23, 2022

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 hongzhidao assigned ghost , hongzhidao and VBart Feb 23, 2022
@tippexs tippexs added the z-documentation-update-needed This type of issues likely have a link to an issue in the Unit Docs repo label Mar 15, 2022
@VBart VBart removed their assignment Apr 1, 2022
@lucatacconi
Copy link

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?

@hongzhidao
Copy link
Contributor Author

hongzhidao commented Jun 7, 2022

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
Copy link
Contributor Author

Hi,
It has been added to the stable version. And here's a related document.
https://unit.nginx.org/configuration/#scripting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
z-documentation-update-needed This type of issues likely have a link to an issue in the Unit Docs repo
Projects
None yet
Development

No branches or pull requests

4 participants