]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: htx: Fully update HTX message when the block value is changed
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 18 Jun 2019 07:49:16 +0000 (09:49 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 18 Jun 2019 08:02:05 +0000 (10:02 +0200)
Everywhere the value length of a block is changed, calling the function
htx_set_blk_value_len(), the HTX message must be updated. But at many places,
because of the recent changes in the HTX structure, this update was only
partially done. tail_addr and head_addr values were not systematically updated.

In fact, the function htx_set_blk_value_len() was designed as an internal
function to the HTX API. And we used it from outside by convenience. But it is
really painfull and error prone to let the caller update the HTX message. So
now, we use the function htx_change_blk_value_len() wherever is possible. It
changes the value length of a block and updates the HTX message accordingly.

This patch must be backported to 2.0.

src/h2.c
src/http_htx.c
src/htx.c
src/proto_htx.c

index 32c1ef16be8042c03fa4fb95fdff0591519cf506..990d602b1b6c33ac328898ef56aa4f36a75ebb80 100644 (file)
--- a/src/h2.c
+++ b/src/h2.c
@@ -736,8 +736,7 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms
                        if (tl > fs)
                                goto fail;
 
-                       htx_set_blk_value_len(blk, tl);
-                       htx->data += vl+2;
+                       htx_change_blk_value_len(htx, blk, tl);
                        *(char *)(htx_get_blk_ptr(htx, blk) + bs + 0) = ';';
                        *(char *)(htx_get_blk_ptr(htx, blk) + bs + 1) = ' ';
                        memcpy(htx_get_blk_ptr(htx, blk) + bs + 2, list[ck].v.ptr, vl);
index 7322b33780fc6a4a8d8685939a93f533688bf316..bc26e5ba4c2ecddcd712143ea94f6c846f51e1f7 100644 (file)
@@ -461,10 +461,7 @@ int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx)
        }
        /* Update the block content and its len */
        memmove(start, start+len, v.len-len);
-       htx_set_blk_value_len(blk, v.len-len);
-
-       /* Update HTX msg */
-       htx->data -= len;
+       htx_change_blk_value_len(htx, blk, v.len-len);
 
        /* Finally update the ctx */
        ctx->value.ptr = start;
index bfd136f460cf07df172acb882fd56569118d0f47..814925985c0e53b7b330ca22af38bdab62cfbc0d 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -406,15 +406,8 @@ void htx_truncate(struct htx *htx, uint32_t offset)
                        offset -= sz;
                        continue;
                }
-               if (type == HTX_BLK_DATA) {
-                       htx_set_blk_value_len(blk, offset);
-                       htx->data -= (sz - offset);
-
-                       if (blk->addr+sz == htx->tail_addr)
-                               htx->tail_addr -= offset;
-                       else if (blk->addr+sz == htx->head_addr)
-                               htx->head_addr -= offset;
-               }
+               if (type == HTX_BLK_DATA)
+                       htx_change_blk_value_len(htx, blk, offset);
                offset = 0;
        }
        while (blk)
@@ -522,14 +515,7 @@ struct htx_blk *htx_add_data_atonce(struct htx *htx, struct ist data)
        /* Append data and update the block itself */
        ptr = htx_get_blk_ptr(htx, tailblk);
        memcpy(ptr+sz, data.ptr, len);
-       htx_set_blk_value_len(tailblk, sz+len);
-
-       /* Update HTTP message */
-       htx->data += len;
-       if (tailblk->addr+sz == htx->tail_addr)
-               htx->tail_addr += len;
-       else if (tailblk->addr+sz == htx->head_addr)
-               htx->head_addr += len;
+       htx_change_blk_value_len(htx, tailblk, sz+len);
 
        if (data.len == len) {
                blk = tailblk;
@@ -988,14 +974,7 @@ size_t htx_add_data(struct htx *htx, const struct ist data)
        /* Append data and update the block itself */
        ptr = htx_get_blk_ptr(htx, tailblk);
        memcpy(ptr + sz, data.ptr, len);
-       htx_set_blk_value_len(tailblk, sz + len);
-
-       /* Update HTTP message */
-       htx->data += len;
-       if (tailblk->addr+sz == htx->tail_addr)
-               htx->tail_addr += len;
-       else if (tailblk->addr+sz == htx->head_addr)
-               htx->head_addr += len;
+       htx_change_blk_value_len(htx, tailblk, sz+len);
 
        BUG_ON((int32_t)htx->tail_addr < 0);
        BUG_ON((int32_t)htx->head_addr < 0);
index 7f5013665e744b0e544ea7b8b805fcff23df2ff8..d821e38cc648e0e9ae756c7a4ace21904fe87390 100644 (file)
@@ -4314,10 +4314,8 @@ static void htx_manage_client_side_cookies(struct stream *s, struct channel *req
                        hdr_end = (preserve_hdr ? del_from : hdr_beg);
                }
                if ((hdr_end - hdr_beg) != ctx.value.len) {
-                       if (hdr_beg != hdr_end) {
-                               htx_set_blk_value_len(ctx.blk, hdr_end - hdr_beg);
-                               htx->data -= ctx.value.len - (hdr_end - hdr_beg);
-                       }
+                       if (hdr_beg != hdr_end)
+                               htx_change_blk_value_len(htx, ctx.blk, hdr_end - hdr_beg);
                        else
                                http_remove_header(htx, &ctx);
                }
@@ -4495,8 +4493,7 @@ static void htx_manage_server_side_cookies(struct stream *s, struct channel *res
                                next         += stripped_before;
                                hdr_end      += stripped_before;
 
-                               htx_set_blk_value_len(ctx.blk, hdr_end - hdr_beg);
-                               htx->data -= ctx.value.len - (hdr_end - hdr_beg);
+                               htx_change_blk_value_len(htx, ctx.blk, hdr_end - hdr_beg);
                                ctx.value.len = hdr_end - hdr_beg;
                        }