# HG changeset patch # User Yaroslav Zhuravlev # Date 1537805429 -10800 # Node ID 87a0e2c73a25047c969d80c029228d736408f461 # Parent 467aef18bf12b52442150f0f47bdd1304019dc4b Refactored njs documentation. diff --git a/xml/en/GNUmakefile b/xml/en/GNUmakefile --- a/xml/en/GNUmakefile +++ b/xml/en/GNUmakefile @@ -125,6 +125,10 @@ REFS = \ njs/index \ njs/njs_changes \ njs/njs_api \ + njs/cli \ + njs/compatibility \ + njs/examples \ + njs/install \ TOP = \ download \ diff --git a/xml/en/docs/http/ngx_http_js_module.xml b/xml/en/docs/http/ngx_http_js_module.xml --- a/xml/en/docs/http/ngx_http_js_module.xml +++ b/xml/en/docs/http/ngx_http_js_module.xml @@ -9,21 +9,21 @@ + rev="17">
The ngx_http_js_module module is used to implement location and variable handlers -in njs — +in njs — a subset of the JavaScript language. This module is not built by default. Download and install instructions are available -here. +here.
diff --git a/xml/en/docs/njs/cli.xml b/xml/en/docs/njs/cli.xml new file mode 100644 --- /dev/null +++ b/xml/en/docs/njs/cli.xml @@ -0,0 +1,47 @@ + + + + + + +
+ +
+ +njs scripts development and debugging can be performed +from the command-line. +The command-line utility is available after the installation of +the Linux package +or after building from the +sources. +Compared to njs running inside nginx, +nginx objects +(HTTP and +Stream) +are not available in the utility. + +$ echo "2**3" | njs - +8 + +$ njs +>> var o = {a:[]} +undefined + +>> JSON.stringify(o, undefined,1) +{ + "a": [ + + ] +} +>> + + + +
+ +
diff --git a/xml/en/docs/njs/compatibility.xml b/xml/en/docs/njs/compatibility.xml new file mode 100644 --- /dev/null +++ b/xml/en/docs/njs/compatibility.xml @@ -0,0 +1,242 @@ + + + + + + +
+ +
+ + +njs is created in compliance with +ECMAScript 5.1 +(strict mode) with some +ECMAScript 6 +and later extensions. +The compliance is still evolving. + + +
+ + +
+ + + + + +Boolean values, numbers, strings, objects, arrays, +functions, and regular expressions + + + +ES5.1 operators, ES7 exponentiation operators + + + +ES5.1 statements: var, if, +else, switch, for, +for in, while, +do while, break, +continue, return, try, +catch, throw, finally + + + +ES6 Number and +Math properties and methods + + + +String methods: + + + +ES5.1: +fromCharCode, concat, +slice, substring, +substr, charAt, +charCodeAt, indexOf, +lastIndexOf, toLowerCase, +toUpperCase, trim, +search, match, split, +replace + + + +ES6: +fromCodePoint, codePointAt, +includes, startsWith, +endsWith, repeat + + + +non-standard: +bytesFrom (0.2.3) +fromUTF8, toUTF8, +fromBytes, toBytes + + + + + + +Object methods: + + +ES5.1: +create (support without properties list), +keys, +defineProperty, +defineProperties, +getOwnPropertyDescriptor, +getPrototypeOf, +hasOwnProperty, +isPrototypeOf, +preventExtensions, +isExtensible, +freeze, +isFrozen, +seal, +isSealed + + + + + + +Array methods: + + +ES5.1: +isArray, slice, splice, +push, pop, unshift, +shift, reverse, sort, +join, concat, indexOf, +lastIndexOf, forEach, +some, every, filter, +map, reduce, +reduceRight + + + +ES6: +of, fill, find, +findIndex + + + +ES7: includes + + + + + + +ES5.1 Function methods: +call, apply, bind + + + +ES5.1 RegExp methods: +test, exec + + + +ES5.1 Date methods + + + +ES5.1 JSON object + + + +ES5.1 global functions: +isFinite, isNaN, +parseFloat, parseInt, +decodeURI, decodeURIComponent, +encodeURI, encodeURIComponent + + + +Error objects: +Error, EvalError, +InternalError, RangeError, +ReferenceError, SyntaxError, +TypeError, URIError + + + +setTimeout() and clearTimeout() functions +(0.2.0) + + + +Node.js style +File system methods: +fs.readFile, fs.readFileSync, +fs.appendFile, fs.appendFileSync, +fs.writeFile, fs.writeFileSync + + + +Node.js style +Crypto methods (0.2.0): +crypto.createHash, +crypto.createHmac + + + + + + +
+ + +
+ + + + + +ES6 let and const declarations + + + +labels + + + +arguments array + + + +eval function + + + +new Function() constructor + + + +setInterval, +setImmediate functions + + + +non-integer fractions (.235) + + + + + +
+ +
+ diff --git a/xml/en/docs/njs/examples.xml b/xml/en/docs/njs/examples.xml new file mode 100644 --- /dev/null +++ b/xml/en/docs/njs/examples.xml @@ -0,0 +1,438 @@ + + + + + + +
+ +
+ + +nginx.conf: + +load_module modules/ngx_http_js_module.so; + +events {} + +http { + js_include hello_world.js; + + server { + listen 8000; + + location / { + js_content hello; + } + } +} + + + + + +hello_world.js: + +function hello(r) { + r.return(200, “Hello world!”); +} + + + +
+ + +
+ + +nginx.conf: + +js_include urldecode.js; + +js_set $decoded_foo decoded_foo; + + + + +urldecode.js: + +function decoded_foo(r) { + return decodeURIComponent(r.args.foo); +} + + + +
+ + +
+ + +nginx.conf: + +js_include urlencode.js; + +js_set $encoded_foo encoded_foo; +... + +location / { + proxy_pass http://example.com?foo=$encoded_foo; +} + + + + +urlencode.js: + +function encoded_foo(r) { + return encodeURIComponent('foo & bar?'); +} + + + +
+ + +
+ + +nginx.conf: + +js_include redirect.js; + +location /redirect { + js_content redirect; +} + +location @named { + return 200 named; +} + + + + +redirect.js: + +function redirect(r) { + r.internalRedirect('@named'); +} + + + +
+ + +
+ + +nginx.conf: + +js_include fastresponse.js; + +location /start { + js_content content; +} + +location /foo { + proxy_pass http://backend1; +} + +location /bar { + proxy_pass http://backend2; +} + + + + +fastresponse.js: + +function content(r) { + var n = 0; + + function done(res) { + if (n++ == 0) { + r.return(res.status, res.responseBody); + } + } + + r.subrequest('/foo', r.variables.args, done); + r.subrequest('/bar', r.variables.args, done); +} + + + +
+ + +
+ + +nginx.conf: + +js_include hs_jwt.js; + +js_set $jwt jwt; + + + + +hs_jwt.js: + +function create_hs256_jwt(claims, key, valid) { + var header = { "typ" : "JWT", "alg" : "HS256", "exp" : Date.now() + valid }; + + var s = JSON.stringify(header).toBytes().toString('base64url') + '.' + + JSON.stringify(claims).toBytes().toString('base64url'); + + var h = require('crypto').createHmac('sha256', key); + + return s + '.' + h.update(s).digest().toString('base64url'); +} + +function jwt(r) { + var claims = { + "iss" : "nginx", + "sub" : "alice", + "foo" : 123, + "bar" : "qq", + "zyx" : false + }; + + return create_hs256_jwt(claims, 'foo', 600); +} + + + +
+ + +
+ + +nginx.conf: + +js_include subrequest.js; + +keyval_zone zone=foo:10m; +... + +location /keyval { + js_content set_keyval; +} + +location /version { + js_content version; +} + +location /api { + api write=on; +} + + + + +subrequest.js: + +function set_keyval(r) { + r.subrequest('/api/3/http/keyvals/foo', + { method: 'POST', + body: JSON.stringify({ foo: 789, bar: "ss dd 00" })}, + + function(res) { + if (res.status >= 300) { + r.return(res.status, res.responseBody); + return; + } + r.return(500); + }); +} + +function version(r) { + r.subrequest('/api/3/nginx', { method: 'GET' }, function(res) { + if (res.status != 200) { + r.return(res.status); + return; + } + + var json = JSON.parse(res.responseBody); + r.return(200, json.version); + }); +} + + + +
+ + + + + +
+ +
+ + +Starting from njs 0.2.4, +stream configuration +example +has been changed. +For njs 0.2.3 +and earlier, use this configuration example: + +load_module modules/ngx_stream_js_module.so; +... + +stream { + js_include stream.js; + + js_set $foo foo; + js_set $bar bar; + + server { + listen 12345; + + js_preread qux; + return $foo; + } + + server { + listen 12346; + + js_access xyz; + proxy_pass 127.0.0.1:8000; + js_filter baz; + } +} + +http { + server { + listen 8000; + location / { + return 200 $http_foo\n; + } + } +} + + + + +The stream.js file: + +var req = ''; +var matched = 0; +var line = ''; + +function qux(s) { + var n = s.buffer.indexOf('\n'); + if (n == -1) { + return s.AGAIN; + } + + line = s.buffer.substr(0, n); +} + +function foo(s) { + return line; +} + +function bar(s) { + var v = s.variables; + s.log("hello from bar() handler!"); + return "foo-var" + v.remote_port + "; pid=" + v.pid; +} + +// The filter processes one buffer per call. +// The buffer is available in s.buffer both for +// reading and writing. Called for both directions. + +function baz(s) { + if (s.fromUpstream || matched) { + return; + } + + // Disable certain addresses. + + if (s.remoteAddress.match('^192.*')) { + return s.ERROR; + } + + // Read HTTP request line. + // Collect bytes in 'req' until request + // line is read. Clear current buffer to + // disable output. + + req = req + s.buffer; + s.buffer = ''; + + var n = req.search('\n'); + + if (n != -1) { + // Inject a new HTTP header. + var rest = req.substr(n + 1); + req = req.substr(0, n + 1); + + var addr = s.remoteAddress; + + s.log('req:' + req); + s.log('rest:' + rest); + + // Output the result and skip further + // processing. + + s.buffer = req + 'Foo: addr_' + addr + '\r\n' + rest; + matched = 1; + } +} + +function xyz(s) { + if (s.remoteAddress.match('^192.*')) { + return s.ABORT; + } +} + + + +
+ +
+ +
diff --git a/xml/en/docs/njs/index.xml b/xml/en/docs/njs/index.xml --- a/xml/en/docs/njs/index.xml +++ b/xml/en/docs/njs/index.xml @@ -9,192 +9,52 @@
- -
+ rev="24" + toc="no"> - -njs is a subset of the JavaScript language that allows -implementing location and variable handlers in -http and -stream. -njs is created in compliance with -ECMAScript 5.1 -(strict mode) with some -ECMAScript 6 -extensions. -The compliance is still evolving. - - -
- - -
+ -
+
+ + +njs is a subset of the JavaScript language that allows +extending nginx functionality. +njs is created in compliance with +ECMAScript 5.1 +(strict mode) with some +ECMAScript 6 +and later extensions. +The compliance is still evolving. + + +
+ + +
-ES6 let and const declarations - - - -labels - - - -arguments array +Complex access control and security checks in njs +before a request reaches an upstream server -eval function - - - -new Function() constructor +Manipulating response headers -setInterval, -setImmediate functions - - - -non-integer fractions (.235) +Writing flexible asynchronous content handlers and filters +See examples and +blog posts +for more njs use cases.
-
+
-The complete list of njs changes is available -here. - -
- - -
- - -njs API reference is available -here. - -
- - -
- - -njs is available in two modules: +To use njs in nginx: -ngx_http_js_module + +install njs scripting language + + + + + +create an njs script file, for example, hello_world.js. +See Reference +for the list of njs properties and methods. + +function hello(r) { + r.return(200, “Hello world!”); +} + + -ngx_stream_js_module - - -Both modules are not built by default, -they should be either compiled from the sources -or installed as a Linux package. -In addition, the Linux package provides -njs command-line utility. - + +in the nginx.conf file, enable +ngx_http_js_module module +and specify the +js_include +directive +with the hello_world.js script file: + +load_module modules/ngx_http_js_module.so; +events {} -
- -For Linux, njs modules -packages can be used: - +http { + js_include hello_world.js; + + server { + listen 8000; - -nginx-module-njs — njs -dynamic modules - + location / { + js_content hello; + } + } +} - -nginx-module-njs-dbg — debug symbols for the -nginx-module-njs package + + - - -
- - -
- - -The repository -with njs sources can be cloned with the following command: -(requires Mercurial client): - -hg clone http://hg.nginx.org/njs - -Then the modules should be compiled using the ---add-module configuration parameter: - -./configure --add-module=path-to-njs/nginx - -The modules can also be built as -dynamic: - -./configure --add-dynamic-module=path-to-njs/nginx - - - - -To build only njs command-line utility, run -./configure and make njs commands -from njs root directory. -The utility is available as ./build/njs. - - -
- -
- - -
- - -njs scripts development and debugging can be performed -from the command-line. -The command-line utility is available after the installation of -the Linux package -or after building from the sources. -Compared to njs running inside nginx, -nginx objects -(HTTP and -Stream) -are not available in the utility. - -$ echo "2**3" | njs - -8 - -$ njs ->> var o = {a:[]} -undefined - ->> JSON.stringify(o, undefined,1) -{ - "a": [ - - ] -} ->> - +There is also a standalone command line utility +that can be used independently of nginx for njs development and debugging.
diff --git a/xml/en/docs/njs/install.xml b/xml/en/docs/njs/install.xml new file mode 100644 --- /dev/null +++ b/xml/en/docs/njs/install.xml @@ -0,0 +1,67 @@ + + + + + + +
+ +
+ + +For Linux, njs modules +packages can be used: + + + +nginx-module-njs — njs +dynamic modules + + + +nginx-module-njs-dbg — debug symbols for the +nginx-module-njs package + + + + + +
+ + +
+ + +The repository +with njs sources can be cloned with the following command: +(requires Mercurial client): + +hg clone http://hg.nginx.org/njs + +Then the modules should be compiled using the +--add-module configuration parameter: + +./configure --add-module=path-to-njs/nginx + +The modules can also be built as +dynamic: + +./configure --add-dynamic-module=path-to-njs/nginx + + + + +To build only njs command-line utility, run +./configure and make njs commands +from njs root directory. +The utility is available as ./build/njs. + + +
+ +
diff --git a/xml/en/docs/njs/njs_api.xml b/xml/en/docs/njs/njs_api.xml --- a/xml/en/docs/njs/njs_api.xml +++ b/xml/en/docs/njs/njs_api.xml @@ -9,7 +9,7 @@
+ rev="8">
@@ -1278,391 +1278,4 @@ the s.allow()
-
- - -
- - - -js_include urldecode.js; - -js_set $decoded_foo decoded_foo; - - - - -The urldecode.js file: - -function decoded_foo(r) { - return decodeURIComponent(r.args.foo); -} - - - -
- - -
- - - -js_include urlencode.js; - -js_set $encoded_foo encoded_foo; -... - -location / { - proxy_pass http://example.com?foo=$encoded_foo; -} - - - - -The urlencode.js file: - -function encoded_foo(r) { - return encodeURIComponent('foo & bar?'); -} - - - -
- - -
- - - -js_include redirect.js; - -location /redirect { - js_content redirect; -} - -location @named { - return 200 named; -} - - - - -The redirect.js file: - -function redirect(r) { - r.internalRedirect('@named'); -} - - - -
- - -
- - - -js_include fastresponse.js; - -location /start { - js_content content; -} - -location /foo { - proxy_pass http://backend1; -} - -location /bar { - proxy_pass http://backend2; -} - - - - -The fastresponse.js file: - -function content(r) { - var n = 0; - - function done(res) { - if (n++ == 0) { - r.return(res.status, res.responseBody); - } - } - - r.subrequest('/foo', r.variables.args, done); - r.subrequest('/bar', r.variables.args, done); -} - - - -
- - -
- - - -js_include hs_jwt.js; - -js_set $jwt jwt; - - - - -The hs_jwt.js file: - -function create_hs256_jwt(claims, key, valid) { - var header = { "typ" : "JWT", "alg" : "HS256", "exp" : Date.now() + valid }; - - var s = JSON.stringify(header).toBytes().toString('base64url') + '.' - + JSON.stringify(claims).toBytes().toString('base64url'); - - var h = require('crypto').createHmac('sha256', key); - - return s + '.' + h.update(s).digest().toString('base64url'); -} - -function jwt(r) { - var claims = { - "iss" : "nginx", - "sub" : "alice", - "foo" : 123, - "bar" : "qq", - "zyx" : false - }; - - return create_hs256_jwt(claims, 'foo', 600); -} - - - -
- - -
- - - -js_include subrequest.js; - -keyval_zone zone=foo:10m; -... - -location /keyval { - js_content set_keyval; -} - -location /version { - js_content version; -} - -location /api { - api write=on; -} - - - - -The subrequest.js file: - -function set_keyval(r) { - r.subrequest('/api/3/http/keyvals/foo', - { method: 'POST', - body: JSON.stringify({ foo: 789, bar: "ss dd 00" })}, - - function(res) { - if (res.status >= 300) { - r.return(res.status, res.responseBody); - return; - } - r.return(500); - }); -} - -function version(r) { - r.subrequest('/api/3/nginx', { method: 'GET' }, function(res) { - if (res.status != 200) { - r.return(res.status); - return; - } - - var json = JSON.parse(res.responseBody); - r.return(200, json.version); - }); -} - - - -
- - - - - -
- - -
- - -Starting from njs 0.2.4, -stream configuration -example -has been changed. -For njs 0.2.3 -and earlier, use this configuration example: - -load_module modules/ngx_stream_js_module.so; -... - -stream { - js_include stream.js; - - js_set $foo foo; - js_set $bar bar; - - server { - listen 12345; - - js_preread qux; - return $foo; - } - - server { - listen 12346; - - js_access xyz; - proxy_pass 127.0.0.1:8000; - js_filter baz; - } -} - -http { - server { - listen 8000; - location / { - return 200 $http_foo\n; - } - } -} - - - - -The stream.js file: - -var req = ''; -var matched = 0; -var line = ''; - -function qux(s) { - var n = s.buffer.indexOf('\n'); - if (n == -1) { - return s.AGAIN; - } - - line = s.buffer.substr(0, n); -} - -function foo(s) { - return line; -} - -function bar(s) { - var v = s.variables; - s.log("hello from bar() handler!"); - return "foo-var" + v.remote_port + "; pid=" + v.pid; -} - -// The filter processes one buffer per call. -// The buffer is available in s.buffer both for -// reading and writing. Called for both directions. - -function baz(s) { - if (s.fromUpstream || matched) { - return; - } - - // Disable certain addresses. - - if (s.remoteAddress.match('^192.*')) { - return s.ERROR; - } - - // Read HTTP request line. - // Collect bytes in 'req' until request - // line is read. Clear current buffer to - // disable output. - - req = req + s.buffer; - s.buffer = ''; - - var n = req.search('\n'); - - if (n != -1) { - // Inject a new HTTP header. - var rest = req.substr(n + 1); - req = req.substr(0, n + 1); - - var addr = s.remoteAddress; - - s.log('req:' + req); - s.log('rest:' + rest); - - // Output the result and skip further - // processing. - - s.buffer = req + 'Foo: addr_' + addr + '\r\n' + rest; - matched = 1; - } -} - -function xyz(s) { - if (s.remoteAddress.match('^192.*')) { - return s.ABORT; - } -} - - - -
- -
- -
-
diff --git a/xml/en/docs/stream/ngx_stream_js_module.xml b/xml/en/docs/stream/ngx_stream_js_module.xml --- a/xml/en/docs/stream/ngx_stream_js_module.xml +++ b/xml/en/docs/stream/ngx_stream_js_module.xml @@ -9,20 +9,20 @@ + rev="15">
The ngx_stream_js_module module is used to implement -handlers in njs — +handlers in njs — a subset of the JavaScript language. This module is not built by default. Download and install instructions are available -here. +here.
@@ -36,7 +36,7 @@ This example is valid for njs 0.2.4. For njs 0.2.3 and earlier, use -this example. +this example. load_module modules/ngx_stream_js_module.so; diff --git a/xml/index.xml b/xml/index.xml --- a/xml/index.xml +++ b/xml/index.xml @@ -34,7 +34,7 @@ support and control API for TLS c -njs-0.2.4 +njs-0.2.4 version has been released, featuring s.on(), s.off(), @@ -56,7 +56,7 @@ mainline version has been released. -njs-0.2.3 +njs-0.2.3 version has been released, featuring String.bytesFrom(), String.padStart(), @@ -93,7 +93,7 @@ balancing method. -njs-0.2.2 +njs-0.2.2 version has been released, featuring HTTP internalRedirect() method support @@ -119,7 +119,7 @@ mainline version has been released. -njs-0.2.1 +njs-0.2.1 version has been released. @@ -178,7 +178,7 @@ mainline version has been released. -njs-0.2.0 +njs-0.2.0 version has been released, featuring HTTP subrequest() method support diff --git a/xml/ru/GNUmakefile b/xml/ru/GNUmakefile --- a/xml/ru/GNUmakefile +++ b/xml/ru/GNUmakefile @@ -108,6 +108,10 @@ REFS = \ ngx_google_perftools_module \ njs/index \ njs/njs_api \ + njs/cli \ + njs/compatibility \ + njs/examples \ + njs/install \ TOP = \ download \ diff --git a/xml/ru/docs/http/ngx_http_js_module.xml b/xml/ru/docs/http/ngx_http_js_module.xml --- a/xml/ru/docs/http/ngx_http_js_module.xml +++ b/xml/ru/docs/http/ngx_http_js_module.xml @@ -9,21 +9,21 @@ + rev="17">
Модуль ngx_http_js_module позволяет задавать обработчики location и переменных -на njs — +на njs — подмножестве языка JavaScript. По умолчанию этот модуль не собирается. Инструкция по сборке и установке доступны -здесь. +здесь.
diff --git a/xml/ru/docs/njs/cli.xml b/xml/ru/docs/njs/cli.xml new file mode 100644 --- /dev/null +++ b/xml/ru/docs/njs/cli.xml @@ -0,0 +1,46 @@ + + + + + + +
+ +
+ +Создание и отладка njs-скриптов может осуществляться +в командной строке. +Утилита командной строки доступна после установки +пакета Linux +или после сборки из +исходных файлов. +В отличие от njs, запущенном внутри nginx, +в утилите недоступны объекты nginx +(HTTP и +Stream). + +$ echo "2**3" | njs - +8 + +$ njs +>> var o = {a:[]} +undefined + +>> JSON.stringify(o, undefined,1) +{ + "a": [ + + ] +} +>> + + + +
+ +
diff --git a/xml/ru/docs/njs/compatibility.xml b/xml/ru/docs/njs/compatibility.xml new file mode 100644 --- /dev/null +++ b/xml/ru/docs/njs/compatibility.xml @@ -0,0 +1,242 @@ + + + + + + +
+ +
+ + +njs совместим с +ECMAScript 5.1 +(строгий режим) c некоторыми расширениями +ECMAScript 6 +и позже. +Совместимость находится в стадии развития. + + +
+ + +
+ + + + + +Логические значения, числа, строки, объекты, массивы, +функции и регулярные выражения + + + +ES5.1 операторы, ES7 операторы возведения в степень + + + +ES5.1 инструкции: var, if, +else, switch, for, +for in, while, +do while, break, +continue, return, try, +catch, throw, finally + + + +ES6 методы и свойства Number и +Math + + + +Методы String: + + + +ES5.1: +fromCharCode, concat, +slice, substring, +substr, charAt, +charCodeAt, indexOf, +lastIndexOf, toLowerCase, +toUpperCase, trim, +search, match, split, +replace + + + +ES6: +fromCodePoint, codePointAt, +includes, startsWith, +endsWith, repeat + + + +нестандартные: +bytesFrom (0.2.3), +fromUTF8, toUTF8, +fromBytes, toBytes + + + + + + +Методы Object: + + +ES5.1: +create (поддержка без списка свойств), +keys, +defineProperty, +defineProperties, +getOwnPropertyDescriptor, +getPrototypeOf, +hasOwnProperty, +isPrototypeOf, +preventExtensions, +isExtensible, +freeze, +isFrozen, +seal, +isSealed + + + + + + +Методы Array: + + +ES5.1: +isArray, slice, splice, +push, pop, unshift, +shift, reverse, sort, +join, concat, indexOf, +lastIndexOf, forEach, +some, every, filter, +map, reduce, +reduceRight + + + +ES6: +of, fill, find, +findIndex + + + +ES7: includes + + + + + + +ES5.1 методы Function: +call, apply, bind + + + +ES5.1 методы RegExp: +test, exec + + + +ES5.1 методы Date + + + +ES5.1 объект JSON + + + +ES5.1 глобальные функции: +isFinite, isNaN, +parseFloat, parseInt, +decodeURI, decodeURIComponent, +encodeURI, encodeURIComponent + + + +Объекты Error: +Error, EvalError, +InternalError, RangeError, +ReferenceError, SyntaxError, +TypeError, URIError + + + +Функции setTimeout() и clearTimeout() +(0.2.0) + + + +Методы File system +стиль Node.js: +fs.readFile, fs.readFileSync, +fs.appendFile, fs.appendFileSync, +fs.writeFile, fs.writeFileSync + + + +Методы Crypto +стиль Node.js +(0.2.0): +crypto.createHash, +crypto.createHmac + + + + + +
+ + +
+ + + + + +ES6 объявления let и const + + + +labels + + + +массив arguments + + + +функция eval + + + +конструктор new Function() + + + +функции setInterval, +setImmediate + + + +дроби без целой части (.235) + + + + + +
+ +
+ diff --git a/xml/ru/docs/njs/examples.xml b/xml/ru/docs/njs/examples.xml new file mode 100644 --- /dev/null +++ b/xml/ru/docs/njs/examples.xml @@ -0,0 +1,438 @@ + + + + + + +
+ +
+ + +nginx.conf: + +load_module modules/ngx_http_js_module.so; + +events {} + +http { + js_include hello_world.js; + + server { + listen 8000; + + location / { + js_content hello; + } + } +} + + + + + +hello_world.js: + +function hello(r) { + r.return(200, “Hello world!”); +} + + + +
+ + +
+ + +nginx.conf: + +js_include urldecode.js; + +js_set $decoded_foo decoded_foo; + + + + +urldecode.js: + +function decoded_foo(r) { + return decodeURIComponent(r.args.foo); +} + + + +
+ + +
+ + +nginx.conf: + +js_include urlencode.js; + +js_set $encoded_foo encoded_foo; +... + +location / { + proxy_pass http://example.com?foo=$encoded_foo; +} + + + + +urlencode.js: + +function encoded_foo(r) { + return encodeURIComponent('foo & bar?'); +} + + + +
+ + +
+ + +nginx.conf: + +js_include redirect.js; + +location /redirect { + js_content redirect; +} + +location @named { + return 200 named; +} + + + + +redirect.js: + +function redirect(r) { + r.internalRedirect('@named'); +} + + + +
+ + +
+ + +nginx.conf: + +js_include fastresponse.js; + +location /start { + js_content content; +} + +location /foo { + proxy_pass http://backend1; +} + +location /bar { + proxy_pass http://backend2; +} + + + + +fastresponse.js: + +function content(r) { + var n = 0; + + function done(res) { + if (n++ == 0) { + r.return(res.status, res.responseBody); + } + } + + r.subrequest('/foo', r.variables.args, done); + r.subrequest('/bar', r.variables.args, done); +} + + + +
+ + +
+ + +nginx.conf: + +js_include hs_jwt.js; + +js_set $jwt jwt; + + + + +hs_jwt.js: + +function create_hs256_jwt(claims, key, valid) { + var header = { "typ" : "JWT", "alg" : "HS256", "exp" : Date.now() + valid }; + + var s = JSON.stringify(header).toBytes().toString('base64url') + '.' + + JSON.stringify(claims).toBytes().toString('base64url'); + + var h = require('crypto').createHmac('sha256', key); + + return s + '.' + h.update(s).digest().toString('base64url'); +} + +function jwt(r) { + var claims = { + "iss" : "nginx", + "sub" : "alice", + "foo" : 123, + "bar" : "qq", + "zyx" : false + }; + + return create_hs256_jwt(claims, 'foo', 600); +} + + + +
+ + +
+ + +nginx.conf: + +js_include subrequest.js; + +keyval_zone zone=foo:10m; +... + +location /keyval { + js_content set_keyval; +} + +location /version { + js_content version; +} + +location /api { + api write=on; +} + + + + +subrequest.js: + +function set_keyval(r) { + r.subrequest('/api/3/http/keyvals/foo', + { method: 'POST', + body: JSON.stringify({ foo: 789, bar: "ss dd 00" })}, + + function(res) { + if (res.status >= 300) { + r.return(res.status, res.responseBody); + return; + } + r.return(500); + }); +} + +function version(r) { + r.subrequest('/api/3/nginx', { method: 'GET' }, function(res) { + if (res.status != 200) { + r.return(res.status); + return; + } + + var json = JSON.parse(res.responseBody); + r.return(200, json.version); + }); +} + + + +
+ + + + + +
+ +
+ + +Начиная с версии njs 0.2.4 +пример +конфигурации в stream +был изменён. +Для njs 0.2.3 +и более ранних версий необходимо использовать следующий пример конфигурации: + +load_module modules/ngx_stream_js_module.so; +... + +stream { + js_include stream.js; + + js_set $foo foo; + js_set $bar bar; + + server { + listen 12345; + + js_preread qux; + return $foo; + } + + server { + listen 12346; + + js_access xyz; + proxy_pass 127.0.0.1:8000; + js_filter baz; + } +} + +http { + server { + listen 8000; + location / { + return 200 $http_foo\n; + } + } +} + + + + +Файл stream.js: + +var req = ''; +var matched = 0; +var line = ''; + +function qux(s) { + var n = s.buffer.indexOf('\n'); + if (n == -1) { + return s.AGAIN; + } + + line = s.buffer.substr(0, n); +} + +function foo(s) { + return line; +} + +function bar(s) { + var v = s.variables; + s.log("hello from bar() handler!"); + return "foo-var" + v.remote_port + "; pid=" + v.pid; +} + +// Фильтр обрабатывает один буфер за вызов. +// Буфер недоступен в s.buffer для +// чтения и записи. Вызывается в обоих направлениях. + +function baz(s) { + if (s.fromUpstream || matched) { + return; + } + + // Отключение определённых адресов. + + if (s.remoteAddress.match('^192.*')) { + return s.ERROR; + } + + // Чтение строки HTTP-запроса. + // Получение байт в 'req' до того как + // будет прочитана строка запроса. Очистка текущего буфера + // для отключения вывода. + + req = req + s.buffer; + s.buffer = ''; + + var n = req.search('\n'); + + if (n != -1) { + // Inject a new HTTP header. + var rest = req.substr(n + 1); + req = req.substr(0, n + 1); + + var addr = s.remoteAddress; + + s.log('req:' + req); + s.log('rest:' + rest); + + // Вывод результата и пропуск дальнейшей + // обработки. + + s.buffer = req + 'Foo: addr_' + addr + '\r\n' + rest; + matched = 1; + } +} + +function xyz(s) { + if (s.remoteAddress.match('^192.*')) { + return s.ABORT; + } +} + + + +
+ +
+ +
diff --git a/xml/ru/docs/njs/index.xml b/xml/ru/docs/njs/index.xml --- a/xml/ru/docs/njs/index.xml +++ b/xml/ru/docs/njs/index.xml @@ -9,191 +9,52 @@
- -
+ rev="24" + toc="no"> - -njs - это подмножество языка JavaScript, который позволяет -задавать обработчики location и переменных в -http и -stream. -njs совместим с -ECMAScript 5.1 -(строгий режим) c некоторыми расширениями -ECMAScript 6. -Совместимость находится в стадии развития. - - -
- - -
+ -
+
+ + +njs - это подмножество языка JavaScript, позволяющее +расширить функциональность nginx. +njs совместим с +ECMAScript 5.1 +(строгий режим) c некоторыми расширениями +ECMAScript 6 +и позже. +Совместимость находится в стадии +развития. + + +
+ + +
-ES6 объявления let и const - - - -labels - - - -массив arguments +Комплексное управление доступом и проверка защиты при помощи njs +до получения запроса сервером группы -функция eval - - - -конструктор new Function() +Управление заголовками ответа -функции setInterval, -setImmediate - - - -дроби без целой части (.235) +Создание гибких асинхронных обработчиков содержимого и фильтров +Подробнее о сценариях использования +см. в примерах +и блогпостах.
-
- - -Полная история изменений njs доступна -здесь. - -
- -
+
-Справочник njs API доступен -здесь. - -
- - -
- - -njs доступен в двух модулях: +Чтобы использовать njs в nginx, необходимо: -ngx_http_js_module + +установить njs + + + + + +создать файл сценария njs, например hello_world.js. +Описание свойств и методов языка njs +см. в справочнике. + +function hello(r) { + r.return(200, “Hello world!”); +} + + -ngx_stream_js_module + + +в файле nginx.conf включить +модуль ngx_http_js_module +и указать директиву +js_include +с файлом сценария hello_world.js: + +load_module modules/ngx_http_js_module.so; + +events {} + +http { + js_include hello_world.js; + + server { + listen 8000; + + location / { + js_content hello; + } + } +} + + + -По умолчанию модули не собираются -их необходимо собрать из исходного кода -или установить из отдельного пакета Linux. -Кроме того, в пакете Linux предоставляется -утилита командной строки njs. - - - -
- -Для установки модулей njs на Linux могут быть использованы -пакеты: - - - -nginx-module-njs — -динамические модули -njs - - - -nginx-module-njs-dbg — debug-символы для -пакета nginx-module-njs - - - + Также доступна отдельная утилита командной строки, +которая может использоваться независимо от nginx для разработки и отладки njs.
- -
- - -Репозиторий -с исходным кодом njs можно клонировать следующей командой: -(необходим клиент Mercurial): - -hg clone http://hg.nginx.org/njs - -Затем модули необходимо собрать с помощью -конфигурационного параметра --add-module: - -./configure --add-module=path-to-njs/nginx - -Модули также можно собрать как -динамические: - -./configure --add-dynamic-module=path-to-njs/nginx - - - - -Чтобы собрать только утилиту командной строки njs -необходимо запустить -команды ./configure и make njs -из корневого каталога. -Утилита доступна как ./build/njs. - - -
- - -
- - -Создание и отладка njs-скриптов может осуществляться -в командной строке. -Утилита командной строки доступна после установки -пакета Linux -или после сборки из исходных файлов. -В отличие от njs, запущенном внутри nginx, -в утилите недоступны объекты nginx -(HTTP и -Stream). - -$ echo "2**3" | njs - -8 - -$ njs ->> var o = {a:[]} -undefined - ->> JSON.stringify(o, undefined,1) -{ - "a": [ - - ] -} ->> - - - -
- -
-
diff --git a/xml/ru/docs/stream/ngx_stream_js_module.xml b/xml/ru/docs/stream/ngx_stream_js_module.xml --- a/xml/ru/docs/stream/ngx_stream_js_module.xml +++ b/xml/ru/docs/stream/ngx_stream_js_module.xml @@ -9,20 +9,20 @@ + rev="15">
Модуль ngx_stream_js_module позволяет задавать -обработчики на njs — +обработчики на njs — подмножестве языка JavaScript. По умолчанию этот модуль не собирается. Инструкция по сборке и установке доступны -здесь. +здесь.
@@ -36,7 +36,7 @@ версией njs 0.2.4. Для версий njs 0.2.3 и ранее необходимо использовать -этот пример. +этот пример. load_module modules/ngx_stream_js_module.so;