[njs] Modules: fixed incorrect config rejections introduced in d157f56.
noreply at nginx.com
noreply at nginx.com
Wed Aug 27 01:59:39 UTC 2025
details: https://github.com/nginx/njs/commit/2c93ca079f497b68ea1680d282f705c926cf7210
branches: master
commit: 2c93ca079f497b68ea1680d282f705c926cf7210
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Fri, 15 Aug 2025 17:28:47 -0700
description:
Modules: fixed incorrect config rejections introduced in d157f56.
d157f56 introduced configure time checks for js_set and js_periodic
directives. It turned out to be too strict.
The fix is to remove them completely as there is no way to track
variable usage context in configure time.
---
nginx/ngx_http_js_module.c | 66 +++++-------------------
nginx/ngx_stream_js_module.c | 64 +++++------------------
nginx/t/js_variables_location.t | 96 +++++++++++++++++++++++++++++++++++
nginx/t/stream_js_variables_server.t | 98 ++++++++++++++++++++++++++++++++++++
4 files changed, 218 insertions(+), 106 deletions(-)
diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c
index 578aec42..402c7382 100644
--- a/nginx/ngx_http_js_module.c
+++ b/nginx/ngx_http_js_module.c
@@ -40,9 +40,6 @@ typedef struct {
ngx_log_t log;
ngx_http_log_ctx_t log_ctx;
ngx_event_t event;
-
- u_char *file_name;
- ngx_uint_t line;
} ngx_js_periodic_t;
@@ -1540,6 +1537,9 @@ ngx_http_js_variable_set(ngx_http_request_t *r, ngx_http_variable_value_t *v,
}
if (rc == NGX_DECLINED) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "no \"js_import\" directives found for \"js_set\" handler"
+ " \"%V\" in the current scope", fname);
v->not_found = 1;
return NGX_OK;
}
@@ -4485,6 +4485,15 @@ ngx_http_js_periodic_handler(ngx_event_t *ev)
rc = ngx_http_js_init_vm(r, ngx_http_js_periodic_session_proto_id);
+ if (rc == NGX_DECLINED) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "no \"js_import\" directives found for \"js_periodic\""
+ " handler \"%V\" in the current scope",
+ &periodic->method);
+ ngx_http_js_periodic_destroy(r, periodic);
+ return;
+ }
+
if (rc != NGX_OK) {
ngx_http_js_periodic_destroy(r, periodic);
return;
@@ -7691,61 +7700,12 @@ ngx_http_js_init_conf_vm(ngx_conf_t *cf, ngx_js_loc_conf_t *conf)
static ngx_int_t
ngx_http_js_init(ngx_conf_t *cf)
{
- ngx_uint_t i, found_issue;
- ngx_js_set_t *data;
- ngx_hash_key_t *key;
- ngx_http_variable_t *v;
- ngx_js_periodic_t *periodic;
- ngx_js_loc_conf_t *jlcf;
- ngx_js_main_conf_t *jmcf;
- ngx_http_core_main_conf_t *cmcf;
-
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_js_header_filter;
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_js_body_filter;
- jmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_js_module);
- jlcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_js_module);
-
- if (jlcf->engine == NULL) {
- found_issue = 0;
-
- if (jmcf->periodics != NULL) {
- periodic = jmcf->periodics->elts;
-
- for (i = 0; i < jmcf->periodics->nelts; i++) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"js_import\" directives found for "
- "\"js_periodic\" \"%V\" in %s:%ui",
- &periodic[i].method, periodic[i].file_name,
- periodic[i].line);
- }
-
- found_issue = 1;
- }
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
- key = cmcf->variables_keys->keys.elts;
-
- for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
- v = key[i].value;
- if (v->get_handler == ngx_http_js_variable_set) {
- data = (ngx_js_set_t *) v->data;
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"js_import\" directives found for "
- "\"js_set\" \"$%V\" \"%V\" in %s:%ui", &v->name,
- &data->fname, data->file_name, data->line);
- found_issue = 1;
- }
- }
-
- if (found_issue) {
- return NGX_ERROR;
- }
- }
-
return NGX_OK;
}
@@ -7944,8 +7904,6 @@ invalid:
periodic->jitter = jitter;
periodic->worker_affinity = mask;
periodic->conf_ctx = cf->ctx;
- periodic->file_name = cf->conf_file->file.name.data;
- periodic->line = cf->conf_file->line;
return NGX_CONF_OK;
}
diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c
index 396a71e2..a3a85662 100644
--- a/nginx/ngx_stream_js_module.c
+++ b/nginx/ngx_stream_js_module.c
@@ -46,9 +46,6 @@ typedef struct {
ngx_log_t log;
ngx_event_t event;
-
- u_char *file_name;
- ngx_uint_t line;
} ngx_js_periodic_t;
@@ -1068,6 +1065,9 @@ ngx_stream_js_variable_set(ngx_stream_session_t *s,
}
if (rc == NGX_DECLINED) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "no \"js_import\" directives found for \"js_set\" handler"
+ " \"%V\" in the current scope", fname);
v->not_found = 1;
return NGX_OK;
}
@@ -3061,6 +3061,15 @@ ngx_stream_js_periodic_handler(ngx_event_t *ev)
rc = ngx_stream_js_init_vm(s, ngx_stream_js_periodic_session_proto_id);
+ if (rc == NGX_DECLINED) {
+ ngx_log_error(NGX_LOG_ERR, &periodic->log, 0,
+ "no \"js_import\" directives found for \"js_periodic\""
+ " handler \"%V\" in the current scope",
+ &periodic->method);
+ ngx_stream_js_periodic_destroy(s, periodic);
+ return;
+ }
+
if (rc != NGX_OK) {
ngx_stream_js_periodic_destroy(s, periodic);
return;
@@ -3395,8 +3404,6 @@ invalid:
periodic->jitter = jitter;
periodic->worker_affinity = mask;
periodic->conf_ctx = cf->ctx;
- periodic->file_name = cf->conf_file->file.name.data;
- periodic->line = cf->conf_file->line;
return NGX_CONF_OK;
}
@@ -3617,14 +3624,6 @@ ngx_stream_js_shared_dict_zone(ngx_conf_t *cf, ngx_command_t *cmd,
static ngx_int_t
ngx_stream_js_init(ngx_conf_t *cf)
{
- ngx_uint_t i;
- ngx_flag_t found_issue;
- ngx_js_set_t *data;
- ngx_hash_key_t *key;
- ngx_stream_variable_t *v;
- ngx_js_periodic_t *periodic;
- ngx_js_loc_conf_t *jlcf;
- ngx_js_main_conf_t *jmcf;
ngx_stream_handler_pt *h;
ngx_stream_core_main_conf_t *cmcf;
@@ -3647,45 +3646,6 @@ ngx_stream_js_init(ngx_conf_t *cf)
*h = ngx_stream_js_preread_handler;
- jmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_js_module);
- jlcf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_js_module);
-
- if (jlcf->engine == NULL) {
- found_issue = 0;
-
- if (jmcf->periodics != NULL) {
- periodic = jmcf->periodics->elts;
-
- for (i = 0; i < jmcf->periodics->nelts; i++) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"js_import\" directives found for "
- "\"js_periodic\" \"%V\" in %s:%ui",
- &periodic[i].method, periodic[i].file_name,
- periodic[i].line);
- }
-
- found_issue = 1;
- }
-
- key = cmcf->variables_keys->keys.elts;
-
- for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
- v = key[i].value;
- if (v->get_handler == ngx_stream_js_variable_set) {
- data = (ngx_js_set_t *) v->data;
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"js_import\" directives found for "
- "\"js_set\" \"$%V\" \"%V\" in %s:%ui", &v->name,
- &data->fname, data->file_name, data->line);
- found_issue = 1;
- }
- }
-
- if (found_issue) {
- return NGX_ERROR;
- }
- }
-
return NGX_OK;
}
diff --git a/nginx/t/js_variables_location.t b/nginx/t/js_variables_location.t
new file mode 100644
index 00000000..02bd85ef
--- /dev/null
+++ b/nginx/t/js_variables_location.t
@@ -0,0 +1,96 @@
+#!/usr/bin/perl
+
+# (C) Dmitry Volyntsev
+# (C) Nginx, Inc.
+
+# Tests for http njs module, setting nginx variables, location js_import.
+
+###############################################################################
+
+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 rewrite/)
+ ->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+daemon off;
+
+events {
+}
+
+http {
+ %%TEST_GLOBALS_HTTP%%
+
+ server {
+ listen 127.0.0.1:8080;
+ server_name localhost;
+
+ location /foo {
+ js_import main from foo.js;
+ js_set $test_var main.variable;
+
+ return 200 $test_var;
+ }
+
+ location /bar {
+ js_import main from bar.js;
+ js_set $test_var main.variable;
+
+ return 200 $test_var;
+ }
+
+ location /not_found {
+ return 200 "NOT_FOUND:$test_var";
+ }
+ }
+}
+
+EOF
+
+$t->write_file('foo.js', <<EOF);
+ function variable(r) {
+ return 'foo_var';
+ }
+
+ export default {variable};
+
+EOF
+
+$t->write_file('bar.js', <<EOF);
+ function variable(r) {
+ return 'bar_var';
+ }
+
+ export default {variable};
+
+EOF
+
+$t->try_run('no njs')->plan(4);
+
+###############################################################################
+
+like(http_get('/foo'), qr/foo_var/, 'foo var');
+like(http_get('/bar'), qr/bar_var/, 'bar var');
+like(http_get('/not_found'), qr/NOT_FOUND:$/, 'not found is empty');
+
+$t->stop();
+
+ok(index($t->read_file('error.log'),
+ 'no "js_import" directives found for "js_set" handler "main.variable" '
+ . 'in the current scope') > 0, 'log error for js_set without js_import');
+
+###############################################################################
diff --git a/nginx/t/stream_js_variables_server.t b/nginx/t/stream_js_variables_server.t
new file mode 100644
index 00000000..a7d53718
--- /dev/null
+++ b/nginx/t/stream_js_variables_server.t
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+
+# (C) Dmitry Volyntsev
+# (C) Nginx, Inc.
+
+# Tests for stream njs module, setting nginx variables, server js_import.
+
+###############################################################################
+
+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 stream_return/)
+ ->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+daemon off;
+
+events {
+}
+
+stream {
+ %%TEST_GLOBALS_STREAM%%
+
+ server {
+ listen 127.0.0.1:8081;
+
+ js_import main from foo.js;
+ js_set $test_var main.variable;
+
+ return $test_var;
+ }
+
+ server {
+ listen 127.0.0.1:8082;
+
+ js_import main from bar.js;
+ js_set $test_var main.variable;
+
+ return $test_var;
+ }
+
+ server {
+ listen 127.0.0.1:8083;
+
+ return "NOT_FOUND:$test_var";
+ }
+}
+
+EOF
+
+$t->write_file('foo.js', <<EOF);
+ function variable(s) {
+ return 'foo_var';
+ }
+
+ export default {variable};
+
+EOF
+
+$t->write_file('bar.js', <<EOF);
+ function variable(s) {
+ return 'bar_var';
+ }
+
+ export default {variable};
+
+EOF
+
+$t->try_run('no stream njs available')->plan(4);
+
+###############################################################################
+
+is(stream('127.0.0.1:' . port(8081))->read(), 'foo_var', 'foo var');
+is(stream('127.0.0.1:' . port(8082))->read(), 'bar_var', 'bar var');
+is(stream('127.0.0.1:' . port(8083))->read(), 'NOT_FOUND:', 'not found var');
+
+$t->stop();
+
+ok(index($t->read_file('error.log'),
+ 'no "js_import" directives found for "js_set" handler "main.variable" '
+ . 'in the current scope') > 0, 'log error for js_set without js_import');
+
+###############################################################################
More information about the nginx-devel
mailing list