mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MINOR: h3: complete HTTP/3 request method encoding
On the backend side, HTX start-line is converted into a HTTP/3 request message. Previously, GET method was hardcoded. Implement proper method conversion, by extracting it from the HTX start-line. qpack_encode_method() has also been extended, so that it is able to encode any method, either using a static table entry, or with a literal field line with name ref representation.
This commit is contained in:
parent
f5342e0a96
commit
a0912cf914
@ -8,7 +8,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);
|
||||
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_path(struct buffer *out, const struct ist path);
|
||||
int qpack_encode_header(struct buffer *out, const struct ist n, const struct ist v);
|
||||
|
6
src/h3.c
6
src/h3.c
@ -1707,6 +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;
|
||||
int frame_length_size; /* size in bytes of frame length varint field */
|
||||
int ret, err, hdr;
|
||||
|
||||
@ -1724,6 +1725,7 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
case HTX_BLK_REQ_SL:
|
||||
BUG_ON_HOT(sl); /* Only one start-line expected */
|
||||
sl = htx_get_blk_ptr(htx, blk);
|
||||
meth = htx_sl_req_meth(sl);
|
||||
break;
|
||||
|
||||
case HTX_BLK_HDR:
|
||||
@ -1757,10 +1759,8 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
if (qpack_encode_field_section_line(&headers_buf))
|
||||
goto err;
|
||||
|
||||
/* :method */
|
||||
if (qpack_encode_method(&headers_buf, HTTP_METH_GET))
|
||||
if (qpack_encode_method(&headers_buf, sl->info.req.meth, meth))
|
||||
goto err;
|
||||
/* :scheme */
|
||||
|
||||
if (qpack_encode_scheme(&headers_buf))
|
||||
goto err;
|
||||
|
@ -133,27 +133,40 @@ int qpack_encode_int_status(struct buffer *out, unsigned int status)
|
||||
}
|
||||
|
||||
/* Returns 0 on success else non-zero. */
|
||||
int qpack_encode_method(struct buffer *out, enum http_meth_t meth)
|
||||
int qpack_encode_method(struct buffer *out, enum http_meth_t meth, struct ist other)
|
||||
{
|
||||
int size, idx = 0;
|
||||
int sz, idx = 0;
|
||||
|
||||
switch (meth) {
|
||||
case HTTP_METH_GET: idx = 17; break;
|
||||
default: ABORT_NOW();
|
||||
case HTTP_METH_CONNECT: idx = 15; break;
|
||||
case HTTP_METH_DELETE: idx = 16; break;
|
||||
case HTTP_METH_GET: idx = 17; break;
|
||||
case HTTP_METH_HEAD: idx = 18; break;
|
||||
case HTTP_METH_OPTIONS: idx = 19; break;
|
||||
case HTTP_METH_POST: idx = 20; break;
|
||||
case HTTP_METH_PUT: idx = 21; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (idx) {
|
||||
/* method present in QPACK static table
|
||||
* -> indexed field line
|
||||
*/
|
||||
size = qpack_get_prefix_int_size(idx, 6);
|
||||
if (b_room(out) < size)
|
||||
/* indexed field line */
|
||||
if (b_room(out) < 2)
|
||||
return 1;
|
||||
|
||||
qpack_encode_prefix_integer(out, idx, 6, 0xc0);
|
||||
}
|
||||
else {
|
||||
ABORT_NOW();
|
||||
BUG_ON(!istlen(other)); /* non standard method, <other> must be set. */
|
||||
|
||||
sz = 2 + qpack_get_prefix_int_size(istlen(other), 7) + istlen(other);
|
||||
if (b_room(out) < sz)
|
||||
return 1;
|
||||
|
||||
/* literal field line with name ref */
|
||||
qpack_encode_prefix_integer(out, 15, 4, 0x50);
|
||||
qpack_encode_prefix_integer(out, istlen(other), 7, 0);
|
||||
for (size_t i = 0; i < istlen(other); ++i)
|
||||
b_putchr(out, istptr(other)[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user