[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