MEDIUM: h3: use absolute URI form with :authority

Change the representation of the start-line URI when parsing a HTTP/3
request into HTX. Adopt the same conversion as HTTP/2. If :authority
header is used (default case), the URI is encoded using absolute-form,
with scheme, host and path concatenated. If only a plain host header is
used instead, fallback to the origin form.

This commit may cause some configuration to be broken if parsing is
performed on the URI. Indeed, now most of the HTTP/3 requests will be
represented with an absolute-form URI at the stream layer.

Note that prior to this commit a check was performed on the path used as
URI to ensure that it did not contain any invalid characters. Now, this
is directly performed on the URI itself, which may include the path.

This must not be backported.
This commit is contained in:
Amaury Denoyelle 2025-04-16 15:17:57 +02:00
parent 1faa1285aa
commit 2c3d656f8d

View File

@ -529,6 +529,7 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
unsigned int flags = HTX_SL_F_NONE;
struct ist meth = IST_NULL, path = IST_NULL;
struct ist scheme = IST_NULL, authority = IST_NULL;
struct ist uri;
struct ist v;
int hdr_idx, ret;
int cookie = -1, last_cookie = -1, i;
@ -752,9 +753,26 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
goto out;
}
if (!istlen(scheme)) {
/* No scheme (CONNECT), use :authority only. */
uri = authority;
}
else if (isttest(authority)) {
/* Use absolute URI form as :authority is present. */
uri = ist2bin(trash.area, scheme);
istcat(&uri, ist("://"), trash.size);
istcat(&uri, authority, trash.size);
if (!isteq(path, ist("*")))
istcat(&uri, path, trash.size);
}
else {
/* Use origin URI form. */
uri = path;
}
/* Ensure that final URI does not contains LWS nor CTL characters. */
for (i = 0; i < path.len; i++) {
unsigned char c = istptr(path)[i];
for (i = 0; i < uri.len; i++) {
unsigned char c = istptr(uri)[i];
if (HTTP_IS_LWS(c) || HTTP_IS_CTL(c)) {
TRACE_ERROR("invalid character in path", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
h3s->err = H3_ERR_MESSAGE_ERROR;
@ -764,7 +782,7 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
}
}
sl = htx_add_stline(htx, HTX_BLK_REQ_SL, flags, meth, path, ist("HTTP/3.0"));
sl = htx_add_stline(htx, HTX_BLK_REQ_SL, flags, meth, uri, ist("HTTP/3.0"));
if (!sl) {
len = -1;
goto out;