unit
unit copied to clipboard
NJS module preview.
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:
- 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.
- Download the patch
wget -O unit-njs-module.patch https://gist.githubusercontent.com/tippexs/b6d167102f0bb06adcde304970e3a757/raw/37b67016a57578d0344737a5f7eec0f1bf194732/hg-unit-njs.patch
- Apply to patch
cd unit
hg import ../unit-njs-module.patch
- Configure
./configure --openssl --with-njs=../njs/
- 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.
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?
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.