From: Dragan Dosen Date: Thu, 14 Feb 2019 11:30:53 +0000 (+0100) Subject: BUG/MEDIUM: http_fetch: fix "req.body_len" and "req.body_size" fetch methods in HTX... X-Git-Tag: v2.0-dev1~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a606685f1d6bb4b6bf8ea82419c0eb03982360c;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/http_fetch.c b/src/http_fetch.c index 01cbac4fce..51f2ef13f2 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;