]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: h3: adjust auth request encoding or fallback to host
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 30 May 2025 16:00:48 +0000 (18:00 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 16 Jun 2025 16:11:09 +0000 (18:11 +0200)
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.

include/haproxy/qpack-enc.h
src/h3.c
src/qpack-enc.c

index 29136191b8bcb347ecef8eec070d6dc78e5f581d..7bc3783a44f9602b2e717e5d20210397cccacdc4 100644 (file)
@@ -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_ */
index 41d9250b1baffa52427fc7d21cd83de60e1796c7..0f642daee8e3d217f6c7c33f8002f8cfe86c5142 100644 (file)
--- 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;
        }
index 5f4694979654dbd87eefe64cf3195bcb3e0ceaed..f6a18397f6e81dc488145f1be3a5816005f20e8f 100644 (file)
@@ -228,6 +228,25 @@ int qpack_encode_path(struct buffer *out, const struct ist path)
        }
 }
 
+/* Encode pseudo-header authority defined to <auth> into <out> 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)
 {