From 88765b69e0f6b80b9330f65955d62d884d3e6388 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 25 Feb 2026 15:37:30 +0100 Subject: [PATCH] MINOR: h1-htx: Reports non-HTTP version via dedicated flags 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 | 2 +- include/haproxy/htx-t.h | 1 + src/h1_htx.c | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/haproxy/h1.h b/include/haproxy/h1.h index d77ed1e1f..a9d01d047 100644 --- a/include/haproxy/h1.h +++ b/include/haproxy/h1.h @@ -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 diff --git a/include/haproxy/htx-t.h b/include/haproxy/htx-t.h index 046ac167a..3d4ecb7fe 100644 --- a/include/haproxy/htx-t.h +++ b/include/haproxy/htx-t.h @@ -141,6 +141,7 @@ #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 diff --git a/src/h1_htx.c b/src/h1_htx.c index b956747c2..2fd6540ba 100644 --- a/src/h1_htx.c +++ b/src/h1_htx.c @@ -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) {