[PATCH 06 of 12] Upstream: added a function to initialize and clear input headers

Maxim Dounin mdounin at mdounin.ru
Fri Aug 8 20:09:01 UTC 2025


# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1754683253 -10800
#      Fri Aug 08 23:00:53 2025 +0300
# Node ID 924c082b02a4afed6910650d6ee3b709244a0fba
# Parent  8466023cd0bec68089048f45e1e4c3985d54678e
Upstream: added a function to initialize and clear input headers.

When headers are already initialized, we now reinitialize corresponding
ngx_list_t members to clear the structure instead of reinitializing the
whole structure (and allocating memory for elements of the first list part),
similarly to ngx_http_clean_header().

diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -45,6 +45,8 @@ static void ngx_http_upstream_connect(ng
     ngx_http_upstream_t *u);
 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
+static ngx_int_t ngx_http_upstream_clear_headers(ngx_http_request_t *r,
+    ngx_http_upstream_t *u);
 static void ngx_http_upstream_send_request(ngx_http_request_t *r,
     ngx_http_upstream_t *u, ngx_uint_t do_write);
 static ngx_int_t ngx_http_upstream_send_request_body(ngx_http_request_t *r,
@@ -519,9 +521,6 @@ ngx_http_upstream_create(ngx_http_reques
     r->cache = NULL;
 #endif
 
-    u->headers_in.content_length_n = -1;
-    u->headers_in.last_modified_time = -1;
-
     return NGX_OK;
 }
 
@@ -1087,21 +1086,7 @@ ngx_http_upstream_cache_send(ngx_http_re
     u->buffer = *c->buf;
     u->buffer.pos += c->header_start;
 
-    ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
-    u->headers_in.content_length_n = -1;
-    u->headers_in.last_modified_time = -1;
-
-    if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
-                      sizeof(ngx_table_elt_t))
-        != NGX_OK)
-    {
-        return NGX_ERROR;
-    }
-
-    if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
-                      sizeof(ngx_table_elt_t))
-        != NGX_OK)
-    {
+    if (ngx_http_upstream_clear_headers(r, u) != NGX_OK) {
         return NGX_ERROR;
     }
 
@@ -2027,21 +2012,7 @@ ngx_http_upstream_reinit(ngx_http_reques
     u->upgrade = 0;
     u->error = 0;
 
-    ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
-    u->headers_in.content_length_n = -1;
-    u->headers_in.last_modified_time = -1;
-
-    if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
-                      sizeof(ngx_table_elt_t))
-        != NGX_OK)
-    {
-        return NGX_ERROR;
-    }
-
-    if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
-                      sizeof(ngx_table_elt_t))
-        != NGX_OK)
-    {
+    if (ngx_http_upstream_clear_headers(r, u) != NGX_OK) {
         return NGX_ERROR;
     }
 
@@ -2099,6 +2070,54 @@ ngx_http_upstream_reinit(ngx_http_reques
 }
 
 
+static ngx_int_t
+ngx_http_upstream_clear_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
+{
+    if (u->headers_in.headers.last) {
+
+        /* clear headers and reinitialize lists */
+
+        ngx_memzero(&u->headers_in.status_n,
+                    sizeof(ngx_http_upstream_headers_in_t)
+                    - offsetof(ngx_http_upstream_headers_in_t, status_n));
+
+        u->headers_in.headers.part.nelts = 0;
+        u->headers_in.headers.part.next = NULL;
+        u->headers_in.headers.last = &u->headers_in.headers.part;
+
+        u->headers_in.trailers.part.nelts = 0;
+        u->headers_in.trailers.part.next = NULL;
+        u->headers_in.trailers.last = &u->headers_in.trailers.part;
+
+        u->headers_in.content_length_n = -1;
+        u->headers_in.last_modified_time = -1;
+
+        return NGX_OK;
+    }
+
+    /* initialize headers */
+
+    if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
+                      sizeof(ngx_table_elt_t))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
+                      sizeof(ngx_table_elt_t))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    u->headers_in.content_length_n = -1;
+    u->headers_in.last_modified_time = -1;
+
+    return NGX_OK;
+}
+
+
 static void
 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
     ngx_uint_t do_write)
@@ -2440,24 +2459,6 @@ ngx_http_upstream_process_header(ngx_htt
 
         u->buffer.tag = u->output.tag;
 
-        if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
-                          sizeof(ngx_table_elt_t))
-            != NGX_OK)
-        {
-            ngx_http_upstream_finalize_request(r, u,
-                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
-            return;
-        }
-
-        if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
-                          sizeof(ngx_table_elt_t))
-            != NGX_OK)
-        {
-            ngx_http_upstream_finalize_request(r, u,
-                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
-            return;
-        }
-
 #if (NGX_HTTP_CACHE)
 
         if (r->cache) {
@@ -2465,6 +2466,12 @@ ngx_http_upstream_process_header(ngx_htt
             u->buffer.last = u->buffer.pos;
         }
 #endif
+
+        if (ngx_http_upstream_clear_headers(r, u) != NGX_OK) {
+            ngx_http_upstream_finalize_request(r, u,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
     }
 
     for ( ;; ) {



More information about the nginx-devel mailing list