mirror of
https://github.com/haproxy/haproxy.git
synced 2026-02-20 00:10:41 -05:00
BUG/MINOR: mux-h1: Mark the output buffer as full when the xfer is interrupted
When an outgoing HTX message is formatted to a raw message, if we fail to copy data of an HTX block into the output buffer, we mark it as full. Before it was only done calling the function buf_room_for_htx_data(). But this function is designed to optimize input processing. This patch must be backported to 2.0 and 1.9.
This commit is contained in:
parent
48fa033f28
commit
a61aa544b4
1 changed files with 18 additions and 13 deletions
31
src/mux_h1.c
31
src/mux_h1.c
|
|
@ -1576,7 +1576,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
vlen = sz;
|
||||
if (vlen > count) {
|
||||
if (type != HTX_BLK_DATA)
|
||||
goto copy;
|
||||
goto full;
|
||||
vlen = count;
|
||||
}
|
||||
|
||||
|
|
@ -1592,7 +1592,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
h1s->meth = sl->info.req.meth;
|
||||
h1_parse_req_vsn(h1m, sl);
|
||||
if (!htx_reqline_to_h1(sl, &tmp))
|
||||
goto copy;
|
||||
goto full;
|
||||
h1m->flags |= H1_MF_XFER_LEN;
|
||||
if (sl->flags & HTX_SL_F_BODYLESS)
|
||||
h1m->flags |= H1_MF_CLEN;
|
||||
|
|
@ -1607,7 +1607,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
h1s->status = sl->info.res.status;
|
||||
h1_parse_res_vsn(h1m, sl);
|
||||
if (!htx_stline_to_h1(sl, &tmp))
|
||||
goto copy;
|
||||
goto full;
|
||||
if (sl->flags & HTX_SL_F_XFER_LEN)
|
||||
h1m->flags |= H1_MF_XFER_LEN;
|
||||
if (sl->info.res.status < 200 &&
|
||||
|
|
@ -1654,7 +1654,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV))
|
||||
h1_adjust_case_outgoing_hdr(h1s, h1m, &n);
|
||||
if (!htx_hdr_to_h1(n, v, &tmp))
|
||||
goto copy;
|
||||
goto full;
|
||||
skip_hdr:
|
||||
h1m->state = H1_MSG_HDR_L2_LWS;
|
||||
break;
|
||||
|
|
@ -1676,7 +1676,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV))
|
||||
h1_adjust_case_outgoing_hdr(h1s, h1m, &n);
|
||||
if (!htx_hdr_to_h1(n, v, &tmp))
|
||||
goto copy;
|
||||
goto full;
|
||||
}
|
||||
h1s->flags |= H1S_F_HAVE_O_CONN;
|
||||
}
|
||||
|
|
@ -1694,7 +1694,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV))
|
||||
h1_adjust_case_outgoing_hdr(h1s, h1m, &n);
|
||||
if (!htx_hdr_to_h1(n, v, &tmp))
|
||||
goto copy;
|
||||
goto full;
|
||||
TRACE_STATE("add \"Transfer-Encoding: chunked\"", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1c->conn, h1s);
|
||||
h1m->flags |= H1_MF_CHNK;
|
||||
}
|
||||
|
|
@ -1712,14 +1712,14 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV))
|
||||
h1_adjust_case_outgoing_hdr(h1s, h1m, &n);
|
||||
if (!htx_hdr_to_h1(n, v, &tmp))
|
||||
goto copy;
|
||||
goto full;
|
||||
}
|
||||
TRACE_STATE("add server name header", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1c->conn, h1s);
|
||||
h1s->flags |= H1S_F_HAVE_SRV_NAME;
|
||||
}
|
||||
|
||||
if (!chunk_memcat(&tmp, "\r\n", 2))
|
||||
goto copy;
|
||||
goto full;
|
||||
|
||||
TRACE_PROTO((!(h1m->flags & H1_MF_RESP) ? "H1 request headers xferred" : "H1 response headers xferred"),
|
||||
H1_EV_TX_DATA|H1_EV_TX_HDRS, h1c->conn, h1s);
|
||||
|
|
@ -1756,7 +1756,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
/* Chunked message without explicit trailers */
|
||||
if (h1m->flags & H1_MF_CHNK) {
|
||||
if (!chunk_memcat(&tmp, "0\r\n\r\n", 5))
|
||||
goto copy;
|
||||
goto full;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -1764,7 +1764,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
/* If the message is not chunked, never
|
||||
* add the last chunk. */
|
||||
if ((h1m->flags & H1_MF_CHNK) && !chunk_memcat(&tmp, "0\r\n", 3))
|
||||
goto copy;
|
||||
goto full;
|
||||
TRACE_PROTO("sending message trailers", H1_EV_TX_DATA|H1_EV_TX_TLRS, h1c->conn, h1s, chn_htx);
|
||||
goto trailers;
|
||||
}
|
||||
|
|
@ -1775,7 +1775,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
v = htx_get_blk_value(chn_htx, blk);
|
||||
v.len = vlen;
|
||||
if (!htx_data_to_h1(v, &tmp, !!(h1m->flags & H1_MF_CHNK)))
|
||||
goto copy;
|
||||
goto full;
|
||||
|
||||
if (h1m->state == H1_MSG_DATA)
|
||||
TRACE_PROTO((!(h1m->flags & H1_MF_RESP) ? "H1 request payload data xferred" : "H1 response payload data xferred"),
|
||||
|
|
@ -1799,7 +1799,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
|
||||
if (type == HTX_BLK_EOT) {
|
||||
if (!chunk_memcat(&tmp, "\r\n", 2))
|
||||
goto copy;
|
||||
goto full;
|
||||
TRACE_PROTO((!(h1m->flags & H1_MF_RESP) ? "H1 request trailers xferred" : "H1 response trailers xferred"),
|
||||
H1_EV_TX_DATA|H1_EV_TX_TLRS, h1c->conn, h1s);
|
||||
}
|
||||
|
|
@ -1811,7 +1811,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV))
|
||||
h1_adjust_case_outgoing_hdr(h1s, h1m, &n);
|
||||
if (!htx_hdr_to_h1(n, v, &tmp))
|
||||
goto copy;
|
||||
goto full;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1871,6 +1871,11 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
|||
end:
|
||||
TRACE_LEAVE(H1_EV_TX_DATA, h1c->conn, h1s, chn_htx, (size_t[]){total});
|
||||
return total;
|
||||
|
||||
full:
|
||||
TRACE_STATE("h1c obuf full", H1_EV_TX_DATA|H1_EV_H1S_BLK, h1c->conn, h1s);
|
||||
h1c->flags |= H1C_F_OUT_FULL;
|
||||
goto copy;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
|
|
|||
Loading…
Reference in a new issue