mirror of
https://github.com/haproxy/haproxy.git
synced 2026-02-03 20:39:41 -05:00
MINOR: h3/hq-interop: restore function for standalone FIN receive
Previously, a function qcs_http_handle_standalone_fin() was implemented to handle a received standalone FIN, bypassing app_ops layer decoding. However, this was removed as app_ops layer interaction is necessary. For example, HTTP/3 checks that FIN is never sent on the control uni stream. This patch reintroduces qcs_http_handle_standalone_fin(), albeit in a slightly diminished version. Most importantly, it is now the responsibility of the app_ops layer itself to use it, to avoid the shortcoming described above. The main objective of this patch is to be able to support standalone FIN in HTTP/0.9 layer. This is easily done via the reintroduction of qcs_http_handle_standalone_fin() usage. This will be useful to perform testing, as standalone FIN is a corner case which can easily be broken.
This commit is contained in:
parent
6f95d0dad0
commit
861b11334c
4 changed files with 31 additions and 14 deletions
|
|
@ -8,6 +8,9 @@
|
|||
|
||||
size_t qcs_http_rcv_buf(struct qcs *qcs, struct buffer *buf, size_t count,
|
||||
char *fin);
|
||||
|
||||
int qcs_http_handle_standalone_fin(struct qcs *qcs);
|
||||
|
||||
size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count,
|
||||
char *fin);
|
||||
|
||||
|
|
|
|||
15
src/h3.c
15
src/h3.c
|
|
@ -1322,21 +1322,8 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
|
|||
}
|
||||
|
||||
if (!b_data(b) && fin && quic_stream_is_bidi(qcs->id)) {
|
||||
struct buffer *appbuf;
|
||||
struct htx *htx;
|
||||
int eom;
|
||||
|
||||
TRACE_PROTO("received FIN without data", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
|
||||
if (!(appbuf = qcc_get_stream_rxbuf(qcs))) {
|
||||
TRACE_ERROR("data buffer alloc failure", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
|
||||
qcc_set_error(qcs->qcc, H3_ERR_INTERNAL_ERROR, 1);
|
||||
goto err;
|
||||
}
|
||||
|
||||
htx = htx_from_buf(appbuf);
|
||||
eom = htx_set_eom(htx);
|
||||
htx_to_buf(htx, appbuf);
|
||||
if (!eom) {
|
||||
if (qcs_http_handle_standalone_fin(qcs)) {
|
||||
TRACE_ERROR("cannot set EOM", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
|
||||
qcc_set_error(qcs->qcc, H3_ERR_INTERNAL_ERROR, 1);
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ static ssize_t hq_interop_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
|
|||
/* hq-interop parser does not support buffer wrapping. */
|
||||
BUG_ON(b_data(b) != b_contig_data(b, 0));
|
||||
|
||||
if (!b_data(b) && fin && quic_stream_is_bidi(qcs->id)) {
|
||||
if (qcs_http_handle_standalone_fin(qcs))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* skip method */
|
||||
while (data && HTTP_IS_TOKEN(*ptr)) {
|
||||
ptr++;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,27 @@ size_t qcs_http_rcv_buf(struct qcs *qcs, struct buffer *buf, size_t count,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int qcs_http_handle_standalone_fin(struct qcs *qcs)
|
||||
{
|
||||
struct buffer *appbuf;
|
||||
struct htx *htx;
|
||||
int eom;
|
||||
|
||||
if (!(appbuf = qcc_get_stream_rxbuf(qcs)))
|
||||
goto err;
|
||||
|
||||
htx = htx_from_buf(appbuf);
|
||||
eom = htx_set_eom(htx);
|
||||
htx_to_buf(htx, appbuf);
|
||||
if (!eom)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* QUIC MUX snd_buf operation using HTX data. HTX data will be transferred from
|
||||
* <buf> to <qcs> stream buffer. Input buffer is expected to be of length
|
||||
* <count>. <fin> will be set to signal the last data to send for this stream.
|
||||
|
|
|
|||
Loading…
Reference in a new issue