]> git.kaiwu.me - nginx.git/commitdiff
Cache: keep c->body_start when Vary changes (ticket #2029).
authorSergey Kandaurov <pluknet@nginx.com>
Wed, 9 Sep 2020 16:26:27 +0000 (19:26 +0300)
committerSergey Kandaurov <pluknet@nginx.com>
Wed, 9 Sep 2020 16:26:27 +0000 (19:26 +0300)
If the variant hash doesn't match one we used as a secondary cache key,
we switch back to the original key.  In this case, c->body_start was kept
updated from an existing cache node overwriting the new response value.
After file cache update, it led to discrepancy between a cache node and
cache file seen as critical errors "file cache .. has too long header".

src/http/ngx_http_cache.h
src/http/ngx_http_file_cache.c

index d010a4ef0adc7dc4945c7ecc9a22ed67ac4557a6..bb936c5fe0c590da1fca89e2c8c8d27d2cdf08ab 100644 (file)
@@ -117,6 +117,7 @@ struct ngx_http_cache_s {
     unsigned                         purged:1;
     unsigned                         reading:1;
     unsigned                         secondary:1;
+    unsigned                         update_variant:1;
     unsigned                         background:1;
 
     unsigned                         stale_updating:1;
index 7a5b4ca5be22f6879e53aa33b42e30934f6a376b..c40093bca61cbd199c0c06e85640614f85241c8b 100644 (file)
@@ -854,7 +854,7 @@ ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
         if (fcn->exists || fcn->uses >= c->min_uses) {
 
             c->exists = fcn->exists;
-            if (fcn->body_start) {
+            if (fcn->body_start && !c->update_variant) {
                 c->body_start = fcn->body_start;
             }
 
@@ -1339,6 +1339,7 @@ ngx_http_file_cache_update_variant(ngx_http_request_t *r, ngx_http_cache_t *c)
     ngx_shmtx_unlock(&cache->shpool->mutex);
 
     c->file.name.len = 0;
+    c->update_variant = 1;
 
     ngx_memcpy(c->key, c->main, NGX_HTTP_CACHE_KEY_LEN);