diff --git a/include/haproxy/mux_quic.h b/include/haproxy/mux_quic.h index 8b861f700..872c5eafe 100644 --- a/include/haproxy/mux_quic.h +++ b/include/haproxy/mux_quic.h @@ -15,6 +15,8 @@ void qcc_set_error(struct qcc *qcc, int err, int app); struct qcs *qcc_init_stream_local(struct qcc *qcc, int bidi); struct stconn *qcs_attach_sc(struct qcs *qcs, struct buffer *buf, char fin); +int qcs_is_close_local(struct qcs *qcs); +int qcs_is_close_remote(struct qcs *qcs); struct buffer *qcs_get_buf(struct qcs *qcs, struct buffer *bptr); int qcs_subscribe(struct qcs *qcs, int event_type, struct wait_event *es); diff --git a/src/h3.c b/src/h3.c index 94b50ba90..b10851baa 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1673,6 +1673,31 @@ static size_t h3_snd_buf(struct qcs *qcs, struct htx *htx, size_t count) } } + /* RFC 9114 4.1. HTTP Message Framing + * + * A server can send a complete response prior to the client sending an + * entire request if the response does not depend on any portion of the + * request that has not been sent and received. When the server does not + * need to receive the remainder of the request, it MAY abort reading + * the request stream, send a complete response, and cleanly close the + * sending part of the stream. The error code H3_NO_ERROR SHOULD be used + * when requesting that the client stop sending on the request stream. + * Clients MUST NOT discard complete responses as a result of having + * their request terminated abruptly, though clients can always discard + * responses at their discretion for other reasons. If the server sends + * a partial or complete response but does not abort reading the + * request, clients SHOULD continue sending the content of the request + * and close the stream normally. + */ + if (unlikely((htx->flags & HTX_FL_EOM) && htx_is_empty(htx)) && + !qcs_is_close_remote(qcs)) { + /* Generate a STOP_SENDING if full response transferred before + * receiving the full request. + */ + qcs->err = H3_NO_ERROR; + qcc_abort_stream_read(qcs); + } + out: return total; } diff --git a/src/mux_quic.c b/src/mux_quic.c index 2c400b446..698bacf08 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -403,12 +403,12 @@ static void qcs_close_remote(struct qcs *qcs) } } -static int qcs_is_close_local(struct qcs *qcs) +int qcs_is_close_local(struct qcs *qcs) { return qcs->st == QC_SS_HLOC || qcs->st == QC_SS_CLO; } -static int qcs_is_close_remote(struct qcs *qcs) +int qcs_is_close_remote(struct qcs *qcs) { return qcs->st == QC_SS_HREM || qcs->st == QC_SS_CLO; }