From 5965a6e1d2afa8041c4b518f878f3d22066e20e4 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 3 Feb 2026 07:45:03 +0100 Subject: [PATCH] MEDIUM: cache: Don't rely on a chunk to store messages payload When the response payload is stored in the cache, we can avoid to use a trash chunk as temporary space area before copying everything in the cache in one call. Instead we can directly write each HTX block in the cache, one by one. It should not be an issue because, most of time, there is only one DATA block. This commit depends on "BUG/MEDIUM: shctx: Use the next block when data exactly filled a block". --- src/cache.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cache.c b/src/cache.c index 5fd254059..fd3d7c5d7 100644 --- a/src/cache.c +++ b/src/cache.c @@ -755,7 +755,6 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms struct htx_blk *blk; struct shared_block *fb; struct htx_ret htxret; - size_t data_len = 0; unsigned int orig_len, to_forward; int ret; @@ -767,7 +766,6 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms return len; } - chunk_reset(&trash); orig_len = len; to_forward = 0; @@ -789,10 +787,17 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms v = isttrim(v, len); info = (type << 28) + v.len; - chunk_memcat(&trash, (char *)&info, sizeof(info)); - chunk_istcat(&trash, v); + fb = shctx_row_reserve_hot(shctx, st->first_block, sizeof(info)+v.len); + if (!fb) + goto no_cache; + ret = shctx_row_data_append(shctx, st->first_block, (unsigned char *)&info, sizeof(info)); + if (ret < 0) + goto no_cache; + ret = shctx_row_data_append(shctx, st->first_block, (unsigned char *)istptr(v), istlen(v)); + if (ret < 0) + goto no_cache; + ASSUME_NONNULL((struct cache_entry *)st->first_block->data)->body_size += v.len; to_forward += v.len; - data_len += v.len; len -= v.len; break; @@ -804,8 +809,15 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms if (sz > len) goto end; - chunk_memcat(&trash, (char *)&blk->info, sizeof(blk->info)); - chunk_memcat(&trash, htx_get_blk_ptr(htx, blk), sz); + fb = shctx_row_reserve_hot(shctx, st->first_block, sizeof(blk->info)+sz); + if (!fb) + goto no_cache; + ret = shctx_row_data_append(shctx, st->first_block, (unsigned char *)&(blk->info), sizeof(blk->info)); + if (ret < 0) + goto no_cache; + ret = shctx_row_data_append(shctx, st->first_block, (unsigned char *)htx_get_blk_ptr(htx, blk), sz); + if (ret < 0) + goto no_cache; to_forward += sz; len -= sz; break; @@ -815,18 +827,6 @@ cache_store_http_payload(struct stream *s, struct filter *filter, struct http_ms } end: - - fb = shctx_row_reserve_hot(shctx, st->first_block, trash.data); - if (!fb) { - goto no_cache; - } - - ASSUME_NONNULL((struct cache_entry *)st->first_block->data)->body_size += data_len; - ret = shctx_row_data_append(shctx, st->first_block, - (unsigned char *)b_head(&trash), b_data(&trash)); - if (ret < 0) - goto no_cache; - return to_forward; no_cache: -- 2.47.3