diff --git a/src/mux_h1.c b/src/mux_h1.c index 2bb532810..885269909 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -1568,7 +1568,10 @@ static size_t h1_process_input(struct h1c *h1c, struct buffer *buf, size_t count h1s->cs->flags &= ~CS_FL_MAY_SPLICE; } - if (h1s->flags & H1S_F_PARSING_DONE) + /* Don't set EOI on the conn-stream for protocol upgrade requests, wait + * the response to do so or not depending on the status code. + */ + if ((h1s->flags & H1S_F_PARSING_DONE) && !(h1m->flags & H1_MF_CONN_UPG)) h1s->cs->flags |= CS_FL_EOI; if (h1s_data_pending(h1s) && !htx_is_empty(htx)) @@ -1577,8 +1580,10 @@ static size_t h1_process_input(struct h1c *h1c, struct buffer *buf, size_t count h1s->cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM); if (h1s->flags & H1S_F_REOS) { h1s->cs->flags |= CS_FL_EOS; - if (h1m->state == H1_MSG_TUNNEL) + if (h1m->state >= H1_MSG_DONE) { + /* DONE or TUNNEL, set EOI on the conn-stream */ h1s->cs->flags |= CS_FL_EOI; + } else if (h1m->state > H1_MSG_LAST_LF && h1m->state < H1_MSG_DONE) h1s->cs->flags |= CS_FL_ERROR; } @@ -2023,6 +2028,13 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun htx_to_buf(chn_htx, buf); out: + /* Both the request and the response reached the DONE state. So set EOI + * flag on the conn-stream. Most of time, the flag will already be set, + * except for protocol upgrades. + */ + if (h1s->cs && h1s->req.state == H1_MSG_DONE && h1s->res.state == H1_MSG_DONE) + h1s->cs->flags |= CS_FL_EOI; + if (!buf_room_for_htx_data(&h1c->obuf)) { TRACE_STATE("h1c obuf full", H1_EV_TX_DATA|H1_EV_H1S_BLK, h1c->conn, h1s); h1c->flags |= H1C_F_OUT_FULL;