]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: h1-htx: Reports non-HTTP version via dedicated flags
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 25 Feb 2026 14:37:30 +0000 (15:37 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 5 Mar 2026 14:34:46 +0000 (15:34 +0100)
Now, when the HTTP version format is not strictly valid, flags are set on
the h1 parser and the HTX start-line. H1_MF_NOT_HTTP is set on the H1 parser
and HTX_SL_F_NOT_HTTP is set on the HTX start-line. These flags were
introduced to avoid parsing again and again the version to know if it is a
valid version or not, escpecially because it is most of time valid.

include/haproxy/h1.h
include/haproxy/htx-t.h
src/h1_htx.c

index d77ed1e1f175be1809e1013381bbbeb518fbcb39..a9d01d0477282022620a1cfd198b00a03fbc5150 100644 (file)
@@ -99,7 +99,7 @@ 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)
 #define H1_MF_UPG_H2C           0x00040000 // "h2c" or "h2" used as upgrade token
-
+#define H1_MF_NOT_HTTP           0x00080000 // Not an HTTP message (e.g "RTSP", only possible if invalid message are accepted)
 /* 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
index 046ac167a97e1aa29b68f321fdfb1ac4c8eeac38..3d4ecb7fe41c86be0c7a8b07c4e94198aaae91e3 100644 (file)
 #define HTX_SL_F_NORMALIZED_URI 0x00000800 /* The received URI is normalized (an implicit absolute-uri form) */
 #define HTX_SL_F_CONN_UPG       0x00001000 /* The message contains "connection: upgrade" header */
 #define HTX_SL_F_BODYLESS_RESP  0x00002000 /* The response to this message is bodyloess (only for reqyest) */
+#define HTX_SL_F_NOT_HTTP       0x00004000 /* Not an HTTP message (e.g "RTSP", only possible if invalid message are accepted) */
 
 /* This function is used to report flags in debugging tools. Please reflect
  * below any single-bit flag addition above in the same order via the
index b956747c2886ab1107424f1ea68480aa89920dc9..2fd6540ba56a839b9ccd787952542d7a5d679f36 100644 (file)
@@ -79,6 +79,16 @@ static int h1_process_req_vsn(struct h1m *h1m, union h1_sl *sl)
                sl->rq.v = ist("HTTP/1.0");
                return 1;
        }
+       else {
+               if (sl->rq.v.len != 8 ||
+                   !istnmatch(sl->rq.v, ist("HTTP/"), 5) ||
+                   !isdigit((unsigned char)*(sl->rq.v.ptr + 5)) ||
+                   *(sl->rq.v.ptr + 6) != '.' ||
+                   !isdigit((unsigned char)*(sl->rq.v.ptr + 7))) {
+                       h1m->flags |= H1_MF_NOT_HTTP;
+                       return 1;
+               }
+       }
 
        if ((sl->rq.v.len == 8) &&
            ((*(sl->rq.v.ptr + 5) > '1') ||
@@ -106,6 +116,16 @@ static int h1_process_res_vsn(struct h1m *h1m, union h1_sl *sl)
                    !isdigit((unsigned char)*(sl->st.v.ptr + 7)))
                        return 0;
        }
+       else {
+               if (sl->st.v.len != 8 ||
+                   !istnmatch(sl->st.v, ist("HTTP/"), 5) ||
+                   !isdigit((unsigned char)*(sl->st.v.ptr + 5)) ||
+                   *(sl->st.v.ptr + 6) != '.' ||
+                   !isdigit((unsigned char)*(sl->st.v.ptr + 7))) {
+                       h1m->flags |= H1_MF_NOT_HTTP;
+                       return 1;
+               }
+       }
 
        if ((sl->st.v.len == 8) &&
            ((*(sl->st.v.ptr + 5) > '1') ||
@@ -124,6 +144,8 @@ static unsigned int h1m_htx_sl_flags(struct h1m *h1m)
                flags |= HTX_SL_F_IS_RESP;
        if (h1m->flags & H1_MF_VER_11)
                flags |= HTX_SL_F_VER_11;
+       if (h1m->flags & H1_MF_NOT_HTTP)
+               flags |= HTX_SL_F_NOT_HTTP;
        if (h1m->flags & H1_MF_XFER_ENC)
                flags |= HTX_SL_F_XFER_ENC;
        if (h1m->flags & H1_MF_XFER_LEN) {