[njs] HTTP: introduced detached subrequest mode in r.subrequest().

Dmitry Volyntsev xeioex at nginx.com
Mon Mar 2 18:12:07 UTC 2020


details:   https://hg.nginx.org/njs/rev/a95c44303c1b
branches:  
changeset: 1344:a95c44303c1b
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Mar 02 21:11:37 2020 +0300
description:
HTTP: introduced detached subrequest mode in r.subrequest().

If "options.detached" boolean flag is true the created subrequest is
a detached subrequest. Responses to detached subrequest are ignored.
Unlike ordinary subrequests, a detached subrequest can be created
inside a variable handler. The detached flag and callback argument are
mutually exclusive.

diffstat:

 nginx/ngx_http_js_module.c |  58 +++++++++++++++++++++++++++++++--------------
 1 files changed, 40 insertions(+), 18 deletions(-)

diffs (119 lines):

diff -r 36208bd2362f -r a95c44303c1b nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c	Fri Feb 28 19:39:13 2020 +0300
+++ b/nginx/ngx_http_js_module.c	Mon Mar 02 21:11:37 2020 +0300
@@ -1786,7 +1786,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
 {
     ngx_int_t                 rc, promise;
     njs_str_t                 uri_arg, args_arg, method_name, body_arg;
-    ngx_uint_t                method, methods_max, has_body;
+    ngx_uint_t                method, methods_max, has_body, detached;
     njs_value_t              *value, *arg, *options;
     njs_function_t           *callback;
     ngx_http_js_ctx_t        *ctx;
@@ -1817,6 +1817,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
     static const njs_str_t args_key   = njs_str("args");
     static const njs_str_t method_key = njs_str("method");
     static const njs_str_t body_key = njs_str("body");
+    static const njs_str_t detached_key = njs_str("detached");
 
     r = njs_vm_external(vm, njs_arg(args, nargs, 0));
     if (njs_slow_path(r == NULL)) {
@@ -1852,6 +1853,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
     args_arg.start = NULL;
     has_body = 0;
     promise = 0;
+    detached = 0;
 
     arg = njs_arg(args, nargs, 2);
 
@@ -1881,6 +1883,11 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
             }
         }
 
+        value = njs_vm_object_prop(vm, options, &detached_key);
+        if (value != NULL) {
+            detached = njs_value_bool(value);
+        }
+
         value = njs_vm_object_prop(vm, options, &method_key);
         if (value != NULL) {
             if (ngx_http_js_string(vm, value, &method_name) != NJS_OK) {
@@ -1924,7 +1931,12 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
         }
     }
 
-    if (callback == NULL) {
+    if (detached && callback != NULL) {
+        njs_vm_error(vm, "detached flag and callback are mutually exclusive");
+        return NJS_ERROR;
+    }
+
+    if (!detached && callback == NULL) {
         callback = njs_vm_function_alloc(vm, ngx_http_js_promise_trampoline);
         if (callback == NULL) {
             goto memory_error;
@@ -1948,7 +1960,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
         sr->method_name.data = method_name.start;
     }
 
-    sr->header_only = (sr->method == NGX_HTTP_HEAD);
+    sr->header_only = (sr->method == NGX_HTTP_HEAD) || (callback == NULL);
 
     if (has_body) {
         rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
@@ -1993,6 +2005,8 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
                                      njs_value_arg(&ctx->promise_callbacks));
     }
 
+    njs_value_undefined_set(njs_vm_retval(vm));
+
     return NJS_OK;
 
 memory_error:
@@ -2015,23 +2029,31 @@ ngx_http_js_subrequest(ngx_http_request_
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
 
-    flags = NGX_HTTP_SUBREQUEST_BACKGROUND | NGX_HTTP_SUBREQUEST_IN_MEMORY;
-
-    ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
-    if (ps == NULL) {
-        njs_vm_error(ctx->vm, "internal error");
-        return NJS_ERROR;
+    flags = NGX_HTTP_SUBREQUEST_BACKGROUND;
+
+    if (callback != NULL) {
+        ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
+        if (ps == NULL) {
+            njs_vm_error(ctx->vm, "internal error");
+            return NJS_ERROR;
+        }
+
+        vm_event = njs_vm_add_event(ctx->vm, callback, 1, NULL, NULL);
+        if (vm_event == NULL) {
+            njs_vm_error(ctx->vm, "internal error");
+            return NJS_ERROR;
+        }
+
+        ps->handler = ngx_http_js_subrequest_done;
+        ps->data = vm_event;
+
+        flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY;
+
+    } else {
+        ps = NULL;
+        vm_event = NULL;
     }
 
-    vm_event = njs_vm_add_event(ctx->vm, callback, 1, NULL, NULL);
-    if (vm_event == NULL) {
-        njs_vm_error(ctx->vm, "internal error");
-        return NJS_ERROR;
-    }
-
-    ps->handler = ngx_http_js_subrequest_done;
-    ps->data = vm_event;
-
     uri.len = uri_arg->length;
     uri.data = uri_arg->start;
 


More information about the nginx-devel mailing list