details: https://github.com/nginx/njs/commit/8553c2a6a2cb0c7bdd111f5b1799aaba8004eba6 branches: master commit: 8553c2a6a2cb0c7bdd111f5b1799aaba8004eba6 user: Thomas P. <t...@users.noreply.github.com> date: Tue, 30 Jul 2024 18:03:34 +0200 description: HTTP: expose capture group variables.
--- nginx/ngx_http_js_module.c | 29 +++++++++++- nginx/t/js_capture_variables.t | 101 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index 86d907df..824b647c 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -2954,10 +2954,10 @@ static njs_int_t ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop, ngx_http_request_t *r, njs_value_t *setval, njs_value_t *retval) { - njs_int_t rc; + njs_int_t rc, is_capture, start, length; njs_str_t val, s; ngx_str_t name; - ngx_uint_t key; + ngx_uint_t i, key; ngx_http_variable_t *v; ngx_http_core_main_conf_t *cmcf; ngx_http_variable_value_t *vv; @@ -2972,6 +2972,31 @@ ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop, name.len = val.length; if (setval == NULL) { + is_capture = 1; + for (i = 0; i < name.len; i++) { + if (name.data[i] < '0' || name.data[i] > '9') { + is_capture = 0; + break; + } + } + + if (is_capture) { + key = ngx_atoi(name.data, name.len) * 2; + if (r->captures == NULL || r->captures_data == NULL + || r->ncaptures <= key) + { + njs_value_undefined_set(retval); + return NJS_DECLINED; + } + + start = r->captures[key]; + length = r->captures[key + 1] - start; + + return ngx_js_prop(vm, njs_vm_prop_magic32(prop), retval, + &r->captures_data[start], length); + } + + /* Lookup the variable in nginx variables */ key = ngx_hash_strlow(name.data, name.data, name.len); vv = ngx_http_get_variable(r, &name, key); diff --git a/nginx/t/js_capture_variables.t b/nginx/t/js_capture_variables.t new file mode 100644 index 00000000..ccc977ee --- /dev/null +++ b/nginx/t/js_capture_variables.t @@ -0,0 +1,101 @@ +#!/usr/bin/perl + +# (C) Thomas P. + +# Tests for http njs module, reading location capture variables. + +############################################################################### + +use warnings; +use strict; + +use Test::More; + +BEGIN { use FindBin; chdir($FindBin::Bin); } + +use lib 'lib'; +use Test::Nginx; + +############################################################################### + +select STDERR; $| = 1; +select STDOUT; $| = 1; + +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; + + server { + listen 127.0.0.1:8080; + server_name localhost; + + location /njs { + js_content test.njs; + } + + location ~ /(.+)/(.+) { + js_content test.variables; + } + } +} + +EOF + +$t->write_file('test.js', <<EOF); + function variables(r) { + return r.return(200, `"\${r.variables[r.args.index]}"`); + } + + function test_njs(r) { + r.return(200, njs.version); + } + + export default {njs:test_njs, variables}; + +EOF + +$t->try_run('no njs capture variables')->plan(4); + +############################################################################### + +TODO: { +local $TODO = 'not yet' unless has_version('0.8.6'); + +like(http_get('/test/hello?index=0'), qr/"\/test\/hello"/, 'global capture'); +like(http_get('/test/hello?index=1'), qr/"test"/, 'local capture 1'); +like(http_get('/test/hello?index=2'), qr/"hello"/, 'local capture 2'); +like(http_get('/test/hello?index=3'), qr/"undefined"/, 'undefined capture'); + +} + +############################################################################### + +sub has_version { + my $need = shift; + + http_get('/njs') =~ /^([.0-9]+)$/m; + + my @v = split(/\./, $1); + my ($n, $v); + + for $n (split(/\./, $need)) { + $v = shift @v || 0; + return 0 if $n > $v; + return 1 if $v > $n; + } + + return 1; +} + +############################################################################### _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel