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.
This commit is contained in:
Amaury Denoyelle 2025-05-30 18:00:48 +02:00
parent 96183abfbd
commit 555ec99d43
3 changed files with 28 additions and 3 deletions

View 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_ */

View File

@ -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")))
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;
}

View 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)
{