From 836b27f618ccf81c53551d3de164bc7b33e924ad Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 10 Aug 2022 20:04:40 -0700 Subject: [PATCH] Stream: improved flags argument for s.on() callback methods. --- nginx/ngx_js.c | 25 +++++++++++++++ nginx/ngx_js.h | 4 +++ nginx/ngx_stream_js_module.c | 62 ++++++++++++++++++++++++++---------- src/njs.h | 1 + src/njs_extern.c | 2 +- 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 903d51f2..19a5b74b 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -262,6 +262,31 @@ ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, } +njs_int_t +ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) +{ + uintptr_t data; + + data = (uintptr_t) njs_vm_external(vm, NJS_PROTO_ID_ANY, value); + if (data == 0) { + njs_value_undefined_set(retval); + return NJS_DECLINED; + } + + data = data & (uintptr_t) njs_vm_prop_magic32(prop); + + switch (njs_vm_prop_magic16(prop)) { + case NGX_JS_BOOLEAN: + default: + njs_value_boolean_set(retval, data); + break; + } + + return NJS_OK; +} + + njs_int_t ngx_js_ext_boolean(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) diff --git a/nginx/ngx_js.h b/nginx/ngx_js.h index 64091961..93870bc5 100644 --- a/nginx/ngx_js.h +++ b/nginx/ngx_js.h @@ -19,6 +19,8 @@ #define NGX_JS_DEPRECATED 1 #define NGX_JS_STRING 2 #define NGX_JS_BUFFER 4 +#define NGX_JS_BOOLEAN 8 +#define NGX_JS_NUMBER 16 #define ngx_js_buffer_type(btype) ((btype) & ~NGX_JS_DEPRECATED) @@ -80,6 +82,8 @@ njs_int_t ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); njs_int_t ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); +njs_int_t ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval); njs_int_t ngx_js_ext_boolean(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c index 5f092dd6..902b542e 100644 --- a/nginx/ngx_stream_js_module.c +++ b/nginx/ngx_stream_js_module.c @@ -493,6 +493,30 @@ static njs_external_t ngx_stream_js_ext_session[] = { }; +static njs_external_t ngx_stream_js_ext_session_flags[] = { + + { + .flags = NJS_EXTERN_PROPERTY | NJS_EXTERN_SYMBOL, + .name.symbol = NJS_SYMBOL_TO_STRING_TAG, + .u.property = { + .value = "Stream Flags", + } + }, + + { + .flags = NJS_EXTERN_PROPERTY, + .name.string = njs_str("last"), + .enumerable = 1, + .u.property = { + .handler = ngx_js_ext_flags, + .magic16 = NGX_JS_BOOLEAN, + .magic32 = 0x00000001, + } + }, + +}; + + static njs_vm_ops_t ngx_stream_js_ops = { ngx_stream_js_set_timer, ngx_stream_js_clear_timer, @@ -525,6 +549,7 @@ static ngx_stream_filter_pt ngx_stream_next_filter; static njs_int_t ngx_stream_js_session_proto_id; +static njs_int_t ngx_stream_js_session_flags_proto_id; static ngx_int_t @@ -923,14 +948,12 @@ static njs_int_t ngx_stream_js_run_event(ngx_stream_session_t *s, ngx_stream_js_ctx_t *ctx, ngx_stream_js_ev_t *event) { - size_t len; - u_char *p; - njs_int_t ret; - ngx_buf_t *b; - ngx_connection_t *c; - njs_opaque_value_t last_key, last; - - static const njs_str_t last_str = njs_str("last"); + size_t len; + u_char *p; + njs_int_t ret; + ngx_buf_t *b; + uintptr_t flags; + ngx_connection_t *c; if (event->ev == NULL) { return NJS_OK; @@ -957,16 +980,12 @@ ngx_stream_js_run_event(ngx_stream_session_t *s, ngx_stream_js_ctx_t *ctx, return ret; } - njs_vm_value_string_set(ctx->vm, njs_value_arg(&last_key), last_str.start, - last_str.length); - - njs_value_boolean_set(njs_value_arg(&last), b && b->last_buf); + flags = b && b->last_buf; - ret = njs_vm_object_alloc(ctx->vm, njs_value_arg(&ctx->args[2]), - njs_value_arg(&last_key), - njs_value_arg(&last), NULL); + ret = njs_vm_external_create(ctx->vm, njs_value_arg(&ctx->args[2]), + ngx_stream_js_session_flags_proto_id, (void *) flags, 0); if (ret != NJS_OK) { - return ret; + return NGX_ERROR; } njs_vm_post_event(ctx->vm, event->ev, njs_value_arg(&ctx->args[1]), 2); @@ -1787,7 +1806,16 @@ ngx_stream_js_init_conf_vm(ngx_conf_t *cf, ngx_stream_js_srv_conf_t *conf) njs_nitems(ngx_stream_js_ext_session)); if (ngx_stream_js_session_proto_id < 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "failed to add js request proto"); + "failed to add js session proto"); + return NGX_ERROR; + } + + ngx_stream_js_session_flags_proto_id = njs_vm_external_prototype(conf->vm, + ngx_stream_js_ext_session_flags, + njs_nitems(ngx_stream_js_ext_session_flags)); + if (ngx_stream_js_session_flags_proto_id < 0) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "failed to add js session flags proto"); return NGX_ERROR; } diff --git a/src/njs.h b/src/njs.h index 0b9c5513..dab26023 100644 --- a/src/njs.h +++ b/src/njs.h @@ -155,6 +155,7 @@ struct njs_external_s { struct { const char value[15]; /* NJS_STRING_SHORT + 1. */ njs_prop_handler_t handler; + uint16_t magic16; uint32_t magic32; } property; diff --git a/src/njs_extern.c b/src/njs_extern.c index fdccf660..e9e8ac2c 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -92,7 +92,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, prop->type = NJS_PROPERTY_HANDLER; prop->value.type = NJS_INVALID; prop->value.data.truth = 1; - prop->value.data.magic16 = 0; + prop->value.data.magic16 = external->u.property.magic16; prop->value.data.magic32 = external->u.property.magic32; prop->value.data.u.prop_handler = external->u.property.handler; -- 2.47.3