aboutsummaryrefslogtreecommitdiff
path: root/nginx/t
diff options
context:
space:
mode:
Diffstat (limited to 'nginx/t')
-rw-r--r--nginx/t/js_fetch.t31
-rw-r--r--nginx/t/js_fetch_https.t10
-rw-r--r--nginx/t/js_fetch_objects.t10
-rw-r--r--nginx/t/js_fetch_resolver.t10
-rw-r--r--nginx/t/js_fetch_timeout.t10
-rw-r--r--nginx/t/js_fetch_verify.t10
-rw-r--r--nginx/t/js_internal_redirect.t29
-rw-r--r--nginx/t/js_periodic.t2
-rw-r--r--nginx/t/js_periodic_fetch.t19
-rw-r--r--nginx/t/js_shared_dict.t10
-rw-r--r--nginx/t/js_shared_dict_state.t256
-rw-r--r--nginx/t/stream_js_fetch.t10
-rw-r--r--nginx/t/stream_js_fetch_https.t10
-rw-r--r--nginx/t/stream_js_fetch_init.t10
-rw-r--r--nginx/t/stream_js_periodic_fetch.t10
-rw-r--r--nginx/t/stream_js_shared_dict.t10
-rw-r--r--nginx/t/stream_js_shared_dict_state.t137
17 files changed, 459 insertions, 125 deletions
diff --git a/nginx/t/js_fetch.t b/nginx/t/js_fetch.t
index 7ee1a602..76d9238d 100644
--- a/nginx/t/js_fetch.t
+++ b/nginx/t/js_fetch.t
@@ -52,10 +52,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /broken {
js_content test.broken;
}
@@ -68,6 +64,10 @@ http {
js_content test.body;
}
+ location /body_content_length {
+ js_content test.body_content_length;
+ }
+
location /body_special {
js_content test.body_special;
}
@@ -138,10 +138,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
function body(r) {
var loc = r.args.loc;
var getter = r.args.getter;
@@ -164,6 +160,13 @@ $t->write_file('test.js', <<EOF);
.catch(e => r.return(501, e.message))
}
+ async function body_content_length(r) {
+ let resp = await ngx.fetch(`http://127.0.0.1:$p0/loc`,
+ {headers: {'Content-Length': '100'},
+ body: "CONTENT-BODY"});
+ r.return(resp.status);
+ }
+
function property(r) {
var opts = {headers:{}};
@@ -408,12 +411,12 @@ $t->write_file('test.js', <<EOF);
export default {njs: test_njs, body, broken, broken_response, body_special,
chain, chunked_ok, chunked_fail, header, header_iter,
- host_header, multi, loc, property, engine};
+ host_header, multi, loc, property, body_content_length };
EOF
$t->try_run('no njs.fetch');
-$t->plan(37);
+$t->plan(38);
$t->run_daemon(\&http_daemon, port(8082));
$t->waitforsocket('127.0.0.1:' . port(8082));
@@ -516,6 +519,14 @@ like(http_get('/body_special?loc=head/large&method=HEAD'),
qr/200 OK.*<empty>$/s, 'fetch head method large content-length');
}
+TODO: {
+local $TODO = 'not yet' unless has_version('0.9.1');
+
+like(http_get('/body_content_length'), qr/200 OK/s,
+ 'fetch body content-length');
+
+}
+
###############################################################################
sub has_version {
diff --git a/nginx/t/js_fetch_https.t b/nginx/t/js_fetch_https.t
index 8ede1048..42b5acbb 100644
--- a/nginx/t/js_fetch_https.t
+++ b/nginx/t/js_fetch_https.t
@@ -48,10 +48,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /https {
js_content test.https;
}
@@ -106,10 +102,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
function https(r) {
var url = `https://\${r.args.domain}:$p1/loc`;
var opt = {};
@@ -124,7 +116,7 @@ $t->write_file('test.js', <<EOF);
.catch(e => r.return(501, e.message))
}
- export default {njs: test_njs, https, engine};
+ export default {njs: test_njs, https};
EOF
my $d = $t->testdir();
diff --git a/nginx/t/js_fetch_objects.t b/nginx/t/js_fetch_objects.t
index bc5cc7ed..c9d04c49 100644
--- a/nginx/t/js_fetch_objects.t
+++ b/nginx/t/js_fetch_objects.t
@@ -45,10 +45,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /headers {
js_content test.headers;
}
@@ -92,10 +88,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
function header(r) {
r.return(200, r.headersIn.a);
}
@@ -528,7 +520,7 @@ $t->write_file('test.js', <<EOF);
run(r, tests);
}
- export default {njs: test_njs, engine, body, headers, request, response,
+ export default {njs: test_njs, body, headers, request, response,
fetch, fetch_multi_header};
EOF
diff --git a/nginx/t/js_fetch_resolver.t b/nginx/t/js_fetch_resolver.t
index 031ff43c..67680283 100644
--- a/nginx/t/js_fetch_resolver.t
+++ b/nginx/t/js_fetch_resolver.t
@@ -50,10 +50,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /dns {
js_content test.dns;
@@ -108,10 +104,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
const p0 = $p0;
const p1 = $p1;
@@ -141,7 +133,7 @@ $t->write_file('test.js', <<EOF);
r.return(c, `\${v.host}:\${v.request_method}:\${foo}:\${bar}:\${body}`);
}
- export default {njs: test_njs, dns, loc, engine};
+ export default {njs: test_njs, dns, loc};
EOF
$t->try_run('no njs.fetch');
diff --git a/nginx/t/js_fetch_timeout.t b/nginx/t/js_fetch_timeout.t
index ab1ba24a..2ca1510f 100644
--- a/nginx/t/js_fetch_timeout.t
+++ b/nginx/t/js_fetch_timeout.t
@@ -47,10 +47,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /normal_timeout {
js_content test.timeout_test;
}
@@ -84,10 +80,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
async function timeout_test(r) {
let rs = await Promise.allSettled([
'http://127.0.0.1:$p1/normal_reply',
@@ -110,7 +102,7 @@ $t->write_file('test.js', <<EOF);
setTimeout((r) => { r.return(200); }, 250, r, 0);
}
- export default {njs: test_njs, engine, timeout_test, normal_reply,
+ export default {njs: test_njs, timeout_test, normal_reply,
delayed_reply};
EOF
diff --git a/nginx/t/js_fetch_verify.t b/nginx/t/js_fetch_verify.t
index f98b4d8c..8b691a74 100644
--- a/nginx/t/js_fetch_verify.t
+++ b/nginx/t/js_fetch_verify.t
@@ -48,10 +48,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /https {
js_content test.https;
}
@@ -80,10 +76,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
function https(r) {
ngx.fetch(`https://example.com:$p1/loc`)
.then(reply => reply.text())
@@ -91,7 +83,7 @@ $t->write_file('test.js', <<EOF);
.catch(e => r.return(501, e.message));
}
- export default {njs: test_njs, engine, https};
+ export default {njs: test_njs, https};
EOF
$t->write_file('openssl.conf', <<EOF);
diff --git a/nginx/t/js_internal_redirect.t b/nginx/t/js_internal_redirect.t
index abfe79f9..721113bb 100644
--- a/nginx/t/js_internal_redirect.t
+++ b/nginx/t/js_internal_redirect.t
@@ -11,6 +11,7 @@ use warnings;
use strict;
use Test::More;
+use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -54,6 +55,10 @@ http {
return 200 redirect$arg_b;
}
+ location /destroyed_ctx {
+ js_content test.destroyed_ctx;
+ }
+
location @named {
return 200 named;
}
@@ -87,7 +92,16 @@ $t->write_file('test.js', <<EOF);
}
}
- export default {njs:test_njs, redirect};
+ function destroyed_ctx(r) {
+ try {
+ r.return(200);
+
+ } catch (e) {
+ r.internalRedirect("\@sub");
+ }
+ }
+
+ export default {njs:test_njs, redirect, destroyed_ctx};
EOF
@@ -103,5 +117,18 @@ like(http_get('/test?unsafe=1'), qr/500 Internal Server/s,
'unsafe redirect');
like(http_get('/test?quoted=1'), qr/200 .*redirect/s,
'quoted redirect');
+get('/destroyed_ctx', 'If-Match: tt');
###############################################################################
+
+sub get {
+ my ($url, @headers) = @_;
+ return http(
+ "GET $url HTTP/1.1" . CRLF .
+ 'Host: localhost' . CRLF .
+ 'Connection: close' . CRLF .
+ join(CRLF, @headers) . CRLF . CRLF
+ );
+}
+
+################################################################################
diff --git a/nginx/t/js_periodic.t b/nginx/t/js_periodic.t
index d6868935..7e134588 100644
--- a/nginx/t/js_periodic.t
+++ b/nginx/t/js_periodic.t
@@ -56,7 +56,7 @@ http {
server_name localhost;
location @periodic {
- js_periodic test.tick interval=30ms jitter=1ms;
+ js_periodic test.tick interval=20ms jitter=1ms;
js_periodic test.timer interval=1s worker_affinity=all;
js_periodic test.overrun interval=30ms;
js_periodic test.affinity interval=50ms worker_affinity=0101;
diff --git a/nginx/t/js_periodic_fetch.t b/nginx/t/js_periodic_fetch.t
index 0231b662..39385132 100644
--- a/nginx/t/js_periodic_fetch.t
+++ b/nginx/t/js_periodic_fetch.t
@@ -54,10 +54,6 @@ http {
js_periodic test.fetch_exception interval=1s;
}
- location /engine {
- js_content test.engine;
- }
-
location /fetch_ok {
return 200 'ok';
}
@@ -81,10 +77,6 @@ EOF
my $p0 = port(8080);
$t->write_file('test.js', <<EOF);
- function engine(r) {
- r.return(200, njs.engine);
- }
-
async function fetch() {
let reply = await ngx.fetch('http://127.0.0.1:$p0/fetch_ok');
let body = await reply.text();
@@ -107,16 +99,15 @@ $t->write_file('test.js', <<EOF);
}
function test_fetch(r) {
- r.return(200, ngx.shared.strings.get('fetch').startsWith('okok'));
+ r.return(200, ngx.shared.strings.get('fetch'));
}
function test_multiple_fetches(r) {
- r.return(200, ngx.shared.strings.get('multiple_fetches')
- .startsWith('ok\@foo'));
+ r.return(200, ngx.shared.strings.get('multiple_fetches'));
}
export default { fetch, fetch_exception, multiple_fetches, test_fetch,
- test_multiple_fetches, engine };
+ test_multiple_fetches };
EOF
$t->try_run('no js_periodic with fetch');
@@ -127,8 +118,8 @@ $t->plan(3);
select undef, undef, undef, 0.1;
-like(http_get('/test_fetch'), qr/true/, 'periodic fetch test');
-like(http_get('/test_multiple_fetches'), qr/true/, 'multiple fetch test');
+like(http_get('/test_fetch'), qr/(ok)+/, 'periodic fetch test');
+like(http_get('/test_multiple_fetches'), qr/ok\@foo/, 'multiple fetch test');
$t->stop();
diff --git a/nginx/t/js_shared_dict.t b/nginx/t/js_shared_dict.t
index 8be2831f..b27a33ef 100644
--- a/nginx/t/js_shared_dict.t
+++ b/nginx/t/js_shared_dict.t
@@ -52,10 +52,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /add {
js_content test.add;
}
@@ -141,10 +137,6 @@ $t->write_file('test.js', <<'EOF');
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
function convertToValue(dict, v) {
if (dict.type == 'number') {
return parseInt(v);
@@ -337,7 +329,7 @@ $t->write_file('test.js', <<'EOF');
export default { add, capacity, chain, clear, del, free_space, get, has,
incr, items, keys, name, njs: test_njs, pop, replace, set,
- set_clear, size, zones, engine, overflow };
+ set_clear, size, zones, overflow };
EOF
$t->try_run('no js_shared_dict_zone');
diff --git a/nginx/t/js_shared_dict_state.t b/nginx/t/js_shared_dict_state.t
new file mode 100644
index 00000000..32eef948
--- /dev/null
+++ b/nginx/t/js_shared_dict_state.t
@@ -0,0 +1,256 @@
+#!/usr/bin/perl
+
+# (C) Dmitry Volyntsev
+# (C) Nginx, Inc.
+
+# Tests for js_shared_dict_zone directive, state= parameter.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+use Socket qw/ CRLF /;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+eval { require JSON::PP; };
+plan(skip_all => "JSON::PP not installed") if $@;
+
+my $t = Test::Nginx->new()->has(qw/http/)
+ ->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+daemon off;
+
+events {
+}
+
+http {
+ %%TEST_GLOBALS_HTTP%%
+
+ js_import test.js;
+
+ js_shared_dict_zone zone=bar:64k type=string state=bar.json;
+ js_shared_dict_zone zone=waka:32k timeout=1000s type=number state=waka.json;
+
+ server {
+ listen 127.0.0.1:8080;
+ server_name localhost;
+
+ location /add {
+ js_content test.add;
+ }
+
+ location /clear {
+ js_content test.clear;
+ }
+
+ location /delete {
+ js_content test.del;
+ }
+
+ location /get {
+ js_content test.get;
+ }
+
+ location /incr {
+ js_content test.incr;
+ }
+
+ location /pop {
+ js_content test.pop;
+ }
+
+ location /set {
+ js_content test.set;
+ }
+ }
+}
+
+EOF
+
+$t->write_file('bar.json', <<EOF);
+{"waka":{"value":"foo","expire":0},
+ "bar": { "value" :"\\u0061\\u0062\\u0063"},
+"FOO \\n": { "value" : "BAZ", "unexpected_str": "u\\r" },
+ "X": { "valu\\u0065" : "\\n" , "unexpected_num": 23.1 } ,
+ "\\u0061\\u0062\\u0063": { "value" : "def" } ,
+}
+EOF
+
+$t->write_file('test.js', <<'EOF');
+ function convertToValue(dict, v) {
+ if (dict.type == 'number') {
+ return parseInt(v);
+
+ } else if (v == 'empty') {
+ v = '';
+ }
+
+ return v;
+ }
+
+ function add(r) {
+ var dict = ngx.shared[r.args.dict];
+ var value = convertToValue(dict, r.args.value);
+
+ if (r.args.timeout) {
+ var timeout = Number(r.args.timeout);
+ r.return(200, dict.add(r.args.key, value, timeout));
+
+ } else {
+ r.return(200, dict.add(r.args.key, value));
+ }
+ }
+
+ function clear(r) {
+ var dict = ngx.shared[r.args.dict];
+ var result = dict.clear();
+ r.return(200, result === undefined ? 'undefined' : result);
+ }
+
+ function del(r) {
+ var dict = ngx.shared[r.args.dict];
+ r.return(200, dict.delete(r.args.key));
+ }
+
+ function get(r) {
+ var dict = ngx.shared[r.args.dict];
+ var val = dict.get(r.args.key);
+
+ if (val == '') {
+ val = 'empty';
+
+ } else if (val === undefined) {
+ val = 'undefined';
+ }
+
+ r.return(200, val);
+ }
+
+ function incr(r) {
+ var dict = ngx.shared[r.args.dict];
+ var def = r.args.def ? parseInt(r.args.def) : 0;
+
+ if (r.args.timeout) {
+ var timeout = Number(r.args.timeout);
+ var val = dict.incr(r.args.key, parseInt(r.args.by), def, timeout);
+ r.return(200, val);
+
+ } else {
+ var val = dict.incr(r.args.key, parseInt(r.args.by), def);
+ r.return(200, val);
+ }
+ }
+
+ function pop(r) {
+ var dict = ngx.shared[r.args.dict];
+ var val = dict.pop(r.args.key);
+ if (val == '') {
+ val = 'empty';
+
+ } else if (val === undefined) {
+ val = 'undefined';
+ }
+
+ r.return(200, val);
+ }
+
+ function set(r) {
+ var dict = ngx.shared[r.args.dict];
+ var value = convertToValue(dict, r.args.value);
+
+ if (r.args.timeout) {
+ var timeout = Number(r.args.timeout);
+ r.return(200, dict.set(r.args.key, value, timeout) === dict);
+
+ } else {
+ r.return(200, dict.set(r.args.key, value) === dict);
+ }
+ }
+
+ export default { add, clear, del, get, incr, pop, set };
+EOF
+
+$t->try_run('no js_shared_dict_zone with state=')->plan(11);
+
+###############################################################################
+
+like(http_get('/get?dict=bar&key=waka'), qr/foo/, 'get bar.waka');
+like(http_get('/get?dict=bar&key=bar'), qr/abc/, 'get bar.bar');
+like(http_get('/get?dict=bar&key=FOO%20%0A'), qr/BAZ/, 'get bar["FOO \\n"]');
+like(http_get('/get?dict=bar&key=abc'), qr/def/, 'get bar.abc');
+
+http_get('/set?dict=bar&key=waka&value=foo2');
+http_get('/delete?dict=bar&key=bar');
+
+http_get('/set?dict=waka&key=foo&value=42');
+
+select undef, undef, undef, 1.1;
+
+$t->reload();
+
+my $bar_state = read_state($t, 'bar.json');
+my $waka_state = read_state($t, 'waka.json');
+
+is($bar_state->{waka}->{value}, 'foo2', 'get bar.waka from state');
+is($bar_state->{bar}, undef, 'no bar.bar in state');
+is($waka_state->{foo}->{value}, '42', 'get waka.foo from state');
+like($waka_state->{foo}->{expire}, qr/^\d+$/, 'waka.foo expire');
+
+http_get('/pop?dict=bar&key=FOO%20%0A');
+
+http_get('/incr?dict=waka&key=foo&by=1');
+
+select undef, undef, undef, 1.1;
+
+$bar_state = read_state($t, 'bar.json');
+$waka_state = read_state($t, 'waka.json');
+
+is($bar_state->{'FOO \\n'}, undef, 'no bar.FOO \\n in state');
+is($waka_state->{foo}->{value}, '43', 'get waka.foo from state');
+
+http_get('/clear?dict=bar');
+
+select undef, undef, undef, 1.1;
+
+$bar_state = read_state($t, 'bar.json');
+
+is($bar_state->{waka}, undef, 'no bar.waka in state');
+
+###############################################################################
+
+sub decode_json {
+ my $json;
+ eval { $json = JSON::PP::decode_json(shift) };
+
+ if ($@) {
+ return "<failed to parse JSON>";
+ }
+
+ return $json;
+}
+
+sub read_state {
+ my ($self, $file) = @_;
+ my $json = $self->read_file($file);
+
+ if ($json) {
+ $json = decode_json($json);
+ }
+
+ return $json;
+}
+
+###############################################################################
diff --git a/nginx/t/stream_js_fetch.t b/nginx/t/stream_js_fetch.t
index 9a42ae29..cb87eec7 100644
--- a/nginx/t/stream_js_fetch.t
+++ b/nginx/t/stream_js_fetch.t
@@ -46,10 +46,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /validate {
js_content test.validate;
}
@@ -103,10 +99,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
function validate(r) {
r.return((r.requestText == 'QZ') ? 200 : 403);
}
@@ -166,7 +158,7 @@ $t->write_file('test.js', <<EOF);
}
export default {njs: test_njs, validate, preread_verify, filter_verify,
- access_ok, access_nok, engine};
+ access_ok, access_nok};
EOF
$t->try_run('no stream njs available');
diff --git a/nginx/t/stream_js_fetch_https.t b/nginx/t/stream_js_fetch_https.t
index 987a896a..f397ea70 100644
--- a/nginx/t/stream_js_fetch_https.t
+++ b/nginx/t/stream_js_fetch_https.t
@@ -47,10 +47,6 @@ http {
location /njs {
js_content test.njs;
}
-
- location /engine {
- js_content test.engine;
- }
}
server {
@@ -163,10 +159,6 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
function preread(s) {
s.on('upload', function (data, flags) {
if (data.startsWith('GO')) {
@@ -201,7 +193,7 @@ $t->write_file('test.js', <<EOF);
(r.status == 200) ? s.allow(): s.deny();
}
- export default {njs: test_njs, engine, preread, access_ok, access_nok};
+ export default {njs: test_njs, preread, access_ok, access_nok};
EOF
my $d = $t->testdir();
diff --git a/nginx/t/stream_js_fetch_init.t b/nginx/t/stream_js_fetch_init.t
index f48b9d5e..3980a9ee 100644
--- a/nginx/t/stream_js_fetch_init.t
+++ b/nginx/t/stream_js_fetch_init.t
@@ -58,10 +58,6 @@ http {
js_content test.njs;
}
- location /engine {
- js_content test.engine;
- }
-
location /success {
return 200;
}
@@ -77,17 +73,13 @@ $t->write_file('test.js', <<EOF);
r.return(200, njs.version);
}
- function engine(r) {
- r.return(200, njs.engine);
- }
-
async function access_ok(s) {
let reply = await ngx.fetch('http://127.0.0.1:$p/success');
(reply.status == 200) ? s.allow(): s.deny();
}
- export default {njs: test_njs, engine, access_ok};
+ export default {njs: test_njs, access_ok};
EOF
$t->try_run('no stream njs available');
diff --git a/nginx/t/stream_js_periodic_fetch.t b/nginx/t/stream_js_periodic_fetch.t
index 60599423..4ebec96e 100644
--- a/nginx/t/stream_js_periodic_fetch.t
+++ b/nginx/t/stream_js_periodic_fetch.t
@@ -67,10 +67,6 @@ http {
listen 127.0.0.1:8080;
server_name localhost;
- location /engine {
- js_content test.engine;
- }
-
location /fetch_ok {
return 200 'ok';
}
@@ -86,10 +82,6 @@ EOF
my $p1 = port(8080);
$t->write_file('test.js', <<EOF);
- function engine(r) {
- r.return(200, njs.engine);
- }
-
async function fetch() {
let reply = await ngx.fetch('http://127.0.0.1:$p1/fetch_ok');
let body = await reply.text();
@@ -142,7 +134,7 @@ $t->write_file('test.js', <<EOF);
});
}
- export default { engine, fetch, fetch_exception, test, multiple_fetches };
+ export default { fetch, fetch_exception, test, multiple_fetches };
EOF
$t->run_daemon(\&stream_daemon, port(8090));
diff --git a/nginx/t/stream_js_shared_dict.t b/nginx/t/stream_js_shared_dict.t
index 915cc40b..0435033d 100644
--- a/nginx/t/stream_js_shared_dict.t
+++ b/nginx/t/stream_js_shared_dict.t
@@ -43,10 +43,6 @@ http {
location / {
return 200;
}
-
- location /engine {
- js_content test.engine;
- }
}
}
@@ -75,10 +71,6 @@ EOF
$t->write_file('test.js', <<EOF);
import qs from 'querystring';
- function engine(r) {
- r.return(200, 'engine');
- }
-
function preread_verify(s) {
var collect = Buffer.from([]);
@@ -121,7 +113,7 @@ $t->write_file('test.js', <<EOF);
});
}
- export default { engine, preread_verify, control_access };
+ export default { preread_verify, control_access };
EOF
diff --git a/nginx/t/stream_js_shared_dict_state.t b/nginx/t/stream_js_shared_dict_state.t
new file mode 100644
index 00000000..c2edb63e
--- /dev/null
+++ b/nginx/t/stream_js_shared_dict_state.t
@@ -0,0 +1,137 @@
+#!/usr/bin/perl
+
+# (C) Dmitry Volyntsev
+# (C) Nginx, Inc.
+
+# Tests for js_shared_dict_zone directive, state= parameter.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+use Test::Nginx::Stream qw/ stream /;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+my $t = Test::Nginx->new()->has(qw/stream/)
+ ->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+daemon off;
+
+events {
+}
+
+stream {
+ %%TEST_GLOBALS_STREAM%%
+
+ js_import test.js;
+
+ js_shared_dict_zone zone=foo:32k state=foo.json;
+
+ server {
+ listen 127.0.0.1:8081;
+ js_preread test.preread_verify;
+ proxy_pass 127.0.0.1:8090;
+ }
+}
+
+EOF
+
+$t->write_file('foo.json', <<EOF);
+{"QZ":{"value":"1"},"QQ":{"value":"1"}}
+EOF
+
+$t->write_file('test.js', <<EOF);
+ function preread_verify(s) {
+ var collect = Buffer.from([]);
+
+ s.on('upstream', function (data, flags) {
+ collect = Buffer.concat([collect, data]);
+
+ if (collect.length >= 4 && collect.readUInt16BE(0) == 0xabcd) {
+ let id = collect.slice(2,4);
+
+ ngx.shared.foo.get(id) ? s.done(): s.deny();
+
+ } else if (collect.length) {
+ s.deny();
+ }
+ });
+ }
+
+ export default { preread_verify };
+
+EOF
+
+$t->try_run('no js_shared_dict_zone with state=');
+
+$t->plan(2);
+
+$t->run_daemon(\&stream_daemon, port(8090));
+$t->waitforsocket('127.0.0.1:' . port(8090));
+
+###############################################################################
+
+is(stream('127.0.0.1:' . port(8081))->io("\xAB\xCDQY##"), "",
+ 'access failed, QY is not in the shared dict');
+is(stream('127.0.0.1:' . port(8081))->io("\xAB\xCDQZ##"), "\xAB\xCDQZ##",
+ 'access granted');
+
+###############################################################################
+
+sub stream_daemon {
+ my $server = IO::Socket::INET->new(
+ Proto => 'tcp',
+ LocalAddr => '127.0.0.1:' . port(8090),
+ Listen => 5,
+ Reuse => 1
+ )
+ or die "Can't create listening socket: $!\n";
+
+ local $SIG{PIPE} = 'IGNORE';
+
+ while (my $client = $server->accept()) {
+ $client->autoflush(1);
+
+ log2c("(new connection $client)");
+
+ $client->sysread(my $buffer, 65536) or next;
+
+ log2i("$client $buffer");
+
+ log2o("$client $buffer");
+
+ $client->syswrite($buffer);
+
+ close $client;
+ }
+}
+
+sub log2i { Test::Nginx::log_core('|| <<', @_); }
+sub log2o { Test::Nginx::log_core('|| >>', @_); }
+sub log2c { Test::Nginx::log_core('||', @_); }
+
+sub get {
+ my ($url, %extra) = @_;
+
+ my $s = IO::Socket::INET->new(
+ Proto => 'tcp',
+ PeerAddr => '127.0.0.1:' . port(8082)
+ ) or die "Can't connect to nginx: $!\n";
+
+ return http_get($url, socket => $s);
+}
+
+###############################################################################