]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-h1: Add a flag on H1 streams with a response known to be bodyless
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 2 Dec 2020 15:08:38 +0000 (16:08 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 28 Jan 2021 15:37:14 +0000 (16:37 +0100)
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

index 332a3c347a273e8dbc5427086d535b909f557a51..277220b2e765e01f34b8676bbd0e08766082af2b 100644 (file)
@@ -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;