Mercurial > hg > nginx-site
comparison xml/en/docs/njs/examples.xml @ 2245:87a0e2c73a25
Refactored njs documentation.
author | Yaroslav Zhuravlev <yar@nginx.com> |
---|---|
date | Mon, 24 Sep 2018 19:10:29 +0300 |
parents | |
children | 32ba43abf9cd |
comparison
equal
deleted
inserted
replaced
2244:467aef18bf12 | 2245:87a0e2c73a25 |
---|---|
1 <?xml version="1.0"?> | |
2 | |
3 <!-- | |
4 Copyright (C) Nginx, Inc. | |
5 --> | |
6 | |
7 <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> | |
8 | |
9 <article name="Examples" | |
10 link="/en/docs/njs/examples.html" | |
11 lang="en" | |
12 rev="1"> | |
13 | |
14 <section id="helloword" name="Hello World"> | |
15 | |
16 <para> | |
17 <path>nginx.conf</path>: | |
18 <example> | |
19 load_module modules/ngx_http_js_module.so; | |
20 | |
21 events {} | |
22 | |
23 http { | |
24 js_include hello_world.js; | |
25 | |
26 server { | |
27 listen 8000; | |
28 | |
29 location / { | |
30 js_content hello; | |
31 } | |
32 } | |
33 } | |
34 | |
35 </example> | |
36 </para> | |
37 | |
38 <para> | |
39 <literal>hello_world.js</literal>: | |
40 <example> | |
41 function hello(r) { | |
42 r.return(200, “Hello world!”); | |
43 } | |
44 </example> | |
45 </para> | |
46 | |
47 </section> | |
48 | |
49 | |
50 <section id="urldecode" name="URL Decoding"> | |
51 | |
52 <para> | |
53 <path>nginx.conf</path>: | |
54 <example> | |
55 js_include urldecode.js; | |
56 | |
57 js_set $decoded_foo decoded_foo; | |
58 </example> | |
59 </para> | |
60 | |
61 <para> | |
62 <path>urldecode.js</path>: | |
63 <example> | |
64 function decoded_foo(r) { | |
65 return decodeURIComponent(r.args.foo); | |
66 } | |
67 </example> | |
68 </para> | |
69 | |
70 </section> | |
71 | |
72 | |
73 <section id="urlencode" name="URL Encoding"> | |
74 | |
75 <para> | |
76 <path>nginx.conf</path>: | |
77 <example> | |
78 js_include urlencode.js; | |
79 | |
80 js_set $encoded_foo encoded_foo; | |
81 ... | |
82 | |
83 location / { | |
84 proxy_pass http://example.com?foo=$encoded_foo; | |
85 } | |
86 </example> | |
87 </para> | |
88 | |
89 <para> | |
90 <path>urlencode.js</path>: | |
91 <example> | |
92 function encoded_foo(r) { | |
93 return encodeURIComponent('foo & bar?'); | |
94 } | |
95 </example> | |
96 </para> | |
97 | |
98 </section> | |
99 | |
100 | |
101 <section id="redirect" name="Internal Redirect"> | |
102 | |
103 <para> | |
104 <path>nginx.conf</path>: | |
105 <example> | |
106 js_include redirect.js; | |
107 | |
108 location /redirect { | |
109 js_content redirect; | |
110 } | |
111 | |
112 location @named { | |
113 return 200 named; | |
114 } | |
115 </example> | |
116 </para> | |
117 | |
118 <para> | |
119 <path>redirect.js</path>: | |
120 <example> | |
121 function redirect(r) { | |
122 r.internalRedirect('@named'); | |
123 } | |
124 </example> | |
125 </para> | |
126 | |
127 </section> | |
128 | |
129 | |
130 <section id="fast_response" name="Returning Fastest Response from Proxy"> | |
131 | |
132 <para> | |
133 <path>nginx.conf</path>: | |
134 <example> | |
135 js_include fastresponse.js; | |
136 | |
137 location /start { | |
138 js_content content; | |
139 } | |
140 | |
141 location /foo { | |
142 proxy_pass http://backend1; | |
143 } | |
144 | |
145 location /bar { | |
146 proxy_pass http://backend2; | |
147 } | |
148 </example> | |
149 </para> | |
150 | |
151 <para> | |
152 <path>fastresponse.js</path>: | |
153 <example> | |
154 function content(r) { | |
155 var n = 0; | |
156 | |
157 function done(res) { | |
158 if (n++ == 0) { | |
159 r.return(res.status, res.responseBody); | |
160 } | |
161 } | |
162 | |
163 r.subrequest('/foo', r.variables.args, done); | |
164 r.subrequest('/bar', r.variables.args, done); | |
165 } | |
166 </example> | |
167 </para> | |
168 | |
169 </section> | |
170 | |
171 | |
172 <section id="jwt" name="Creating HS JWT"> | |
173 | |
174 <para> | |
175 <path>nginx.conf</path>: | |
176 <example> | |
177 js_include hs_jwt.js; | |
178 | |
179 js_set $jwt jwt; | |
180 </example> | |
181 </para> | |
182 | |
183 <para> | |
184 <path>hs_jwt.js</path>: | |
185 <example> | |
186 function create_hs256_jwt(claims, key, valid) { | |
187 var header = { "typ" : "JWT", "alg" : "HS256", "exp" : Date.now() + valid }; | |
188 | |
189 var s = JSON.stringify(header).toBytes().toString('base64url') + '.' | |
190 + JSON.stringify(claims).toBytes().toString('base64url'); | |
191 | |
192 var h = require('crypto').createHmac('sha256', key); | |
193 | |
194 return s + '.' + h.update(s).digest().toString('base64url'); | |
195 } | |
196 | |
197 function jwt(r) { | |
198 var claims = { | |
199 "iss" : "nginx", | |
200 "sub" : "alice", | |
201 "foo" : 123, | |
202 "bar" : "qq", | |
203 "zyx" : false | |
204 }; | |
205 | |
206 return create_hs256_jwt(claims, 'foo', 600); | |
207 } | |
208 </example> | |
209 </para> | |
210 | |
211 </section> | |
212 | |
213 | |
214 <section id="subrequest" name="Accessing API from a Subrequest"> | |
215 | |
216 <para> | |
217 <path>nginx.conf</path>: | |
218 <example> | |
219 js_include subrequest.js; | |
220 | |
221 keyval_zone zone=foo:10m; | |
222 ... | |
223 | |
224 location /keyval { | |
225 js_content set_keyval; | |
226 } | |
227 | |
228 location /version { | |
229 js_content version; | |
230 } | |
231 | |
232 location /api { | |
233 api write=on; | |
234 } | |
235 </example> | |
236 </para> | |
237 | |
238 <para> | |
239 <path>subrequest.js</path>: | |
240 <example> | |
241 function set_keyval(r) { | |
242 r.subrequest('/api/3/http/keyvals/foo', | |
243 { method: 'POST', | |
244 body: JSON.stringify({ foo: 789, bar: "ss dd 00" })}, | |
245 | |
246 function(res) { | |
247 if (res.status >= 300) { | |
248 r.return(res.status, res.responseBody); | |
249 return; | |
250 } | |
251 r.return(500); | |
252 }); | |
253 } | |
254 | |
255 function version(r) { | |
256 r.subrequest('/api/3/nginx', { method: 'GET' }, function(res) { | |
257 if (res.status != 200) { | |
258 r.return(res.status); | |
259 return; | |
260 } | |
261 | |
262 var json = JSON.parse(res.responseBody); | |
263 r.return(200, json.version); | |
264 }); | |
265 } | |
266 </example> | |
267 </para> | |
268 | |
269 </section> | |
270 | |
271 | |
272 <section id="secure_link" name="Creating secure_link Hash"> | |
273 | |
274 <para> | |
275 <path>nginx.conf</path>: | |
276 <example> | |
277 js_include hash.js; | |
278 | |
279 js_set $new_foo create_secure_link; | |
280 ... | |
281 | |
282 location / { | |
283 secure_link $cookie_foo; | |
284 secure_link_md5 "$uri mykey"; | |
285 ... | |
286 } | |
287 | |
288 location @login { | |
289 add_header Set-Cookie "foo=$new_foo; Max-Age=60"; | |
290 return 302 /; | |
291 } | |
292 </example> | |
293 </para> | |
294 | |
295 <para> | |
296 <path>hash.js</path>: | |
297 <example> | |
298 function create_secure_link(r) { | |
299 return require('crypto').createHash('md5') | |
300 .update(r.uri).update(" mykey") | |
301 .digest('base64url'); | |
302 } | |
303 </example> | |
304 </para> | |
305 | |
306 </section> | |
307 | |
308 | |
309 <section id="legacy" name="Legacy Examples"> | |
310 | |
311 <section id="legacy_stream" name="Injecting HTTP header using stream proxy"> | |
312 | |
313 <para> | |
314 Starting from njs <link doc="../njs/njs_changes.xml" id="njs0.2.4">0.2.4</link>, | |
315 stream configuration | |
316 <link doc="../stream/ngx_stream_js_module.xml" id="example">example</link> | |
317 has been changed. | |
318 For njs <link doc="../njs/njs_changes.xml" id="njs0.2.3">0.2.3</link> | |
319 and earlier, use this configuration example: | |
320 <example> | |
321 load_module modules/ngx_stream_js_module.so; | |
322 ... | |
323 | |
324 stream { | |
325 js_include stream.js; | |
326 | |
327 js_set $foo foo; | |
328 js_set $bar bar; | |
329 | |
330 server { | |
331 listen 12345; | |
332 | |
333 js_preread qux; | |
334 return $foo; | |
335 } | |
336 | |
337 server { | |
338 listen 12346; | |
339 | |
340 js_access xyz; | |
341 proxy_pass 127.0.0.1:8000; | |
342 js_filter baz; | |
343 } | |
344 } | |
345 | |
346 http { | |
347 server { | |
348 listen 8000; | |
349 location / { | |
350 return 200 $http_foo\n; | |
351 } | |
352 } | |
353 } | |
354 </example> | |
355 </para> | |
356 | |
357 <para> | |
358 The <path>stream.js</path> file: | |
359 <example> | |
360 var req = ''; | |
361 var matched = 0; | |
362 var line = ''; | |
363 | |
364 function qux(s) { | |
365 var n = s.buffer.indexOf('\n'); | |
366 if (n == -1) { | |
367 return s.AGAIN; | |
368 } | |
369 | |
370 line = s.buffer.substr(0, n); | |
371 } | |
372 | |
373 function foo(s) { | |
374 return line; | |
375 } | |
376 | |
377 function bar(s) { | |
378 var v = s.variables; | |
379 s.log("hello from bar() handler!"); | |
380 return "foo-var" + v.remote_port + "; pid=" + v.pid; | |
381 } | |
382 | |
383 // The filter processes one buffer per call. | |
384 // The buffer is available in s.buffer both for | |
385 // reading and writing. Called for both directions. | |
386 | |
387 function baz(s) { | |
388 if (s.fromUpstream || matched) { | |
389 return; | |
390 } | |
391 | |
392 // Disable certain addresses. | |
393 | |
394 if (s.remoteAddress.match('^192.*')) { | |
395 return s.ERROR; | |
396 } | |
397 | |
398 // Read HTTP request line. | |
399 // Collect bytes in 'req' until request | |
400 // line is read. Clear current buffer to | |
401 // disable output. | |
402 | |
403 req = req + s.buffer; | |
404 s.buffer = ''; | |
405 | |
406 var n = req.search('\n'); | |
407 | |
408 if (n != -1) { | |
409 // Inject a new HTTP header. | |
410 var rest = req.substr(n + 1); | |
411 req = req.substr(0, n + 1); | |
412 | |
413 var addr = s.remoteAddress; | |
414 | |
415 s.log('req:' + req); | |
416 s.log('rest:' + rest); | |
417 | |
418 // Output the result and skip further | |
419 // processing. | |
420 | |
421 s.buffer = req + 'Foo: addr_' + addr + '\r\n' + rest; | |
422 matched = 1; | |
423 } | |
424 } | |
425 | |
426 function xyz(s) { | |
427 if (s.remoteAddress.match('^192.*')) { | |
428 return s.ABORT; | |
429 } | |
430 } | |
431 </example> | |
432 </para> | |
433 | |
434 </section> | |
435 | |
436 </section> | |
437 | |
438 </article> |