[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