From d9233f091a39b9436da7ed7b0da766169b7c04d3 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 14 Oct 2019 14:01:24 +0200 Subject: [PATCH] MINOR: mux-h1: Xfer as much payload data as possible during output processing When an outgoing HTX message is formatted to a raw message, DATA blocks may be splitted to not tranfser more data than expected. But if the buffer is almost full, the formatting is interrupted, leaving some unused free space in the buffer, because data are too large to be copied in one time. Now, we transfer as much data as possible. When the message is chunked, we also count the size used to encode the data. --- src/mux_h1.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/mux_h1.c b/src/mux_h1.c index 3c3beadff..935c925dc 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -1571,14 +1571,11 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun struct ist n, v; enum htx_blk_type type = htx_get_blk_type(blk); uint32_t sz = htx_get_blksz(blk); - uint32_t vlen; + uint32_t vlen, chklen; vlen = sz; - if (vlen > count) { - if (type != HTX_BLK_DATA) - goto full; - vlen = count; - } + if (type != HTX_BLK_DATA && vlen > count) + goto full; if (type == HTX_BLK_UNUSED) goto nextblk; @@ -1772,6 +1769,28 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun goto error; TRACE_PROTO("sending message data", H1_EV_TX_DATA|H1_EV_TX_BODY, h1c->conn, h1s, chn_htx, (size_t[]){sz}); + + + if (vlen > count) { + /* Get the maximum amount of data we can xferred */ + vlen = count; + } + + chklen = 0; + if (h1m->flags & H1_MF_CHNK) { + chklen = b_room(&tmp); + chklen = ((chklen < 16) ? 1 : (chklen < 256) ? 2 : + (chklen < 4096) ? 3 : (chklen < 65536) ? 4 : + (chklen < 1048576) ? 5 : 8); + chklen += 4; /* 2 x CRLF */ + } + + if (vlen + chklen > b_room(&tmp)) { + /* too large for the buffer */ + if (chklen >= b_room(&tmp)) + goto full; + vlen = b_room(&tmp) - chklen; + } v = htx_get_blk_value(chn_htx, blk); v.len = vlen; if (!htx_data_to_h1(v, &tmp, !!(h1m->flags & H1_MF_CHNK)))