mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 07:07:04 +02:00
MINOR: h3: encode request headers
Implement encoding of HTTP/3 request headers during HTX->H3 conversion on the backend side. This simply relies on h3_encode_header(). Special check is implemented to ensure that connection-specific headers are ignored. An HTTP/3 endpoint must never generate them, or the peer will consider the message as malformed.
This commit is contained in:
parent
7157adb154
commit
f5342e0a96
75
src/h3.c
75
src/h3.c
@ -1700,13 +1700,51 @@ static int h3_encode_header(struct buffer *buf,
|
||||
*/
|
||||
static int h3_req_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
{
|
||||
struct http_hdr list[global.tune.max_http_hdr * 2];
|
||||
struct buffer outbuf;
|
||||
struct buffer headers_buf = BUF_NULL;
|
||||
struct buffer *res;
|
||||
struct htx_blk *blk;
|
||||
enum htx_blk_type type;
|
||||
struct htx_blk *blk;
|
||||
struct htx_sl *sl;
|
||||
int frame_length_size; /* size in bytes of frame length varint field */
|
||||
int ret, err;
|
||||
int ret, err, hdr;
|
||||
|
||||
hdr = 0;
|
||||
sl = NULL;
|
||||
for (blk = htx_get_head_blk(htx); blk; blk = htx_get_next_blk(htx, blk)) {
|
||||
type = htx_get_blk_type(blk);
|
||||
|
||||
switch (type) {
|
||||
case HTX_BLK_EOH:
|
||||
goto end_loop;
|
||||
case HTX_BLK_UNUSED:
|
||||
break;
|
||||
|
||||
case HTX_BLK_REQ_SL:
|
||||
BUG_ON_HOT(sl); /* Only one start-line expected */
|
||||
sl = htx_get_blk_ptr(htx, blk);
|
||||
break;
|
||||
|
||||
case HTX_BLK_HDR:
|
||||
if (unlikely(hdr >= sizeof(list) / sizeof(list[0]) - 1))
|
||||
goto err;
|
||||
|
||||
list[hdr].n = htx_get_blk_name(htx, blk);
|
||||
list[hdr].v = htx_get_blk_value(htx, blk);
|
||||
|
||||
++hdr;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end_loop:
|
||||
BUG_ON_HOT(!sl); /* start-line must be present. */
|
||||
/* marker for end of headers */
|
||||
list[hdr].n = ist("");
|
||||
|
||||
res = qcc_get_stream_txbuf(qcs, &err, 0);
|
||||
BUG_ON(!res);
|
||||
@ -1734,6 +1772,39 @@ static int h3_req_headers_send(struct qcs *qcs, struct htx *htx)
|
||||
if (h3_encode_header(&headers_buf, ist(":authority"), ist("127.0.0.1:20443")))
|
||||
goto err;
|
||||
|
||||
/* Encode every parsed headers, stop at empty one. */
|
||||
for (hdr = 0; hdr < sizeof(list) / sizeof(list[0]); ++hdr) {
|
||||
if (isteq(list[hdr].n, ist("")))
|
||||
break;
|
||||
|
||||
/* RFC 9114 4.2. HTTP Fields
|
||||
*
|
||||
* An intermediary transforming an HTTP/1.x message to HTTP/3
|
||||
* MUST remove connection-specific header fields as discussed in
|
||||
* Section 7.6.1 of [HTTP], or their messages will be treated by
|
||||
* other HTTP/3 endpoints as malformed.
|
||||
*/
|
||||
if (isteq(list[hdr].n, ist("connection")) ||
|
||||
isteq(list[hdr].n, ist("proxy-connection")) ||
|
||||
isteq(list[hdr].n, ist("keep-alive")) ||
|
||||
isteq(list[hdr].n, ist("upgrade")) ||
|
||||
isteq(list[hdr].n, ist("transfer-encoding"))) {
|
||||
continue;
|
||||
}
|
||||
else if (isteq(list[hdr].n, ist("te"))) {
|
||||
/* "te" may only be sent with "trailers" if this value
|
||||
* is present, otherwise it must be deleted.
|
||||
*/
|
||||
const struct ist v = istist(list[hdr].v, ist("trailers"));
|
||||
if (!isttest(v) || (v.len > 8 && v.ptr[8] != ','))
|
||||
continue;
|
||||
list[hdr].v = ist("trailers");
|
||||
}
|
||||
|
||||
if (h3_encode_header(&headers_buf, list[hdr].n, list[hdr].v))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Now that all headers are encoded, we are certain that res buffer is
|
||||
* big enough
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user