From: Christopher Faulet Date: Wed, 2 Dec 2020 15:08:38 +0000 (+0100) Subject: MINOR: mux-h1: Add a flag on H1 streams with a response known to be bodyless X-Git-Tag: v2.4-dev7~94 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5696f5450ee2f14ba962ef365569599be33df658;p=thirdparty%2Fhaproxy.git MINOR: mux-h1: Add a flag on H1 streams with a response known to be bodyless In HTTP/1, responses to HEAD requests and 204/304 must not have payload. The H1S_F_BODYLESS_RESP flag is not set on streams that should handle such responses, on the client side and the server side. On the client side, this flag is set when a HEAD request is parsed and when a 204/304 response is emitted. On the server side, this happends when a HEAD request is emitted or a 204/304 response is parsed. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index 332a3c347a..277220b2e7 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -79,6 +79,7 @@ #define H1S_F_WANT_CLO 0x00000040 #define H1S_F_WANT_MSK 0x00000070 #define H1S_F_NOT_FIRST 0x00000080 /* The H1 stream is not the first one */ +#define H1S_F_BODYLESS_RESP 0x00000100 /* Bodyless response message */ /* 0x00000200 unsued */ #define H1S_F_NOT_IMPL_ERROR 0x00000400 /* Set when a feature is not implemented during the message parsing */ @@ -1335,11 +1336,16 @@ static size_t h1_process_headers(struct h1s *h1s, struct h1m *h1m, struct htx *h h1_capture_bad_message(h1s->h1c, h1s, h1m, buf); } - if (!(h1m->flags & H1_MF_RESP)) + if (!(h1m->flags & H1_MF_RESP)) { h1s->meth = h1sl.rq.meth; - else + if (h1s->meth == HTTP_METH_HEAD) + h1s->flags |= H1S_F_BODYLESS_RESP; + } + else { h1s->status = h1sl.st.status; - + if (h1s->status == 204 || h1s->status == 304) + h1s->flags |= H1S_F_BODYLESS_RESP; + } h1_process_input_conn_mode(h1s, h1m, htx); *ofs += ret; @@ -1772,6 +1778,8 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun if (sl->flags & HTX_SL_F_BODYLESS) h1m->flags |= H1_MF_CLEN; h1m->state = H1_MSG_HDR_FIRST; + if (h1s->meth == HTTP_METH_HEAD) + h1s->flags |= H1S_F_BODYLESS_RESP; if (h1c->flags & H1C_F_WAIT_OUTPUT) { h1c->flags &= ~H1C_F_WAIT_OUTPUT; h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event); @@ -1790,9 +1798,10 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun goto full; if (sl->flags & HTX_SL_F_XFER_LEN) h1m->flags |= H1_MF_XFER_LEN; - if (sl->info.res.status < 200 && - (sl->info.res.status == 100 || sl->info.res.status >= 102)) + if (h1s->status < 200 && (h1s->status == 100 || h1s->status >= 102)) h1s->flags |= H1S_F_HAVE_O_CONN; + else if (h1s->status == 204 || h1s->status == 304) + h1s->flags |= H1S_F_BODYLESS_RESP; h1m->state = H1_MSG_HDR_FIRST; break;