[njs] HTTP: fixed r.send() with Buffer argument.

Dmitry Volyntsev xeioex at nginx.com
Tue Apr 9 05:48:01 UTC 2024


details:   https://hg.nginx.org/njs/rev/adaeb3c3f59a
branches:  
changeset: 2314:adaeb3c3f59a
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Apr 08 22:47:28 2024 -0700
description:
HTTP: fixed r.send() with Buffer argument.

Previously, only string value type was accepted.

This closes #701 issue on Github.

diffstat:

 nginx/ngx_http_js_module.c |  69 ++++++++++++++++++----------------------------
 nginx/t/js.t               |  22 +++++++++++++-
 src/njs.h                  |   2 -
 src/njs_vm.c               |  41 ---------------------------
 4 files changed, 47 insertions(+), 87 deletions(-)

diffs (208 lines):

diff -r 6fb1aca4eeaf -r adaeb3c3f59a nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c	Mon Apr 08 22:47:24 2024 -0700
+++ b/nginx/ngx_http_js_module.c	Mon Apr 08 22:47:28 2024 -0700
@@ -2199,10 +2199,8 @@ static njs_int_t
 ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    njs_int_t            ret;
     njs_str_t            s;
     ngx_buf_t           *b;
-    uintptr_t            next;
     ngx_uint_t           n;
     ngx_chain_t         *out, *cl, **ll;
     ngx_http_js_ctx_t   *ctx;
@@ -2226,47 +2224,34 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_v
     ll = &out;
 
     for (n = 1; n < nargs; n++) {
-        next = 0;
-
-        for ( ;; ) {
-            ret = njs_vm_value_string_copy(vm, &s, njs_argument(args, n),
-                                           &next);
-
-            if (ret == NJS_DECLINED) {
-                break;
-            }
-
-            if (ret == NJS_ERROR) {
-                return NJS_ERROR;
-            }
-
-            if (s.length == 0) {
-                continue;
-            }
-
-            /* TODO: njs_value_release(vm, value) in buf completion */
-
-            b = ngx_calloc_buf(r->pool);
-            if (b == NULL) {
-                return NJS_ERROR;
-            }
-
-            b->start = s.start;
-            b->pos = b->start;
-            b->end = s.start + s.length;
-            b->last = b->end;
-            b->memory = 1;
-
-            cl = ngx_alloc_chain_link(r->pool);
-            if (cl == NULL) {
-                return NJS_ERROR;
-            }
-
-            cl->buf = b;
-
-            *ll = cl;
-            ll = &cl->next;
+        if (ngx_js_string(vm, njs_argument(args, n), &s) != NGX_OK) {
+            return NJS_ERROR;
+        }
+
+        if (s.length == 0) {
+            continue;
+        }
+
+        b = ngx_calloc_buf(r->pool);
+        if (b == NULL) {
+            return NJS_ERROR;
         }
+
+        b->start = s.start;
+        b->pos = b->start;
+        b->end = s.start + s.length;
+        b->last = b->end;
+        b->memory = 1;
+
+        cl = ngx_alloc_chain_link(r->pool);
+        if (cl == NULL) {
+            return NJS_ERROR;
+        }
+
+        cl->buf = b;
+
+        *ll = cl;
+        ll = &cl->next;
     }
 
     *ll = NULL;
diff -r 6fb1aca4eeaf -r adaeb3c3f59a nginx/t/js.t
--- a/nginx/t/js.t	Mon Apr 08 22:47:24 2024 -0700
+++ b/nginx/t/js.t	Mon Apr 08 22:47:28 2024 -0700
@@ -112,6 +112,10 @@ http {
             js_content test.send;
         }
 
+        location /send_buffer {
+            js_content test.send_buffer;
+        }
+
         location /return_method {
             js_content test.return_method;
         }
@@ -219,6 +223,13 @@ EOF
         r.finish();
     }
 
+    function send_buffer(r) {
+        r.status = 200;
+        r.sendHeader();
+        r.send(Buffer.from("send_buffer"));
+        r.finish();
+    }
+
     function return_method(r) {
         r.return(Number(r.args.c), r.args.t);
     }
@@ -265,11 +276,11 @@ EOF
                     variable, global_obj, status, request_body, internal,
                     request_body_cache, send, return_method, sub_internal,
                     type, log, buffer_variable, except, content_except,
-                    content_empty};
+                    content_empty, send_buffer};
 
 EOF
 
-$t->try_run('no njs available')->plan(28);
+$t->try_run('no njs available')->plan(29);
 
 ###############################################################################
 
@@ -289,6 +300,13 @@ like(http_post_big('/body'), qr/200.*^(1
 like(http_get('/send?foo=12345&n=11&foo-2=bar&ndd=&foo-3=z'),
 	qr/n=foo, v=12 n=foo-2, v=ba n=foo-3, v=z/, 'r.send');
 
+TODO: {
+local $TODO = 'not yet' unless has_version('0.8.4');
+
+like(http_get('/send_buffer'), qr/send_buffer/, 'r.send accepts buffer');
+
+}
+
 like(http_get('/return_method?c=200'), qr/200 OK.*\x0d\x0a?\x0d\x0a?$/s,
 	'return code');
 like(http_get('/return_method?c=200&t=SEE-THIS'), qr/200 OK.*^SEE-THIS$/ms,
diff -r 6fb1aca4eeaf -r adaeb3c3f59a src/njs.h
--- a/src/njs.h	Mon Apr 08 22:47:24 2024 -0700
+++ b/src/njs.h	Mon Apr 08 22:47:28 2024 -0700
@@ -412,8 +412,6 @@ NJS_EXPORT njs_int_t njs_vm_value_string
     njs_value_t *value, const u_char *start, uint32_t size);
 NJS_EXPORT njs_int_t njs_vm_value_string_create_chb(njs_vm_t *vm,
     njs_value_t *value, njs_chb_t *chain);
-NJS_EXPORT njs_int_t njs_vm_value_string_copy(njs_vm_t *vm, njs_str_t *retval,
-    njs_value_t *value, uintptr_t *next);
 NJS_EXPORT njs_int_t njs_vm_string_compare(const njs_value_t *v1,
     const njs_value_t *v2);
 
diff -r 6fb1aca4eeaf -r adaeb3c3f59a src/njs_vm.c
--- a/src/njs_vm.c	Mon Apr 08 22:47:24 2024 -0700
+++ b/src/njs_vm.c	Mon Apr 08 22:47:28 2024 -0700
@@ -1662,47 +1662,6 @@ njs_vm_string_compare(const njs_value_t 
 }
 
 
-njs_int_t
-njs_vm_value_string_copy(njs_vm_t *vm, njs_str_t *retval,
-    njs_value_t *value, uintptr_t *next)
-{
-    uintptr_t    n;
-    njs_array_t  *array;
-
-    switch (value->type) {
-
-    case NJS_STRING:
-        if (*next != 0) {
-            return NJS_DECLINED;
-        }
-
-        *next = 1;
-        break;
-
-    case NJS_ARRAY:
-        array = njs_array(value);
-
-        do {
-            n = (*next)++;
-
-            if (n == array->length) {
-                return NJS_DECLINED;
-            }
-
-            value = &array->start[n];
-
-        } while (!njs_is_valid(value));
-
-        break;
-
-    default:
-        return NJS_ERROR;
-    }
-
-    return njs_vm_value_to_string(vm, retval, value);
-}
-
-
 void *
 njs_lvlhsh_alloc(void *data, size_t size)
 {


More information about the nginx-devel mailing list