mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 07:07:04 +02:00
MINOR: h3: complete HTTP/3 request scheme encoding
Previously, scheme was always set to https when transcoding an HTX start-line into a HTTP/3 request. Change this so this conversion is now fully compliant. If no scheme is specified by the client, which is what happens most of the time with HTTP/1, https is set for the HTTP/3 request. Else, reuse the scheme requested by the client. If either https or http is set, qpack_encode_scheme will encode it using entry from QPACK static table. Else, a full literal field line with name ref is used instead as the scheme value is specified as-is.
This commit is contained in:
parent
a0912cf914
commit
235e818fa1
@ -9,7 +9,7 @@ struct buffer;
|
||||
int qpack_encode_field_section_line(struct buffer *out);
|
||||
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);
|
||||
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_header(struct buffer *out, const struct ist n, const struct ist v);
|
||||
|
||||
|
33
src/h3.c
33
src/h3.c
@ -1707,7 +1707,7 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
enum htx_blk_type type;
|
||||
struct htx_blk *blk;
|
||||
struct htx_sl *sl;
|
||||
struct ist meth;
|
||||
struct ist meth, uri, scheme = IST_NULL, auth = IST_NULL;
|
||||
int frame_length_size; /* size in bytes of frame length varint field */
|
||||
int ret, err, hdr;
|
||||
|
||||
@ -1726,6 +1726,7 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
BUG_ON_HOT(sl); /* Only one start-line expected */
|
||||
sl = htx_get_blk_ptr(htx, blk);
|
||||
meth = htx_sl_req_meth(sl);
|
||||
uri = htx_sl_req_uri(sl);
|
||||
break;
|
||||
|
||||
case HTX_BLK_HDR:
|
||||
@ -1762,7 +1763,35 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
if (qpack_encode_method(&headers_buf, sl->info.req.meth, meth))
|
||||
goto err;
|
||||
|
||||
if (qpack_encode_scheme(&headers_buf))
|
||||
if (uri.ptr[0] != '/' && uri.ptr[0] != '*') {
|
||||
int len = 1;
|
||||
|
||||
/* the URI seems to start with a scheme */
|
||||
while (len < uri.len && uri.ptr[len] != ':')
|
||||
len++;
|
||||
|
||||
if (len + 2 < uri.len && uri.ptr[len + 1] == '/' && uri.ptr[len + 2] == '/') {
|
||||
/* make the uri start at the authority now */
|
||||
scheme = ist2(uri.ptr, len);
|
||||
uri = istadv(uri, len + 3);
|
||||
|
||||
/* find the auth part of the URI */
|
||||
auth = ist2(uri.ptr, 0);
|
||||
while (auth.len < uri.len && auth.ptr[auth.len] != '/')
|
||||
auth.len++;
|
||||
|
||||
uri = istadv(uri, auth.len);
|
||||
}
|
||||
}
|
||||
|
||||
if (!istlen(scheme)) {
|
||||
if ((sl->flags & (HTX_SL_F_HAS_SCHM|HTX_SL_F_SCHM_HTTP)) == (HTX_SL_F_HAS_SCHM|HTX_SL_F_SCHM_HTTP))
|
||||
scheme = ist("http");
|
||||
else
|
||||
scheme = ist("https");
|
||||
}
|
||||
|
||||
if (qpack_encode_scheme(&headers_buf, scheme))
|
||||
goto err;
|
||||
|
||||
if (qpack_encode_path(&headers_buf, ist('/')))
|
||||
|
@ -172,17 +172,34 @@ int qpack_encode_method(struct buffer *out, enum http_meth_t meth, struct ist ot
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encode pseudo-header scheme defined to https on <out> buffer.
|
||||
*
|
||||
* Returns 0 on success else non-zero.
|
||||
*/
|
||||
int qpack_encode_scheme(struct buffer *out)
|
||||
/* Returns 0 on success else non-zero. */
|
||||
int qpack_encode_scheme(struct buffer *out, const struct ist scheme)
|
||||
{
|
||||
if (b_room(out) < 2)
|
||||
return 1;
|
||||
int sz;
|
||||
|
||||
if (unlikely(!isteq(scheme, ist("https"))) && !isteq(scheme, ist("http"))) {
|
||||
sz = 2 + qpack_get_prefix_int_size(istlen(scheme), 7) + istlen(scheme);
|
||||
if (b_room(out) < sz)
|
||||
return 1;
|
||||
|
||||
/* literal field line with name ref */
|
||||
qpack_encode_prefix_integer(out, 23, 4, 0x50);
|
||||
qpack_encode_prefix_integer(out, istlen(scheme), 7, 0);
|
||||
for (size_t i = 0; i < istlen(scheme); ++i)
|
||||
b_putchr(out, istptr(scheme)[i]);
|
||||
}
|
||||
else {
|
||||
int idx = 23;
|
||||
|
||||
if (unlikely(!isteq(scheme, ist("http"))))
|
||||
idx = 22;
|
||||
if (b_room(out) < 2)
|
||||
return 1;
|
||||
|
||||
/* :scheme: http[s] */
|
||||
qpack_encode_prefix_integer(out, idx, 6, 0xc0);
|
||||
}
|
||||
|
||||
/* :scheme: https */
|
||||
qpack_encode_prefix_integer(out, 23, 6, 0xc0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user