From: Willy Tarreau Date: Thu, 10 Sep 2026 14:07:54 +0000 (+0200) Subject: MINOR: http-htx: condition uppercase acceptance in trailer names to HTTP_PF_UPCASE_OK X-Git-Tag: v3.5-dev7~35 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=94ddd9d3c567b2a3604c4539877bcfcdaab486a3;p=haproxy.git MINOR: http-htx: condition uppercase acceptance in trailer names to HTTP_PF_UPCASE_OK The trailers parser currently rejects uppercase chars in the name. Let's add a new flag to indicate that they are OK. This will be used by HTTP/1. However this is not sufficient, we now need to use isteqi() instead of isteq() to compare header names. Neither H2 nor H3 need to pass that new flag, hence why the change is minimal. --- diff --git a/include/haproxy/http-t.h b/include/haproxy/http-t.h index 3b3d6f383..7c6493cdf 100644 --- a/include/haproxy/http-t.h +++ b/include/haproxy/http-t.h @@ -112,6 +112,8 @@ enum { /* Flags used by HTTP parsers */ #define HTTP_PF_DIR_RES 0x00000001 /* direction: 0: request; 1: response */ +#define HTTP_PF_UPCASE_OK 0x00000002 /* upper case hdr names: 0: forbidden (h2/h3); 1: ok (h1) */ +#define HTTP_PF_PSEUDO_OK 0x00000004 /* pseudo headers: 0: forbidden (h1); 1: ok (h2/h3) */ /* HTTP parser error codes */ diff --git a/src/http_htx.c b/src/http_htx.c index 3cb6a816d..b74f49dab 100644 --- a/src/http_htx.c +++ b/src/http_htx.c @@ -2038,8 +2038,13 @@ enum http_parser_status http_trailers_to_htx(struct http_hdr *list, struct htx * * field-name = token */ for (i = 0; i < list[idx].n.len; i++) { - if ((uint8_t)(list[idx].n.ptr[i] - 'A') <= 'Z' - 'A' || - !HTTP_IS_TOKEN(list[idx].n.ptr[i])) { + if (!(flags & HTTP_PF_UPCASE_OK) && + (uint8_t)(list[idx].n.ptr[i] - 'A') <= 'Z' - 'A') { + ret = HTTP_PRS_INV_HNAME; + goto fail; + } + + if (!HTTP_IS_TOKEN(list[idx].n.ptr[i])) { ret = HTTP_PRS_INV_HNAME; goto fail; } @@ -2048,14 +2053,14 @@ enum http_parser_status http_trailers_to_htx(struct http_hdr *list, struct htx * /* All field names affecting decoding or routing are forbidden * in trailers. */ - if (isteq(list[idx].n, ist("host")) || - isteq(list[idx].n, ist("content-length")) || - isteq(list[idx].n, ist("connection")) || - isteq(list[idx].n, ist("proxy-connection")) || - isteq(list[idx].n, ist("keep-alive")) || - isteq(list[idx].n, ist("upgrade")) || - isteq(list[idx].n, ist("te")) || - isteq(list[idx].n, ist("transfer-encoding"))) { + if (isteqi(list[idx].n, ist("host")) || + isteqi(list[idx].n, ist("content-length")) || + isteqi(list[idx].n, ist("connection")) || + isteqi(list[idx].n, ist("proxy-connection")) || + isteqi(list[idx].n, ist("keep-alive")) || + isteqi(list[idx].n, ist("upgrade")) || + isteqi(list[idx].n, ist("te")) || + isteqi(list[idx].n, ist("transfer-encoding"))) { ret = HTTP_PRS_FORB_TRL; goto fail; }