diff --git a/include/haproxy/mux_h1-t.h b/include/haproxy/mux_h1-t.h index 450707e5b..23b582218 100644 --- a/include/haproxy/mux_h1-t.h +++ b/include/haproxy/mux_h1-t.h @@ -44,11 +44,12 @@ #define H1C_F_ERROR 0x00000400 /* A read error was detected (handled has an abort) */ #define H1C_F_SILENT_SHUT 0x00000800 /* if H1C is closed closed, silent (or dirty) shutdown must be performed */ #define H1C_F_ABRT_PENDING 0x00001000 /* An error must be sent (previous attempt failed) and H1 connection must be closed ASAP */ -#define H1C_F_WANT_SPLICE 0x00002000 /* Don't read into a buffer because we want to use or we are using splicing */ -#define H1C_F_WAIT_NEXT_REQ 0x00004000 /* waiting for the next request to start, use keep-alive timeout */ -#define H1C_F_UPG_H2C 0x00008000 /* set if an upgrade to h2 should be done */ -#define H1C_F_CO_MSG_MORE 0x00010000 /* set if CO_SFL_MSG_MORE must be set when calling xprt->snd_buf() */ -#define H1C_F_CO_STREAMER 0x00020000 /* set if CO_SFL_STREAMER must be set when calling xprt->snd_buf() */ +#define H1C_F_ABRTED 0x00002000 /* An error must be sent (previous attempt failed) and H1 connection must be closed ASAP */ +#define H1C_F_WANT_SPLICE 0x00004000 /* Don't read into a buffer because we want to use or we are using splicing */ +#define H1C_F_WAIT_NEXT_REQ 0x00008000 /* waiting for the next request to start, use keep-alive timeout */ +#define H1C_F_UPG_H2C 0x00010000 /* set if an upgrade to h2 should be done */ +#define H1C_F_CO_MSG_MORE 0x00020000 /* set if CO_SFL_MSG_MORE must be set when calling xprt->snd_buf() */ +#define H1C_F_CO_STREAMER 0x00040000 /* set if CO_SFL_STREAMER must be set when calling xprt->snd_buf() */ /* 0x00040000 - 0x40000000 unusued*/ #define H1C_F_IS_BACK 0x80000000 /* Set on outgoing connection */ @@ -67,9 +68,9 @@ static forceinline char *h1c_show_flags(char *buf, size_t len, const char *delim _(H1C_F_OUT_ALLOC, _(H1C_F_OUT_FULL, _(H1C_F_IN_ALLOC, _(H1C_F_IN_FULL, _(H1C_F_IN_SALLOC, _(H1C_F_EOS, _(H1C_F_ERR_PENDING, _(H1C_F_ERROR, - _(H1C_F_SILENT_SHUT, _(H1C_F_ABRT_PENDING, _(H1C_F_WANT_SPLICE, - _(H1C_F_WAIT_NEXT_REQ, _(H1C_F_UPG_H2C, _(H1C_F_CO_MSG_MORE, - _(H1C_F_CO_STREAMER, _(H1C_F_IS_BACK)))))))))))))))); + _(H1C_F_SILENT_SHUT, _(H1C_F_ABRT_PENDING, _(H1C_F_ABRTED, + _(H1C_F_WANT_SPLICE, _(H1C_F_WAIT_NEXT_REQ, _(H1C_F_UPG_H2C, _(H1C_F_CO_MSG_MORE, + _(H1C_F_CO_STREAMER, _(H1C_F_IS_BACK))))))))))))))))); /* epilogue */ _(~0U); return buf; diff --git a/src/mux_h1.c b/src/mux_h1.c index 5f3f121e2..d600c78f8 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -852,12 +852,8 @@ static void h1s_destroy(struct h1s *h1s) h1c->flags &= ~(H1C_F_WANT_SPLICE| H1C_F_OUT_FULL|H1C_F_OUT_ALLOC|H1C_F_IN_SALLOC| H1C_F_CO_MSG_MORE|H1C_F_CO_STREAMER); - if (h1s->flags & H1S_F_ERROR_MASK) { - h1c->flags |= H1C_F_ERROR; - TRACE_ERROR("h1s on error, set error on h1c", H1_EV_H1S_END|H1_EV_H1C_ERR, h1c->conn, h1s); - } - if (!(h1c->flags & (H1C_F_EOS|H1C_F_ERR_PENDING|H1C_F_ERROR)) && /* No error/read0 */ + if (!(h1c->flags & (H1C_F_EOS|H1C_F_ERR_PENDING|H1C_F_ERROR|H1C_F_ABRT_PENDING|H1C_F_ABRTED)) && /* No error/read0/abort */ h1_is_alive(h1c) && /* still alive */ (h1s->flags & H1S_F_WANT_KAL) && /* K/A possible */ h1s->req.state == H1_MSG_DONE && h1s->res.state == H1_MSG_DONE) { /* req/res in DONE state */ @@ -2638,7 +2634,7 @@ static int h1_send_error(struct h1c *h1c) h1s_destroy(h1c->h1s); } - h1c->flags &= ~H1C_F_ABRT_PENDING; + h1c->flags = (h1c->flags & ~H1C_F_ABRT_PENDING) | H1C_F_ABRTED; h1c->state = H1_CS_CLOSING; out: TRACE_LEAVE(H1_EV_H1C_ERR, h1c->conn); @@ -2678,6 +2674,7 @@ static int h1_handle_parsing_error(struct h1c *h1c) if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) { h1c->state = H1_CS_CLOSING; + h1c->flags |= H1C_F_ABRTED; goto end; } @@ -2710,6 +2707,7 @@ static int h1_handle_not_impl_err(struct h1c *h1c) if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) { h1c->state = H1_CS_CLOSING; + h1c->flags |= H1C_F_ABRTED; goto end; } @@ -2739,6 +2737,7 @@ static int h1_handle_req_tout(struct h1c *h1c) if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) { h1c->state = H1_CS_CLOSING; + h1c->flags |= H1C_F_ABRTED; goto end; } @@ -3011,7 +3010,7 @@ static int h1_process(struct h1c * h1c) * - a read0 was received or * - a silent shutdown was emitted and all outgoing data sent */ - if ((h1c->flags & (H1C_F_EOS|H1C_F_ERROR|H1C_F_ABRT_PENDING)) || + if ((h1c->flags & (H1C_F_EOS|H1C_F_ERROR|H1C_F_ABRT_PENDING|H1C_F_ABRTED)) || (h1c->state >= H1_CS_CLOSING && (h1c->flags & H1C_F_SILENT_SHUT) && !b_data(&h1c->obuf))) { if (h1c->state != H1_CS_RUNNING) { /* No stream connector or upgrading */