[nginx] Upstream: handling of multiple Vary headers (ticket #1423).

Sergey Kandaurov pluknet at nginx.com
Mon May 30 22:32:57 UTC 2022


details:   https://hg.nginx.org/nginx/rev/cd73509f21e2
branches:  
changeset: 8035:cd73509f21e2
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Mon May 30 21:25:51 2022 +0300
description:
Upstream: handling of multiple Vary headers (ticket #1423).

Previously, only the last header value was used when caching.

diffstat:

 src/http/ngx_http_upstream.c |  48 +++++++++++++++++++++++++++++++++++++++----
 1 files changed, 43 insertions(+), 5 deletions(-)

diffs (71 lines):

diff -r 413dbda22f7d -r cd73509f21e2 src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c	Mon May 30 21:25:49 2022 +0300
+++ b/src/http/ngx_http_upstream.c	Mon May 30 21:25:51 2022 +0300
@@ -5175,6 +5175,9 @@ static ngx_int_t
 ngx_http_upstream_process_vary(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset)
 {
+    u_char                *p;
+    size_t                 len;
+    ngx_str_t              vary;
     ngx_table_elt_t      **ph;
     ngx_http_upstream_t   *u;
 
@@ -5192,17 +5195,52 @@ ngx_http_upstream_process_vary(ngx_http_
         return NGX_OK;
     }
 
-    if (r->cache == NULL) {
+    if (r->cache == NULL || !u->cacheable) {
+        return NGX_OK;
+    }
+
+    if (h->value.len == 1 && h->value.data[0] == '*') {
+        u->cacheable = 0;
         return NGX_OK;
     }
 
-    if (h->value.len > NGX_HTTP_CACHE_VARY_LEN
-        || (h->value.len == 1 && h->value.data[0] == '*'))
-    {
+    if (u->headers_in.vary->next) {
+
+        len = 0;
+
+        for (h = u->headers_in.vary; h; h = h->next) {
+            len += h->value.len + 2;
+        }
+
+        len -= 2;
+
+        p = ngx_pnalloc(r->pool, len);
+        if (p == NULL) {
+            return NGX_ERROR;
+        }
+
+        vary.len = len;
+        vary.data = p;
+
+        for (h = u->headers_in.vary; h; h = h->next) {
+            p = ngx_copy(p, h->value.data, h->value.len);
+
+            if (h->next == NULL) {
+                break;
+            }
+
+            *p++ = ','; *p++ = ' ';
+        }
+
+    } else {
+        vary = h->value;
+    }
+
+    if (vary.len > NGX_HTTP_CACHE_VARY_LEN) {
         u->cacheable = 0;
     }
 
-    r->cache->vary = h->value;
+    r->cache->vary = vary;
 
 #endif
 



More information about the nginx-devel mailing list