Skip to content

Commit 960d237

Browse files
committed
Fix memory leak when using partial (wildcard) keys.
This should also offer a slight performance boost because it avoids having to perform an allocation for every single cache entry being walked.
1 parent a84b0f3 commit 960d237

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

ngx_cache_purge_module.c

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,15 +1315,25 @@ ngx_http_purge_file_cache_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path) {
13151315
}
13161316

13171317

1318+
typedef struct {
1319+
u_char *key_partial;
1320+
u_char *key_in_file;
1321+
ngx_uint_t key_len;
1322+
} ngx_http_cache_purge_partial_ctx_t;
1323+
13181324
static ngx_int_t
13191325
ngx_http_purge_file_cache_delete_partial_file(ngx_tree_ctx_t *ctx, ngx_str_t *path) {
1326+
ngx_http_cache_purge_partial_ctx_t *data;
13201327
u_char *key_partial;
13211328
u_char *key_in_file;
13221329
ngx_uint_t len;
13231330
ngx_flag_t remove_file = 0;
13241331

1325-
key_partial = ctx->data;
1326-
len = ngx_strlen(key_partial);
1332+
data = ctx->data;
1333+
1334+
key_partial = data->key_partial;
1335+
key_in_file = data->key_in_file;
1336+
len = data->key_len;
13271337

13281338
/* if key_partial is empty always match, because is a '*' */
13291339
if (len == 0) {
@@ -1342,9 +1352,7 @@ ngx_http_purge_file_cache_delete_partial_file(ngx_tree_ctx_t *ctx, ngx_str_t *pa
13421352
}
13431353
file.log = ctx->log;
13441354

1345-
/* I don't know if it's a good idea to use the ngx_cycle pool for this,
1346-
but the request is not available here */
1347-
key_in_file = ngx_pcalloc(ngx_cycle->pool, sizeof(u_char) * (len + 1));
1355+
ngx_memzero(key_in_file, sizeof(u_char) * len);
13481356

13491357
/* KEY: /proxy/passwd */
13501358
/* since we don't need the "KEY: " ignore 5 + 1 extra u_char from last
@@ -1807,18 +1815,21 @@ ngx_http_cache_purge_partial(ngx_http_request_t *r, ngx_http_file_cache_t *cache
18071815
"purge_partial http in %s",
18081816
cache->path->name.data);
18091817

1810-
u_char *key_partial;
1811-
ngx_str_t *key;
1812-
ngx_http_cache_t *c;
1813-
ngx_uint_t len;
1818+
ngx_str_t *keys;
1819+
ngx_str_t key;
18141820

1815-
c = r->cache;
1816-
key = c->keys.elts;
1817-
len = key[0].len;
1821+
/* Only check the first key, and discard '*' at the end */
1822+
keys = r->cache->keys.elts;
1823+
key = keys[0];
1824+
key.len--;
18181825

1819-
/* Only check the first key */
1820-
key_partial = ngx_pcalloc(r->pool, sizeof(u_char) * len);
1821-
ngx_memcpy(key_partial, key[0].data, sizeof(u_char) * (len - 1));
1826+
ngx_http_cache_purge_partial_ctx_t *ctx;
1827+
ctx = ngx_palloc(r->pool, sizeof(ngx_http_cache_purge_partial_ctx_t));
1828+
ctx->key_len = key.len;
1829+
if (key.len > 0) {
1830+
ctx->key_partial = key.data;
1831+
ctx->key_in_file = ngx_pnalloc(r->pool, sizeof(u_char) * key.len);
1832+
}
18221833

18231834
/* Walk the tree and remove all the files matching key_partial */
18241835
ngx_tree_ctx_t tree;
@@ -1827,7 +1838,7 @@ ngx_http_cache_purge_partial(ngx_http_request_t *r, ngx_http_file_cache_t *cache
18271838
tree.pre_tree_handler = ngx_http_purge_file_cache_noop;
18281839
tree.post_tree_handler = ngx_http_purge_file_cache_noop;
18291840
tree.spec_handler = ngx_http_purge_file_cache_noop;
1830-
tree.data = key_partial;
1841+
tree.data = ctx;
18311842
tree.alloc = 0;
18321843
tree.log = ngx_cycle->log;
18331844

0 commit comments

Comments
 (0)