[PATCH 3 of 4] Rewrite: added flushing of variables during length calculations
Maxim Dounin
mdounin at mdounin.ru
Sun Jul 19 00:01:37 UTC 2026
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1784411852 -10800
# Sun Jul 19 00:57:32 2026 +0300
# Node ID 762271b9b20cbb03e7f78c0f4e483930cb1edebc
# Parent b9068e5a711c88abe4d6f4ed335467e0977f2956
Rewrite: added flushing of variables during length calculations.
In particular, this fixes issues observed in the following
configuration:
map $uri $map {
~(?<capture>.*) $capture;
}
set $temp $capture$map;
Note that this slightly changes meaning of "e->flushed" when used for
rewrite-specific codes, notably for ngx_http_script_complex_value_code()
and ngx_http_script_regex_start_code(). It is now also used to indicate
that relevant code-specific flush arrays should be used.
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -171,6 +171,7 @@ ngx_http_rewrite_handler(ngx_http_reques
e->ip = rlcf->codes->elts;
e->request = r;
+ e->flushed = 1;
e->quote = 1;
e->log = rlcf->log;
e->status = NGX_DECLINED;
@@ -389,6 +390,7 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_com
sc.cf = cf;
sc.source = &value[2];
+ sc.flushes = ®ex->flushes;
sc.lengths = ®ex->lengths;
sc.values = &lcf->codes;
sc.variables = ngx_http_script_variables_count(&value[2]);
@@ -981,12 +983,14 @@ ngx_http_rewrite_value(ngx_conf_t *cf, n
}
complex->code = ngx_http_script_complex_value_code;
+ complex->flushes = NULL;
complex->lengths = NULL;
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
sc.cf = cf;
sc.source = value;
+ sc.flushes = &complex->flushes;
sc.lengths = &complex->lengths;
sc.values = &lcf->codes;
sc.variables = n;
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
@@ -1154,11 +1154,16 @@ ngx_http_script_regex_start_code(ngx_htt
}
}
+ if (e->flushed) {
+ ngx_http_script_flush_no_cacheable_variables(e->request, code->flushes);
+ }
+
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
le.ip = code->lengths->elts;
le.line = e->line;
le.request = r;
+ le.flushed = e->flushed;
le.quote = code->redirect;
le.is_args = e->is_args;
@@ -1771,11 +1776,16 @@ ngx_http_script_complex_value_code(ngx_h
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
"http script complex value");
+ if (e->flushed) {
+ ngx_http_script_flush_no_cacheable_variables(e->request, code->flushes);
+ }
+
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
le.ip = code->lengths->elts;
le.line = e->line;
le.request = e->request;
+ le.flushed = e->flushed;
le.quote = e->quote;
le.is_args = e->is_args;
diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -112,6 +112,7 @@ typedef struct {
typedef struct {
ngx_http_script_code_pt code;
ngx_http_regex_t *regex;
+ ngx_array_t *flushes;
ngx_array_t *lengths;
uintptr_t size;
uintptr_t status;
@@ -187,6 +188,7 @@ typedef struct {
typedef struct {
ngx_http_script_code_pt code;
+ ngx_array_t *flushes;
ngx_array_t *lengths;
} ngx_http_script_complex_value_code_t;
More information about the nginx-devel
mailing list