From: Amaury Denoyelle Date: Fri, 30 May 2025 16:00:48 +0000 (+0200) Subject: MINOR: h3: adjust auth request encoding or fallback to host X-Git-Tag: v3.3-dev2~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=555ec99d437f3c55afeb9056e3ba8affd68fafd6;p=thirdparty%2Fhaproxy.git MINOR: h3: adjust auth request encoding or fallback to host Implement proper encoding of HTTP/3 authority pseudo-header during request transcoding on the backend side. A pseudo-header :authority is encoded if a value can be extracted from HTX start-line. A special check is also implemented to ensure that a host header is not encoded if :authority already is. A new function qpack_encode_auth() is defined to implement QPACK encoding of :authority header using literal field line with name ref. --- diff --git a/include/haproxy/qpack-enc.h b/include/haproxy/qpack-enc.h index 29136191b..7bc3783a4 100644 --- a/include/haproxy/qpack-enc.h +++ b/include/haproxy/qpack-enc.h @@ -11,6 +11,7 @@ int qpack_encode_int_status(struct buffer *out, unsigned int status); int qpack_encode_method(struct buffer *out, enum http_meth_t meth, struct ist other); int qpack_encode_scheme(struct buffer *out, const struct ist scheme); int qpack_encode_path(struct buffer *out, const struct ist path); +int qpack_encode_auth(struct buffer *out, const struct ist auth); int qpack_encode_header(struct buffer *out, const struct ist n, const struct ist v); #endif /* QPACK_ENC_H_ */ diff --git a/src/h3.c b/src/h3.c index 41d9250b1..0f642daee 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1797,9 +1797,10 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx) if (qpack_encode_path(&headers_buf, uri)) goto err; - /* :authority */ - if (h3_encode_header(&headers_buf, ist(":authority"), ist("127.0.0.1:20443"))) - goto err; + if (istlen(auth)) { + if (qpack_encode_auth(&headers_buf, auth)) + goto err; + } /* Encode every parsed headers, stop at empty one. */ for (hdr = 0; hdr < sizeof(list) / sizeof(list[0]); ++hdr) { @@ -1830,6 +1831,10 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx) list[hdr].v = ist("trailers"); } + /* host only encoded if authority is not set */ + if (istlen(auth) && isteq(list[hdr].n, ist("host"))) + continue; + if (h3_encode_header(&headers_buf, list[hdr].n, list[hdr].v)) goto err; } diff --git a/src/qpack-enc.c b/src/qpack-enc.c index 5f4694979..f6a18397f 100644 --- a/src/qpack-enc.c +++ b/src/qpack-enc.c @@ -228,6 +228,25 @@ int qpack_encode_path(struct buffer *out, const struct ist path) } } +/* Encode pseudo-header authority defined to into buffer. + * + * Returns 0 on success else non-zero. + */ +int qpack_encode_auth(struct buffer *out, const struct ist auth) +{ + size_t sz; + + sz = 1 + qpack_get_prefix_int_size(istlen(auth), 7) + istlen(auth); + if (b_room(out) < sz) + return 1; + + qpack_encode_prefix_integer(out, 0, 4, 0x50); + qpack_encode_prefix_integer(out, istlen(auth), 7, 0); + for (size_t i = 0; i < istlen(auth); ++i) + b_putchr(out, istptr(auth)[i]); + return 0; +} + /* Returns 0 on success else non-zero. */ int qpack_encode_field_section_line(struct buffer *out) {