[nginx] Script: changed ngx_http_script_run() to avoid flushing ...

Maxim Dounin mdounin at mdounin.ru
Sat Jul 25 00:04:55 UTC 2026


details:   http://freenginx.org/hg/nginx/rev/5bfb1aa8b443
branches:  
changeset: 9577:5bfb1aa8b443
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Sun Jul 19 00:26:15 2026 +0300
description:
Script: changed ngx_http_script_run() to avoid flushing all vars.

Previously, ngx_http_script_run() flushed all non-cacheable variables.
Notably, this made it impossible to ensure that all variables have
cached values.  With this change, ngx_http_script_run() instead uses an
additional length calculation loop without e.flushed set to ensure all
relevant non-cacheable variables are flushed, and also looks up all the
values.

This approach might not be as effective as a separate list of variables
to flush, such as used by ngx_http_complex_value(), yet it is expected
to be better than flush of all variables as used previously.  And this
resolves issues observed with non-cacheable variables and variables with
side effects when using ngx_http_script_run(), such as in the following
configuration:

    map $uri $map {
        ~(?<capture>.*) $capture;
    }

    root html/$capture/$map;

Similar changes were made in the stream module.

diffstat:

 src/http/ngx_http_script.c     |  25 ++++++++++---------------
 src/stream/ngx_stream_script.c |  26 +++++++++++---------------
 2 files changed, 21 insertions(+), 30 deletions(-)

diffs (93 lines):

diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -611,25 +611,21 @@ u_char *
 ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
     void *code_lengths, size_t len, void *code_values)
 {
-    ngx_uint_t                    i;
-    ngx_http_script_code_pt       code;
-    ngx_http_script_len_code_pt   lcode;
-    ngx_http_script_engine_t      e;
-    ngx_http_core_main_conf_t    *cmcf;
-
-    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
-    for (i = 0; i < cmcf->variables.nelts; i++) {
-        if (r->variables[i].no_cacheable) {
-            r->variables[i].valid = 0;
-            r->variables[i].not_found = 0;
-        }
-    }
+    ngx_http_script_code_pt      code;
+    ngx_http_script_engine_t     e;
+    ngx_http_script_len_code_pt  lcode;
 
     ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
 
     e.ip = code_lengths;
     e.request = r;
+
+    while (*(uintptr_t *) e.ip) {
+        lcode = *(ngx_http_script_len_code_pt *) e.ip;
+        (void) lcode(&e);
+    }
+
+    e.ip = code_lengths;
     e.flushed = 1;
 
     while (*(uintptr_t *) e.ip) {
@@ -637,7 +633,6 @@ ngx_http_script_run(ngx_http_request_t *
         len += lcode(&e);
     }
 
-
     value->len = len;
     value->data = ngx_pnalloc(r->pool, len);
     if (value->data == NULL) {
diff --git a/src/stream/ngx_stream_script.c b/src/stream/ngx_stream_script.c
--- a/src/stream/ngx_stream_script.c
+++ b/src/stream/ngx_stream_script.c
@@ -492,20 +492,9 @@ u_char *
 ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value,
     void *code_lengths, size_t len, void *code_values)
 {
-    ngx_uint_t                      i;
-    ngx_stream_script_code_pt       code;
-    ngx_stream_script_engine_t      e;
-    ngx_stream_core_main_conf_t    *cmcf;
-    ngx_stream_script_len_code_pt   lcode;
-
-    cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);
-
-    for (i = 0; i < cmcf->variables.nelts; i++) {
-        if (s->variables[i].no_cacheable) {
-            s->variables[i].valid = 0;
-            s->variables[i].not_found = 0;
-        }
-    }
+    ngx_stream_script_code_pt      code;
+    ngx_stream_script_engine_t     e;
+    ngx_stream_script_len_code_pt  lcode;
 
     ngx_memzero(&e, sizeof(ngx_stream_script_engine_t));
 
@@ -515,10 +504,17 @@ ngx_stream_script_run(ngx_stream_session
 
     while (*(uintptr_t *) e.ip) {
         lcode = *(ngx_stream_script_len_code_pt *) e.ip;
+        (void) lcode(&e);
+    }
+
+    e.ip = code_lengths;
+    e.flushed = 1;
+
+    while (*(uintptr_t *) e.ip) {
+        lcode = *(ngx_stream_script_len_code_pt *) e.ip;
         len += lcode(&e);
     }
 
-
     value->len = len;
     value->data = ngx_pnalloc(s->connection->pool, len);
     if (value->data == NULL) {


More information about the nginx-devel mailing list