mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MINOR: h3: do not consider missing buf room as error on trailers
Improve h3_resp_trailers_send() return value to be similar with h3_resp_data_send(). In particular, if QCS Tx buffer has not enough space for trailer encoding, 0 is returned instead of an error value, with QC_SF_BLK_MROOM set. This unify HTTP/3 headers/data/trailers encoding functions. Negative error codes are limited to fatal error which should cause a connection closure. Not enough output buffer space is only a transient condition which is reflect by the QC_SF_BLK_MROOM flag.
This commit is contained in:
parent
14673fe54d
commit
8df47442d2
41
src/h3.c
41
src/h3.c
@ -1631,7 +1631,8 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
* Caller is responsible to emit an empty QUIC STREAM frame to signal the end
|
* Caller is responsible to emit an empty QUIC STREAM frame to signal the end
|
||||||
* of the stream.
|
* of the stream.
|
||||||
*
|
*
|
||||||
* Returns the size of HTX blocks removed.
|
* Returns the size of HTX blocks removed. A negative error code is returned in
|
||||||
|
* case of a fatal error which should caused a connection closure.
|
||||||
*/
|
*/
|
||||||
static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
||||||
{
|
{
|
||||||
@ -1680,8 +1681,19 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
* frame. Mux will send an empty QUIC STREAM frame with FIN.
|
* frame. Mux will send an empty QUIC STREAM frame with FIN.
|
||||||
*/
|
*/
|
||||||
TRACE_DATA("skipping trailer", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
TRACE_DATA("skipping trailer", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
||||||
|
|
||||||
|
/* Truncate UNUSED / EOT HTX blocks. */
|
||||||
|
blk = htx_get_head_blk(htx);
|
||||||
|
while (blk) {
|
||||||
|
type = htx_get_blk_type(blk);
|
||||||
|
ret += htx_get_blksz(blk);
|
||||||
|
blk = htx_remove_blk(htx, blk);
|
||||||
|
if (type == HTX_BLK_EOT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
list[hdr].n = ist("");
|
list[hdr].n = ist("");
|
||||||
|
|
||||||
if (!(res = qcc_get_stream_txbuf(qcs))) {
|
if (!(res = qcc_get_stream_txbuf(qcs))) {
|
||||||
@ -1692,8 +1704,9 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
|
|
||||||
/* At least 9 bytes to store frame type + length as a varint max size */
|
/* At least 9 bytes to store frame type + length as a varint max size */
|
||||||
if (b_room(res) < 9) {
|
if (b_room(res) < 9) {
|
||||||
|
TRACE_STATE("not enough room for trailers frame", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
||||||
qcs->flags |= QC_SF_BLK_MROOM;
|
qcs->flags |= QC_SF_BLK_MROOM;
|
||||||
goto err;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Force buffer realignment as size required to encode headers is unknown. */
|
/* Force buffer realignment as size required to encode headers is unknown. */
|
||||||
@ -1703,8 +1716,9 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
headers_buf = b_make(b_peek(res, b_data(res) + 9), b_contig_space(res) - 9, 0, 0);
|
headers_buf = b_make(b_peek(res, b_data(res) + 9), b_contig_space(res) - 9, 0, 0);
|
||||||
|
|
||||||
if (qpack_encode_field_section_line(&headers_buf)) {
|
if (qpack_encode_field_section_line(&headers_buf)) {
|
||||||
|
TRACE_STATE("not enough room for trailers section line", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
||||||
qcs->flags |= QC_SF_BLK_MROOM;
|
qcs->flags |= QC_SF_BLK_MROOM;
|
||||||
goto err;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
tail = b_tail(&headers_buf);
|
tail = b_tail(&headers_buf);
|
||||||
@ -1724,8 +1738,9 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (qpack_encode_header(&headers_buf, list[hdr].n, list[hdr].v)) {
|
if (qpack_encode_header(&headers_buf, list[hdr].n, list[hdr].v)) {
|
||||||
|
TRACE_STATE("not enough room for all trailers", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
||||||
qcs->flags |= QC_SF_BLK_MROOM;
|
qcs->flags |= QC_SF_BLK_MROOM;
|
||||||
goto err;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1735,11 +1750,10 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
* frame. Mux will send an empty QUIC STREAM frame with FIN.
|
* frame. Mux will send an empty QUIC STREAM frame with FIN.
|
||||||
*/
|
*/
|
||||||
TRACE_DATA("skipping trailer", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
TRACE_DATA("skipping trailer", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
/* Now that all headers are encoded, we are certain that res buffer is
|
/* Now that all headers are encoded, we are certain that res
|
||||||
* big enough.
|
* buffer is big enough.
|
||||||
*/
|
*/
|
||||||
TRACE_DATA("encoding TRAILERS frame", H3_EV_TX_FRAME|H3_EV_TX_HDR,
|
TRACE_DATA("encoding TRAILERS frame", H3_EV_TX_FRAME|H3_EV_TX_HDR,
|
||||||
qcs->qcc->conn, qcs);
|
qcs->qcc->conn, qcs);
|
||||||
@ -1747,9 +1761,9 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
if (!b_quic_enc_int(res, b_data(&headers_buf), 8))
|
if (!b_quic_enc_int(res, b_data(&headers_buf), 8))
|
||||||
ABORT_NOW();
|
ABORT_NOW();
|
||||||
b_add(res, b_data(&headers_buf));
|
b_add(res, b_data(&headers_buf));
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
/* Encoding success, truncate HTX blocks until EOT. */
|
||||||
ret = 0;
|
|
||||||
blk = htx_get_head_blk(htx);
|
blk = htx_get_head_blk(htx);
|
||||||
while (blk) {
|
while (blk) {
|
||||||
type = htx_get_blk_type(blk);
|
type = htx_get_blk_type(blk);
|
||||||
@ -1759,6 +1773,7 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
TRACE_LEAVE(H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
TRACE_LEAVE(H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -1962,10 +1977,8 @@ static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If an error occurred, either buffer space or connection error
|
/* If an error occured, connection error must be set to break from the current loop. */
|
||||||
* must be set to break current loop.
|
BUG_ON(ret < 0 && !h3c->err);
|
||||||
*/
|
|
||||||
BUG_ON(ret < 0 && !(qcs->flags & QC_SF_BLK_MROOM) && !h3c->err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interrupt sending on connection error. */
|
/* Interrupt sending on connection error. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user