From a2219f5e3be9f61cf0ba524b9d3ecd2994620462 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Mon, 22 Oct 2018 16:59:13 +0200 Subject: [PATCH] MINOR: cache: Add "max-object-size" option. This patch adds "max-object-size" option to the cache to limit the size in bytes of the HTTP objects to be cached. When not provided, the maximum size of an HTTP object is a 256th of the cache size. --- src/cache.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/cache.c b/src/cache.c index c0e8957949..d24115431a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -50,6 +50,7 @@ struct cache { struct eb_root entries; /* head of cache entries based on keys */ unsigned int maxage; /* max-age */ unsigned int maxblocks; + unsigned int maxobjsz; /* max-object-size */ char id[33]; /* cache name */ }; @@ -230,9 +231,6 @@ cache_store_http_forward_data(struct stream *s, struct filter *filter, to_append = MIN(ci_contig_data(msg->chn), len - st->hdrs_len); - /* Skip remaining headers to fill the cache */ - c_adv(msg->chn, st->hdrs_len); - shctx_lock(shctx); fb = shctx_row_reserve_hot(shctx, st->first_block, to_append); if (!fb) { @@ -242,6 +240,8 @@ cache_store_http_forward_data(struct stream *s, struct filter *filter, } shctx_unlock(shctx); + /* Skip remaining headers to fill the cache */ + c_adv(msg->chn, st->hdrs_len); append = shctx_row_data_append(shctx, st->first_block, st->first_block->last_append, (unsigned char *)ci_head(msg->chn), to_append); ret = st->hdrs_len + to_append - append; @@ -431,6 +431,11 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px, if (!(txn->req.flags & HTTP_MSGF_VER_11)) goto out; + /* Do not cache too big objects. */ + if ((msg->flags & HTTP_MSGF_CNT_LEN) && shctx->max_obj_size > 0 && + msg->sov + msg->body_len > shctx->max_obj_size) + goto out; + /* cache only GET method */ if (txn->meth != HTTP_METH_GET) goto out; @@ -830,6 +835,7 @@ int cfg_parse_cache(const char *file, int linenum, char **args, int kwm) } tmp_cache_config->maxage = 60; tmp_cache_config->maxblocks = 0; + tmp_cache_config->maxobjsz = 0; } } else if (strcmp(args[0], "total-max-size") == 0) { int maxsize; @@ -856,7 +862,21 @@ int cfg_parse_cache(const char *file, int linenum, char **args, int kwm) } tmp_cache_config->maxage = atoi(args[1]); - } else if (*args[0] != 0) { + } else if (strcmp(args[0], "max-object-size") == 0) { + if (alertif_too_many_args(1, file, linenum, args, &err_code)) { + err_code |= ERR_ABORT; + goto out; + } + + if (!*args[1]) { + ha_warning("parsing [%s:%d]: '%s' expects a maximum file size parameter in bytes.\n", + file, linenum, args[0]); + err_code |= ERR_WARN; + } + + tmp_cache_config->maxobjsz = atoi(args[1]); + } + else if (*args[0] != 0) { ha_alert("parsing [%s:%d] : unknown keyword '%s' in 'cache' section\n", file, linenum, args[0]); err_code |= ERR_ALERT | ERR_FATAL; goto out; @@ -882,7 +902,13 @@ int cfg_post_parse_section_cache() goto out; } - ret_shctx = shctx_init(&shctx, tmp_cache_config->maxblocks, CACHE_BLOCKSIZE, -1, sizeof(struct cache), 1); + if (!tmp_cache_config->maxobjsz) + /* Default max. file size is a 256th of the cache size. */ + tmp_cache_config->maxobjsz = + (tmp_cache_config->maxblocks * CACHE_BLOCKSIZE) >> 8; + + ret_shctx = shctx_init(&shctx, tmp_cache_config->maxblocks, CACHE_BLOCKSIZE, + tmp_cache_config->maxobjsz, sizeof(struct cache), 1); if (ret_shctx < 0) { if (ret_shctx == SHCTX_E_INIT_LOCK) -- 2.47.3