]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: htx: Change htx_xfer_blk() to also count metadata
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 16 May 2019 09:29:13 +0000 (11:29 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 28 May 2019 05:42:12 +0000 (07:42 +0200)
This patch makes the function more accurate. Thanks to the function
htx_get_max_blksz(), the transfer of data has been simplified. Note that now the
total number of bytes copied (metadata + payload) is returned. This slighly
change how the function is used in the H2 multiplexer.

src/htx.c
src/mux_h2.c

index bdde868af374d86ad031d777f8d33b257242471a..3a2252febf05fb37f077a0835310b29931a57c17 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -480,9 +480,9 @@ struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk,
 }
 
 /* Transfer HTX blocks from <src> to <dst>, stopping on the first block of the
- * type <mark> (typically EOH, EOD or EOM) or when <count> bytes of data were
- * moved. It returns the number of bytes of data moved and the last HTX block
- * inserted in <dst>.
+ * type <mark> (typically EOH, EOD or EOM) or when <count> bytes were moved
+ * (including payload and meta-data). It returns the number of bytes moved and
+ * the last HTX block inserted in <dst>.
  */
 struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
                             enum htx_blk_type mark)
@@ -491,35 +491,29 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
        enum htx_blk_type type;
        uint32_t          info, max, sz, ret;
 
-       ret = 0;
+       ret = htx_used_space(dst);
        blk = htx_get_blk(src, htx_get_head(src));
        dstblk = NULL;
-       while (blk && ret <= count) {
+
+       while (blk && count) {
                type = htx_get_blk_type(blk);
 
                /* Ingore unused block */
                if (type == HTX_BLK_UNUSED)
                        goto next;
 
-               sz = htx_get_blksz(blk);
-               if (!sz) {
-                       dstblk = htx_reserve_nxblk(dst, 0);
-                       if (!dstblk)
-                               break;
-                       dstblk->info = blk->info;
-                       goto next;
-               }
 
+               sz = htx_get_blksz(blk);
                info = blk->info;
-               max = htx_free_data_space(dst);
-               if (max > count - ret)
-                       max = count - ret;
+               max = htx_get_max_blksz(dst, count);
+               if (!max)
+                       break;
                if (sz > max) {
-                       sz = max;
-                       info = (type << 28) + sz;
                        /* Headers and pseudo headers must be fully copied  */
-                       if (type != HTX_BLK_DATA || !sz)
+                       if (type != HTX_BLK_DATA)
                                break;
+                       sz = max;
+                       info = (type << 28) + sz;
                }
 
                dstblk = htx_reserve_nxblk(dst, sz);
@@ -528,13 +522,11 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
                dstblk->info = info;
                memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);
 
-               ret += sz;
+               count -= sizeof(dstblk) + sz;
                if (blk->info != info) {
                        /* Partial move: don't remove <blk> from <src> but
                         * resize its content */
-                       blk->addr += sz;
-                       htx_set_blk_value_len(blk, htx_get_blksz(blk) - sz);
-                       src->data -= sz;
+                       htx_cut_data_blk(src, blk, sz);
                        break;
                }
 
@@ -547,6 +539,8 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
 
        }
 
+  end:
+       ret = htx_used_space(dst) - ret;
        return (struct htx_ret){.ret = ret, .blk = dstblk};
 }
 
index 6ecec4d624bb961b15f07aa66c7c9c630b5208c0..b39896374d26e4ad3c8627e8dd1b35ab0069bc56 100644 (file)
@@ -5379,7 +5379,6 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
        struct h2c *h2c = h2s->h2c;
        struct htx *h2s_htx = NULL;
        struct htx *buf_htx = NULL;
-       struct htx_ret htx_ret;
        size_t ret = 0;
 
        /* transfer possibly pending data to the upper layer */
@@ -5394,6 +5393,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
                        goto end;
                }
 
+               ret = h2s_htx->data;
                buf_htx = htx_from_buf(buf);
                count = htx_free_data_space(buf_htx);
                if (flags & CO_RFL_KEEP_RSV) {
@@ -5402,7 +5402,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
                        count -= global.tune.maxrewrite;
                }
 
-               htx_ret = htx_xfer_blks(buf_htx, h2s_htx, count, HTX_BLK_EOM);
+               htx_xfer_blks(buf_htx, h2s_htx, count, HTX_BLK_EOM);
 
                if (h2s_htx->flags & HTX_FL_PARSING_ERROR)
                        buf_htx->flags |= HTX_FL_PARSING_ERROR;
@@ -5410,7 +5410,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
                buf_htx->extra = (h2s_htx->extra ? (h2s_htx->data + h2s_htx->extra) : 0);
                htx_to_buf(buf_htx, buf);
                htx_to_buf(h2s_htx, &h2s->rxbuf);
-               ret = htx_ret.ret;
+               ret -= h2s_htx->data;
        }
        else {
                ret = b_xfer(buf, &h2s->rxbuf, count);