]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: h1: Properly reset h1m flags when headers parsing is restarted
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 1 Dec 2021 17:01:48 +0000 (18:01 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 2 Dec 2021 08:46:29 +0000 (09:46 +0100)
If H1 headers are not fully received at once, the parsing is restarted a
last time when all headers are finally received. When this happens, the h1m
flags are sanitized to remove all value set during parsing.

But some flags where erroneously preserved. Among others, H1_MF_TE_CHUNKED
flag was not removed, what could lead to parsing error.

To fix the bug and make things easy, a mask has been added with all flags
that must be preserved. It will be more stable. This mask is used to
sanitize h1m flags.

This patch should fix the issue #1469. It must be backported to 2.5.

include/haproxy/h1.h
src/h1.c

index 7ebd9c84bc02a496f0a76a9ff21b73677fc45273..1891c81ce9be4ad8ca91cc47987d6cbec2c16d77 100644 (file)
@@ -99,6 +99,14 @@ enum h1m_state {
 #define H1_MF_TE_CHUNKED        0x00010000 // T-E "chunked"
 #define H1_MF_TE_OTHER          0x00020000 // T-E other than supported ones found (only "chunked" is supported for now)
 
+/* Mask to use to reset H1M flags when we restart headers parsing.
+ *
+ * WARNING: Don't forget to update it if a new flag must be preserved when
+ *          headers parsing is restarted.
+ */
+#define H1_MF_RESTART_MASK    (H1_MF_RESP|H1_MF_TOLOWER|H1_MF_NO_PHDR|H1_MF_HDRS_ONLY| \
+                              H1_MF_CLEAN_CONN_HDR|H1_MF_METH_CONNECT|H1_MF_METH_HEAD)
+
 /* Note: for a connection to be persistent, we need this for the request :
  *   - one of CLEN or CHNK
  *   - version 1.0 and KAL and not CLO
index 99b9c2993b235b484b4546436d079c85adbef5a0..dd208f3235b514442e2d9575e5b2905521685bbd 100644 (file)
--- a/src/h1.c
+++ b/src/h1.c
@@ -1040,7 +1040,7 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
        return -2;
 
  restart:
-       h1m->flags &= ~(H1_MF_VER_11|H1_MF_CLEN|H1_MF_XFER_ENC|H1_MF_CHNK|H1_MF_CONN_KAL|H1_MF_CONN_CLO|H1_MF_CONN_UPG);
+       h1m->flags &= H1_MF_RESTART_MASK;
        h1m->curr_len = h1m->body_len = h1m->next  = 0;
        if (h1m->flags & H1_MF_RESP)
                h1m->state = H1_MSG_RPBEFORE;