From 7bfb66d2b1a361db824cf4e809a094f09d166acc Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 25 Feb 2026 16:10:28 +0100 Subject: [PATCH] MINOR: http-ana: Save the message version in the http_msg structure When the request or the response is received, the numerical value of the message version is now saved. To do so, the field "vsn" was added in the http_msg structure. It is an unsigned char. The 4 MSB bits are used for the major digit and the 4 LSB bits for the minor one. Of couse, the version must be valid. the HTX_SL_F_NOT_HTTP flag of the start-line is used to be sure the version is valid. But because this flag is quite new, we also take care the string representation of the version is 8 bytes length. 0 means the version is not valid. --- include/haproxy/http_ana-t.h | 3 ++- src/http_ana.c | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/haproxy/http_ana-t.h b/include/haproxy/http_ana-t.h index aa496e394..56b9e5b83 100644 --- a/include/haproxy/http_ana-t.h +++ b/include/haproxy/http_ana-t.h @@ -228,7 +228,8 @@ enum h1_state { */ struct http_msg { enum h1_state msg_state; /* where we are in the current message parsing */ - /* 3 bytes unused here */ + unsigned char vsn; /* HTTP version, 4 bits per digit */ + /* 2 bytes unused here */ unsigned int flags; /* flags describing the message (HTTP version, ...) */ struct channel *chn; /* pointer to the channel transporting the message */ }; diff --git a/src/http_ana.c b/src/http_ana.c index fa061b698..399c75906 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -97,7 +97,6 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit) struct htx *htx; struct htx_sl *sl; char http_ver; - int len; DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn, msg); @@ -131,14 +130,16 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit) htx = htxbuf(&req->buf); sl = http_get_stline(htx); - len = HTX_SL_REQ_VLEN(sl); - if (len < 6) { + if ((sl->flags & HTX_SL_F_NOT_HTTP) || HTX_SL_REQ_VLEN(sl) != 8) { + /* Not an HTTP request */ http_ver = 0; + msg->vsn = 0; } else { char *ptr; ptr = HTX_SL_REQ_VPTR(sl); + msg->vsn = ((ptr[5] - '0') << 4) + (ptr[7] - '0'); http_ver = ptr[5] - '0'; } @@ -1470,6 +1471,18 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) BUG_ON(htx_get_first_type(htx) != HTX_BLK_RES_SL); sl = http_get_stline(htx); + if ((sl->flags & HTX_SL_F_NOT_HTTP) || HTX_SL_RES_VLEN(sl) != 8) { + /* Not an HTTP response */ + msg->vsn = 0; + } + else { + /* HTTP response from a server, use it to set the response version */ + char *ptr; + + ptr = HTX_SL_RES_VPTR(sl); + msg->vsn = ((ptr[5] - '0') << 4) + (ptr[7] - '0'); + } + /* Adjust server's health based on status code. Note: status codes 501 * and 505 are triggered on demand by client request, so we must not * count them as server failures.