[njs] Reverted changes introduced in 7eaaa7d57636 (not released) back.
Dmitry Volyntsev
xeioex at nginx.com
Wed Feb 7 04:28:43 UTC 2024
details: https://hg.nginx.org/njs/rev/25e548de3d61
branches:
changeset: 2280:25e548de3d61
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Feb 06 19:32:08 2024 -0800
description:
Reverted changes introduced in 7eaaa7d57636 (not released) back.
Relative importing is again supported.
diffstat:
external/njs_shell.c | 101 ++++++++++++++++++++++++++++++++++++-
nginx/ngx_js.c | 88 ++++++++++++++++++++++++++++++++-
nginx/ngx_js.h | 1 +
nginx/t/js_import_relative.t | 100 +++++++++++++++++++++++++++++++++++++
test/js/import_relative_path.t.js | 9 +++
test/js/module/libs/hash.js | 1 +
test/js/module/sub/sub3.js | 1 +
7 files changed, 296 insertions(+), 5 deletions(-)
diffs (468 lines):
diff -r 673d78618fc9 -r 25e548de3d61 external/njs_shell.c
--- a/external/njs_shell.c Wed Jan 31 17:06:58 2024 -0800
+++ b/external/njs_shell.c Tue Feb 06 19:32:08 2024 -0800
@@ -115,6 +115,8 @@ typedef struct {
njs_queue_t labels;
+ njs_str_t cwd;
+
njs_arr_t *rejected_promises;
njs_bool_t suppress_stdout;
@@ -693,6 +695,8 @@ njs_console_init(njs_vm_t *vm, njs_conso
njs_queue_init(&console->posted_events);
njs_queue_init(&console->labels);
+ njs_memzero(&console->cwd, sizeof(njs_str_t));
+
console->rejected_promises = NULL;
console->completion.completions = njs_vm_completions(vm, NULL);
@@ -869,7 +873,7 @@ njs_module_path(const njs_str_t *dir, nj
if (dir != NULL) {
length += dir->length;
- if (length == 0) {
+ if (length == 0 || dir->length == 0) {
return NJS_DECLINED;
}
@@ -915,7 +919,8 @@ njs_module_path(const njs_str_t *dir, nj
static njs_int_t
-njs_module_lookup(njs_opts_t *opts, njs_module_info_t *info)
+njs_module_lookup(njs_opts_t *opts, const njs_str_t *cwd,
+ njs_module_info_t *info)
{
njs_int_t ret;
njs_str_t *path;
@@ -925,6 +930,12 @@ njs_module_lookup(njs_opts_t *opts, njs_
return njs_module_path(NULL, info);
}
+ ret = njs_module_path(cwd, info);
+
+ if (ret != NJS_DECLINED) {
+ return ret;
+ }
+
path = opts->paths;
for (i = 0; i < opts->n_paths; i++) {
@@ -980,23 +991,86 @@ fail:
}
+static void
+njs_file_dirname(const njs_str_t *path, njs_str_t *name)
+{
+ const u_char *p, *end;
+
+ if (path->length == 0) {
+ goto current_dir;
+ }
+
+ p = path->start + path->length - 1;
+
+ /* Stripping basename. */
+
+ while (p >= path->start && *p != '/') { p--; }
+
+ end = p + 1;
+
+ if (end == path->start) {
+ goto current_dir;
+ }
+
+ /* Stripping trailing slashes. */
+
+ while (p >= path->start && *p == '/') { p--; }
+
+ p++;
+
+ if (p == path->start) {
+ p = end;
+ }
+
+ name->start = path->start;
+ name->length = p - path->start;
+
+ return;
+
+current_dir:
+
+ *name = njs_str_value(".");
+}
+
+
+static njs_int_t
+njs_console_set_cwd(njs_vm_t *vm, njs_console_t *console, njs_str_t *file)
+{
+ njs_str_t cwd;
+
+ njs_file_dirname(file, &cwd);
+
+ console->cwd.start = njs_mp_alloc(njs_vm_memory_pool(vm), cwd.length);
+ if (njs_slow_path(console->cwd.start == NULL)) {
+ return NJS_ERROR;
+ }
+
+ memcpy(console->cwd.start, cwd.start, cwd.length);
+ console->cwd.length = cwd.length;
+
+ return NJS_OK;
+}
+
+
static njs_mod_t *
njs_module_loader(njs_vm_t *vm, njs_external_ptr_t external, njs_str_t *name)
{
u_char *start;
njs_int_t ret;
- njs_str_t text;
+ njs_str_t text, prev_cwd;
njs_mod_t *module;
njs_opts_t *opts;
+ njs_console_t *console;
njs_module_info_t info;
opts = external;
+ console = njs_vm_external_ptr(vm);
njs_memzero(&info, sizeof(njs_module_info_t));
info.name = *name;
- ret = njs_module_lookup(opts, &info);
+ ret = njs_module_lookup(opts, &console->cwd, &info);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
@@ -1010,11 +1084,23 @@ njs_module_loader(njs_vm_t *vm, njs_exte
return NULL;
}
+ prev_cwd = console->cwd;
+
+ ret = njs_console_set_cwd(vm, console, &info.file);
+ if (njs_slow_path(ret != NJS_OK)) {
+ njs_vm_internal_error(vm, "while setting cwd for \"%V\" module",
+ &info.file);
+ return NULL;
+ }
+
start = text.start;
module = njs_vm_compile_module(vm, &info.file, &start,
&text.start[text.length]);
+ njs_mp_free(njs_vm_memory_pool(vm), console->cwd.start);
+ console->cwd = prev_cwd;
+
njs_mp_free(njs_vm_memory_pool(vm), text.start);
return module;
@@ -1025,6 +1111,7 @@ static njs_vm_t *
njs_create_vm(njs_opts_t *opts)
{
njs_vm_t *vm;
+ njs_int_t ret;
njs_vm_opt_t vm_options;
njs_vm_opt_init(&vm_options);
@@ -1068,6 +1155,12 @@ njs_create_vm(njs_opts_t *opts)
njs_vm_external_ptr(vm));
}
+ ret = njs_console_set_cwd(vm, njs_vm_external_ptr(vm), &vm_options.file);
+ if (njs_slow_path(ret != NJS_OK)) {
+ njs_stderror("failed to set cwd\n");
+ return NULL;
+ }
+
njs_vm_set_module_loader(vm, njs_module_loader, opts);
return vm;
diff -r 673d78618fc9 -r 25e548de3d61 nginx/ngx_js.c
--- a/nginx/ngx_js.c Wed Jan 31 17:06:58 2024 -0800
+++ b/nginx/ngx_js.c Tue Feb 06 19:32:08 2024 -0800
@@ -1743,7 +1743,7 @@ ngx_js_module_path(const ngx_str_t *dir,
if (dir != NULL) {
length += dir->len;
- if (length == 0) {
+ if (length == 0 || dir->len == 0) {
return NJS_DECLINED;
}
@@ -1799,6 +1799,12 @@ ngx_js_module_lookup(ngx_js_loc_conf_t *
return ngx_js_module_path(NULL, info);
}
+ ret = ngx_js_module_path(&conf->cwd, info);
+
+ if (ret != NJS_DECLINED) {
+ return ret;
+ }
+
ret = ngx_js_module_path((const ngx_str_t *) &ngx_cycle->conf_prefix, info);
if (ret != NJS_DECLINED) {
@@ -1864,12 +1870,74 @@ fail:
}
+static void
+ngx_js_file_dirname(const njs_str_t *path, ngx_str_t *name)
+{
+ const u_char *p, *end;
+
+ if (path->length == 0) {
+ goto current_dir;
+ }
+
+ p = path->start + path->length - 1;
+
+ /* Stripping basename. */
+
+ while (p >= path->start && *p != '/') { p--; }
+
+ end = p + 1;
+
+ if (end == path->start) {
+ goto current_dir;
+ }
+
+ /* Stripping trailing slashes. */
+
+ while (p >= path->start && *p == '/') { p--; }
+
+ p++;
+
+ if (p == path->start) {
+ p = end;
+ }
+
+ name->data = path->start;
+ name->len = p - path->start;
+
+ return;
+
+current_dir:
+
+ ngx_str_set(name, ".");
+}
+
+
+static njs_int_t
+ngx_js_set_cwd(njs_vm_t *vm, ngx_js_loc_conf_t *conf, njs_str_t *path)
+{
+ ngx_str_t cwd;
+
+ ngx_js_file_dirname(path, &cwd);
+
+ conf->cwd.data = njs_mp_alloc(njs_vm_memory_pool(vm), cwd.len);
+ if (conf->cwd.data == NULL) {
+ return NJS_ERROR;
+ }
+
+ memcpy(conf->cwd.data, cwd.data, cwd.len);
+ conf->cwd.len = cwd.len;
+
+ return NJS_OK;
+}
+
+
static njs_mod_t *
ngx_js_module_loader(njs_vm_t *vm, njs_external_ptr_t external, njs_str_t *name)
{
u_char *start;
njs_int_t ret;
njs_str_t text;
+ ngx_str_t prev_cwd;
njs_mod_t *module;
ngx_js_loc_conf_t *conf;
njs_module_info_t info;
@@ -1894,11 +1962,23 @@ ngx_js_module_loader(njs_vm_t *vm, njs_e
return NULL;
}
+ prev_cwd = conf->cwd;
+
+ ret = ngx_js_set_cwd(vm, conf, &info.file);
+ if (ret != NJS_OK) {
+ njs_vm_internal_error(vm, "while setting cwd for \"%V\" module",
+ &info.file);
+ return NULL;
+ }
+
start = text.start;
module = njs_vm_compile_module(vm, &info.file, &start,
&text.start[text.length]);
+ njs_mp_free(njs_vm_memory_pool(vm), conf->cwd.data);
+ conf->cwd = prev_cwd;
+
njs_mp_free(njs_vm_memory_pool(vm), text.start);
return module;
@@ -1985,6 +2065,12 @@ ngx_js_init_conf_vm(ngx_conf_t *cf, ngx_
njs_vm_set_rejection_tracker(conf->vm, ngx_js_rejection_tracker,
NULL);
+ rc = ngx_js_set_cwd(conf->vm, conf, &options->file);
+ if (rc != NJS_OK) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "failed to set cwd");
+ return NGX_ERROR;
+ }
+
njs_vm_set_module_loader(conf->vm, ngx_js_module_loader, conf);
if (conf->paths != NGX_CONF_UNSET_PTR) {
diff -r 673d78618fc9 -r 25e548de3d61 nginx/ngx_js.h
--- a/nginx/ngx_js.h Wed Jan 31 17:06:58 2024 -0800
+++ b/nginx/ngx_js.h Tue Feb 06 19:32:08 2024 -0800
@@ -83,6 +83,7 @@ struct ngx_js_event_s {
#define _NGX_JS_COMMON_LOC_CONF \
njs_vm_t *vm; \
+ ngx_str_t cwd; \
ngx_array_t *imports; \
ngx_array_t *paths; \
\
diff -r 673d78618fc9 -r 25e548de3d61 nginx/t/js_import_relative.t
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nginx/t/js_import_relative.t Tue Feb 06 19:32:08 2024 -0800
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+# (C) Dmitry Volyntsev
+# (c) Nginx, Inc.
+
+# Tests for http njs module, js_import directive, importing relative paths.
+
+###############################################################################
+
+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 main from lib/main.js;
+
+ server {
+ listen 127.0.0.1:8080;
+ server_name localhost;
+
+ location /local {
+ js_content main.test_local;
+ }
+
+ location /top {
+ js_content main.test_top;
+ }
+ }
+}
+
+EOF
+
+my $d = $t->testdir();
+
+mkdir("$d/lib");
+mkdir("$d/lib/sub");
+
+$t->write_file('lib/main.js', <<EOF);
+ import sub from './sub/foo.js';
+ import local from './foo.js';
+ import top from '../foo.js';
+
+ function test_local(r) {
+ r.return(200, local.test);
+ }
+
+ function test_top(r) {
+ r.return(200, top.test);
+ }
+
+ export default {test_local, test_top};
+
+EOF
+
+$t->write_file('lib/sub/foo.js', <<EOF);
+ export default {test: "SUB"};
+
+EOF
+
+$t->write_file('lib/foo.js', <<EOF);
+ export default {test: "LOCAL"};
+
+EOF
+
+$t->write_file('foo.js', <<EOF);
+ export default {test: "TOP"};
+
+EOF
+
+$t->try_run('no njs available')->plan(2);
+
+###############################################################################
+
+like(http_get('/local'), qr/LOCAL/s, 'local relative import');
+like(http_get('/top'), qr/TOP/s, 'local relative import 2');
+
+###############################################################################
diff -r 673d78618fc9 -r 25e548de3d61 test/js/import_relative_path.t.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/import_relative_path.t.js Tue Feb 06 19:32:08 2024 -0800
@@ -0,0 +1,9 @@
+/*---
+includes: []
+flags: []
+paths: [test/js/module/]
+---*/
+
+import hash from 'libs/hash.js';
+
+assert.sameValue(hash.name, "libs.name");
diff -r 673d78618fc9 -r 25e548de3d61 test/js/module/libs/hash.js
--- a/test/js/module/libs/hash.js Wed Jan 31 17:06:58 2024 -0800
+++ b/test/js/module/libs/hash.js Tue Feb 06 19:32:08 2024 -0800
@@ -4,6 +4,7 @@ function hash() {
return v;
}
+import sub from 'sub/sub3.js';
import name from 'name.js';
import crypto from 'crypto';
diff -r 673d78618fc9 -r 25e548de3d61 test/js/module/sub/sub3.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/module/sub/sub3.js Tue Feb 06 19:32:08 2024 -0800
@@ -0,0 +1,1 @@
+export default { name: "SUB3" };
More information about the nginx-devel
mailing list