From: Maxime Henrion Date: Tue, 30 Jun 2026 15:32:50 +0000 (-0400) Subject: MINOR: cache: factor cache_extract_link_hints out of cache_extract_hints X-Git-Url: http://git.kaiwu.me/http/doc/static/gitweb.js?a=commitdiff_plain;h=39233e0a673e5cd12dec4c2fe90efcdce038aa05;p=haproxy.git MINOR: cache: factor cache_extract_link_hints out of cache_extract_hints Move the per-Link-value processing into a new cache_extract_link_hints() helper. cache_extract_hints() continues to walk the cached row's HDR blocks and now invokes the helper once per Link header it finds. No behaviour change. This prepares the helper for reuse by an upcoming hints-only storage path that extracts Link headers directly from the live response HTX rather than from a cached row. --- diff --git a/src/cache.c b/src/cache.c index f0c6417af..a19d19e23 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1164,6 +1164,47 @@ static void cache_free_blocks(struct shared_block *first, void *data) } } +static void cache_extract_link_hints(struct ist link, struct buffer *hint_buf) +{ + struct ist lv; + size_t hdr_start = b_data(hint_buf); + uint16_t hdr_len = 0; + + if (b_data(hint_buf) + sizeof(hdr_len) > b_size(hint_buf)) + return; + + hint_buf->data += sizeof(hdr_len); + + while (http_next_hdr_value(&link, &lv)) { + size_t needed = lv.len; + + if (!link_is_hint(lv)) + continue; + if (hdr_len > 0) + needed += 2; + if (hdr_len + needed > UINT16_MAX) + continue; + if (b_data(hint_buf) + needed > b_size(hint_buf)) + continue; + + if (hdr_len > 0) { + chunk_memcat(hint_buf, ", ", 2); + hdr_len += 2; + } + chunk_memcat(hint_buf, lv.ptr, lv.len); + hdr_len += lv.len; + } + + /* If we wrote anything in the hint buffer, encode the length of the + * data at the beginning, and if we didn't, reset the buffer pointer to + * its previous state (before the 2 bytes we initially reserved). + */ + if (hdr_len == 0) + hint_buf->data -= sizeof(hdr_len); + else + memcpy(b_orig(hint_buf) + hdr_start, &hdr_len, sizeof(hdr_len)); +} + /* * Walk the HTX header blocks and accumulate Link values relevant for early * hints into . Returns the number of bytes written to . @@ -1204,45 +1245,15 @@ static int cache_extract_hints(struct shared_context *shctx, shctx_row_data_get(shctx, first, (unsigned char *)name, offset + sizeof(info), 4); if (memcmp(name, "link", 4) == 0) { - struct ist iter, lv; - size_t hdr_start = b_data(hint_buf); - uint16_t hdr_len = 0; + struct ist value; shctx_row_data_get(shctx, first, (unsigned char *)value_buf, offset + sizeof(info) + name_len, value_len); - iter = ist2(value_buf, value_len); - - if (b_data(hint_buf) + sizeof(hdr_len) > b_size(hint_buf)) - break; - hint_buf->data += sizeof(hdr_len); - - while (http_next_hdr_value(&iter, &lv)) { - size_t needed = lv.len; - - if (!link_is_hint(lv)) - continue; - if (hdr_len > 0) - needed += 2; - if (hdr_len + needed > UINT16_MAX) - continue; - if (b_data(hint_buf) + needed > b_size(hint_buf)) - continue; - - if (hdr_len > 0) { - chunk_memcat(hint_buf, ", ", 2); - hdr_len += 2; - } - chunk_memcat(hint_buf, lv.ptr, lv.len); - hdr_len += lv.len; - } - if (hdr_len == 0) - hint_buf->data -= sizeof(hdr_len); - else - memcpy(b_orig(hint_buf) + hdr_start, - &hdr_len, sizeof(hdr_len)); + value = ist2(value_buf, value_len); + cache_extract_link_hints(value, hint_buf); } } offset += sizeof(info) + name_len + value_len;