From 5a606685f1d6bb4b6bf8ea82419c0eb03982360c Mon Sep 17 00:00:00 2001 From: Dragan Dosen Date: Thu, 14 Feb 2019 12:30:53 +0100 Subject: [PATCH] BUG/MEDIUM: http_fetch: fix "req.body_len" and "req.body_size" fetch methods in HTX mode When in HTX mode, in functions smp_fetch_body_len() and smp_fetch_body_size() we were subtracting the size of each header block from the total size htx->data to calculate the size of body, and that could result in wrong calculated value. To avoid this, we now loop on blocks to sum up the size of only those that are of type HTX_BLK_DATA. This patch must be backported to 1.9. --- src/http_fetch.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/http_fetch.c b/src/http_fetch.c index 01cbac4fc..51f2ef13f 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -918,21 +918,20 @@ static int smp_fetch_body_len(const struct arg *args, struct sample *smp, const if (IS_HTX_SMP(smp) || (smp->px->mode == PR_MODE_TCP)) { /* HTX version */ struct htx *htx = smp_prefetch_htx(smp, args); - struct htx_blk *blk; + int32_t pos; unsigned long long len = 0; if (!htx) return 0; - len = htx->data; + for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) { + struct htx_blk *blk = htx_get_blk(htx, pos); + enum htx_blk_type type = htx_get_blk_type(blk); - /* Remove the length of headers part */ - blk = htx_get_head_blk(htx); - while (blk) { - len -= htx_get_blksz(blk); - if (htx_get_blk_type(blk) == HTX_BLK_EOH) + if (type == HTX_BLK_EOM || type == HTX_BLK_EOD) break; - blk = htx_get_next_blk(htx, blk); + if (type == HTX_BLK_DATA) + len += htx_get_blksz(blk); } smp->data.type = SMP_T_SINT; @@ -969,21 +968,20 @@ static int smp_fetch_body_size(const struct arg *args, struct sample *smp, const if (IS_HTX_SMP(smp) || (smp->px->mode == PR_MODE_TCP)) { /* HTX version */ struct htx *htx = smp_prefetch_htx(smp, args); - struct htx_blk *blk; + int32_t pos; unsigned long long len = 0; if (!htx) return 0; - len = htx->data; + for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) { + struct htx_blk *blk = htx_get_blk(htx, pos); + enum htx_blk_type type = htx_get_blk_type(blk); - /* Remove the length of headers part */ - blk = htx_get_head_blk(htx); - while (blk) { - len -= htx_get_blksz(blk); - if (htx_get_blk_type(blk) == HTX_BLK_EOH) + if (type == HTX_BLK_EOM || type == HTX_BLK_EOD) break; - blk = htx_get_next_blk(htx, blk); + if (type == HTX_BLK_DATA) + len += htx_get_blksz(blk); } if (htx->extra != ULLONG_MAX) len += htx->extra; -- 2.47.3