BUG/MINOR: mux-h1: Fix condition to set EOI on SE during zero-copy forwarding

During zero-copy data forwarding, the producer must set the EOI flag on the SE
when end of the message is reached. It is already done but there is a case where
this flag is set while it should not. When a request wants to perform a protocol
upgrade and it is waiting for the server response, the flag must not be set
because the HTTP message is finished but some data are possibly still expected,
depending on the server response. On a 101-switching-protocol, more data will be
sent because the producer is switch to TUNNEL state.

So, now, the right condition is used. In DONE state, SE_FL_EOI flag is set on the sedesc iff:

  - it is the response
  - it is the request and the response is also in DONNE state
  - it is a request but no a protocol upgrade nor a CONNECT

This patch must be backported as far as 2.9.

(cherry picked from commit 6b39e245e1d58698310fbb06b8122423232be9a4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
This commit is contained in:
Christopher Faulet 2024-10-02 09:25:28 +02:00
parent c8cde77467
commit f4441c8805

View File

@ -4978,11 +4978,18 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
h1m->curr_len -= total;
if (!h1m->curr_len) {
if (h1m->flags & H1_MF_CLEN) {
/* Set EOI on stream connector in DONE state iff:
* - it is a response
* - it is a request and the response is DONE too
* - it is a request but no a protocol upgrade nor a CONNECT
*
* If not set, Wait the response to do so or not depending on the status
* code.
*/
h1m->state = H1_MSG_DONE;
se_fl_set(h1s->sd, SE_FL_EOI); /* TODO: this line is tricky and must be evaluated first
* Its purpose is to avoid to set CO_SFL_MSG_MORE on the
* next calls to ->complete_fastfwd().
*/
if ((h1m->flags & H1_MF_RESP) || (h1s->res.state == H1_MSG_DONE) ||
((h1s->meth != HTTP_METH_CONNECT) && !(h1m->flags & H1_MF_CONN_UPG)))
se_fl_set(h1s->sd, SE_FL_EOI);
}
else
h1m->state = H1_MSG_CHUNK_CRLF;