Skip to content

Commit 01af09c

Browse files
committed
added support for purging multiple pages with the same cache key
Purging multiple cache entries due to the "Vary" request header fails if not specifying the exact same headers in the purge request. This addition supports purging multiple cache entries by adding a "$" at the end of the cache key specified with the purge request.
1 parent 17df38d commit 01af09c

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,27 @@ The asterisk must be the last character of the key, so you **must** put the $uri
114114

115115

116116

117+
Purging multiple cache entries with the same cache key
118+
======================================================
119+
Caching requests that use the "Vary" header may result in multiple cache
120+
entries with the same cache key. For example, when using the request header
121+
"Vary: Accept-Encoding", a separate cache entry (with different file hash)
122+
will be stored for each content encoding (like compressed or uncompressed),
123+
but they will all have the exact same cache key.
124+
125+
Trying to purge such cached content will fail unless both the "Vary" header
126+
is specified in the purge request, plus all headers as listed in the "Vary"
127+
header, with the exact same values as used when the request was cached.
128+
129+
To be able to purge *all* pages with the same cache key, specify the key with
130+
a "$" at the end, like this:
131+
132+
curl -X PURGE /page$
133+
134+
This will purge all content with the exact key "/page" from the cache.
135+
136+
137+
117138
Sample configuration (same location syntax)
118139
===========================================
119140
http {

ngx_cache_purge_module.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,8 +1807,16 @@ ngx_http_cache_purge_partial(ngx_http_request_t *r, ngx_http_file_cache_t *cache
18071807
len = key[0].len;
18081808

18091809
/* Only check the first key */
1810-
key_partial = ngx_pcalloc(r->pool, sizeof(u_char) * len);
1811-
ngx_memcpy(key_partial, key[0].data, sizeof(u_char) * (len - 1));
1810+
if (key[0].data[key[0].len - 1] == '$') {
1811+
/* Check key for exact match (key terminated by newline) */
1812+
key_partial = ngx_pcalloc(r->pool, sizeof(u_char) * (len + 1));
1813+
ngx_memcpy(key_partial, key[0].data, sizeof(u_char) * (len - 1));
1814+
key_partial[len - 1] = '\n';
1815+
} else {
1816+
/* Check key for prefix match */
1817+
key_partial = ngx_pcalloc(r->pool, sizeof(u_char) * len);
1818+
ngx_memcpy(key_partial, key[0].data, sizeof(u_char) * (len - 1));
1819+
}
18121820

18131821
/* Walk the tree and remove all the files matching key_partial */
18141822
ngx_tree_ctx_t tree;
@@ -1833,7 +1841,8 @@ ngx_http_cache_purge_is_partial(ngx_http_request_t *r) {
18331841
key = c->keys.elts;
18341842

18351843
/* Only check the first key */
1836-
return key[0].data[key[0].len - 1] == '*';
1844+
return (key[0].data[key[0].len - 1] == '*' ||
1845+
key[0].data[key[0].len - 1] == '$');
18371846
}
18381847

18391848
char *

0 commit comments

Comments
 (0)