From 5696f5450ee2f14ba962ef365569599be33df658 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 2 Dec 2020 16:08:38 +0100 Subject: [PATCH] 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. --- src/mux_h1.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mux_h1.c b/src/mux_h1.c index 332a3c3..277220b 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; -- 1.7.10.4