[PATCH] Upstream: prioritise Cache-Control over Expires

Vadim Fedorenko vadim.fedorenko at cdnnow.ru
Thu Apr 14 23:02:53 UTC 2022


# HG changeset patch
# User Vadim Fedorenko <vadim.fedorenko at cdnnow.ru>
# Date 1649889268 -10800
#      Thu Apr 14 01:34:28 2022 +0300
# Node ID ed7a2c031475bcb252952a467c184c94652b926a
# Parent  a736a7a613ea6e182ff86fbadcb98bb0f8891c0b
Upstream: prioritise Cache-Control over Expires.

RFC7234 explicitly says that cache recipient MUST ignore Expires
header if response includes Cache-Control header with max-age or
s-maxage directives. Previously Cache-Control was ignored if it
was after Expires in reply headers.

At the same time this patch makes more stable behaviour of using
latest value of header Cache-Control even if previous value was 0.
Ticket #964 for more information.
---
 src/http/ngx_http_upstream.c | 25 +++++++++++++++++++++++++
 src/http/ngx_http_upstream.h | 15 +++++++++++++++
 2 files changed, 40 insertions(+)

diff -r a736a7a613ea -r ed7a2c031475 src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c	Tue Feb 08 17:35:27 2022 +0300
+++ b/src/http/ngx_http_upstream.c	Thu Apr 14 01:34:28 2022 +0300
@@ -868,6 +868,7 @@
         }
 
         u->cacheable = 1;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_DEFAULT;
 
         c = r->cache;
 
@@ -970,6 +971,7 @@
     case NGX_HTTP_CACHE_SCARCE:
 
         u->cacheable = 0;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_SCARCE;
 
         break;
 
@@ -992,6 +994,7 @@
 
     if (ngx_http_upstream_cache_check_range(r, u) == NGX_DECLINED) {
         u->cacheable = 0;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_RANGE;
     }
 
     r->cached = 0;
@@ -3105,6 +3108,7 @@
 
     case NGX_DECLINED:
         u->cacheable = 0;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_NO_CACHE;
         break;
 
     default: /* NGX_OK */
@@ -3165,6 +3169,7 @@
 
         } else {
             u->cacheable = 0;
+            u->cacheable_reason |= NGX_HTTP_CACHEABLE_INVALID;
         }
     }
 
@@ -4690,6 +4695,7 @@
 #if (NGX_HTTP_CACHE)
     if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) {
         u->cacheable = 0;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_COOKIE;
     }
 #endif
 
@@ -4747,6 +4753,7 @@
         || ngx_strlcasestrn(start, last, (u_char *) "private", 7 - 1) != NULL)
     {
         u->cacheable = 0;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_NO_CACHE;
         return NGX_OK;
     }
 
@@ -4772,15 +4779,21 @@
             }
 
             u->cacheable = 0;
+            u->cacheable_reason |= NGX_HTTP_CACHEABLE_CACHECTRL0;
             return NGX_OK;
         }
 
         if (n == 0) {
             u->cacheable = 0;
+            u->cacheable_reason |= NGX_HTTP_CACHEABLE_CACHECTRL0;
             return NGX_OK;
         }
 
         r->cache->valid_sec = ngx_time() + n;
+        u->cacheable_reason &= ~(NGX_HTTP_CACHEABLE_CACHECTRL0|NGX_HTTP_CACHEABLE_EXPIRES);
+        if (u->cacheable_reason == NGX_HTTP_CACHEABLE_DEFAULT) {
+            u->cacheable = 1;
+        }
     }
 
     p = ngx_strlcasestrn(start, last, (u_char *) "stale-while-revalidate=",
@@ -4800,9 +4813,13 @@
             }
 
             u->cacheable = 0;
+            u->cacheable_reason |= NGX_HTTP_CACHEABLE_CACHECTRL1;
             return NGX_OK;
         }
 
+        if (u->cacheable_reason == NGX_HTTP_CACHEABLE_DEFAULT) {
+            u->cacheable = 1;
+        }
         r->cache->updating_sec = n;
         r->cache->error_sec = n;
     }
@@ -4823,10 +4840,15 @@
             }
 
             u->cacheable = 0;
+            u->cacheable_reason |= NGX_HTTP_CACHEABLE_CACHECTRL2;
             return NGX_OK;
         }
 
         r->cache->error_sec = n;
+        u->cacheable_reason &= ~NGX_HTTP_CACHEABLE_EXPIRES;
+        if (u->cacheable_reason == NGX_HTTP_CACHEABLE_DEFAULT) {
+            u->cacheable = 1;
+        }
     }
     }
 #endif
@@ -4864,6 +4886,7 @@
 
     if (expires == NGX_ERROR || expires < ngx_time()) {
         u->cacheable = 0;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_EXPIRES;
         return NGX_OK;
     }
 
@@ -4907,6 +4930,7 @@
         switch (n) {
         case 0:
             u->cacheable = 0;
+            u->cacheable_reason |= NGX_HTTP_CACHEABLE_XACCEL;
             /* fall through */
 
         case NGX_ERROR:
@@ -5067,6 +5091,7 @@
         || (h->value.len == 1 && h->value.data[0] == '*'))
     {
         u->cacheable = 0;
+        u->cacheable_reason |= NGX_HTTP_CACHEABLE_VARY;
     }
 
     r->cache->vary = h->value;
diff -r a736a7a613ea -r ed7a2c031475 src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h	Tue Feb 08 17:35:27 2022 +0300
+++ b/src/http/ngx_http_upstream.h	Thu Apr 14 01:34:28 2022 +0300
@@ -320,6 +320,20 @@
     ngx_http_upstream_t *u);
 
 
+#define NGX_HTTP_CACHEABLE_DEFAULT      0x80000000
+#define NGX_HTTP_CACHEABLE_SCARCE       0x00000001
+#define NGX_HTTP_CACHEABLE_RANGE        0x00000002
+#define NGX_HTTP_CACHEABLE_INVALID      0x00000004
+#define NGX_HTTP_CACHEABLE_NO_CACHE     0x00000010
+#define NGX_HTTP_CACHEABLE_EXPIRES      0x00000020
+#define NGX_HTTP_CACHEABLE_COOKIE       0x00000040
+#define NGX_HTTP_CACHEABLE_CACHECTRL0   0x00000100
+#define NGX_HTTP_CACHEABLE_CACHECTRL1   0x00000200
+#define NGX_HTTP_CACHEABLE_CACHECTRL2   0x00000400
+#define NGX_HTTP_CACHEABLE_XACCEL       0x00001000
+#define NGX_HTTP_CACHEABLE_VARY         0x00002000
+
+
 struct ngx_http_upstream_s {
     ngx_http_upstream_handler_pt     read_event_handler;
     ngx_http_upstream_handler_pt     write_event_handler;
@@ -384,6 +398,7 @@
 
     ngx_http_cleanup_pt             *cleanup;
 
+    ngx_uint_t                       cacheable_reason;
     unsigned                         store:1;
     unsigned                         cacheable:1;
     unsigned                         accel:1;



More information about the nginx-devel mailing list