mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
BUG/MINOR: h3: properly handle connection headers
Connection headers are not used in HTTP/3. As specified by RFC 9114, a received message containing one of those is considered as malformed and rejected. When converting an HTX message to HTTP/3, these headers are silently skipped. This must be backported up to 2.6. Note that assignment to <h3s.err> must be removed on 2.6 as stream level error has been introduced in 2.7 so this field does not exist in 2.6 A connection error will be used instead automatically.
This commit is contained in:
parent
d1ebee1774
commit
8ad2669175
56
src/h3.c
56
src/h3.c
@ -599,6 +599,37 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (isteq(list[hdr_idx].n, ist("connection")) ||
|
||||||
|
isteq(list[hdr_idx].n, ist("proxy-connection")) ||
|
||||||
|
isteq(list[hdr_idx].n, ist("keep-alive")) ||
|
||||||
|
isteq(list[hdr_idx].n, ist("transfer-encoding"))) {
|
||||||
|
/* RFC 9114 4.2. HTTP Fields
|
||||||
|
*
|
||||||
|
* HTTP/3 does not use the Connection header field to indicate
|
||||||
|
* connection-specific fields; in this protocol, connection-
|
||||||
|
* specific metadata is conveyed by other means. An endpoint
|
||||||
|
* MUST NOT generate an HTTP/3 field section containing
|
||||||
|
* connection-specific fields; any message containing
|
||||||
|
* connection-specific fields MUST be treated as malformed.
|
||||||
|
*/
|
||||||
|
TRACE_ERROR("invalid connection header", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
|
||||||
|
h3s->err = H3_MESSAGE_ERROR;
|
||||||
|
len = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else if (isteq(list[hdr_idx].n, ist("te")) &&
|
||||||
|
!isteq(list[hdr_idx].v, ist("trailers"))) {
|
||||||
|
/* RFC 9114 4.2. HTTP Fields
|
||||||
|
*
|
||||||
|
* The only exception to this is the TE header field, which MAY
|
||||||
|
* be present in an HTTP/3 request header; when it is, it MUST
|
||||||
|
* NOT contain any value other than "trailers".
|
||||||
|
*/
|
||||||
|
TRACE_ERROR("invalid te header", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
|
||||||
|
h3s->err = H3_MESSAGE_ERROR;
|
||||||
|
len = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!htx_add_header(htx, list[hdr_idx].n, list[hdr_idx].v)) {
|
if (!htx_add_header(htx, list[hdr_idx].n, list[hdr_idx].v)) {
|
||||||
h3c->err = H3_INTERNAL_ERROR;
|
h3c->err = H3_INTERNAL_ERROR;
|
||||||
@ -1113,13 +1144,28 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
|
|||||||
if (isteq(list[hdr].n, ist("")))
|
if (isteq(list[hdr].n, ist("")))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* draft-ietf-quic-http34 4.1. HTTP Message Exchanges
|
/* RFC 9114 4.2. HTTP Fields
|
||||||
* Transfer codings (see Section 6.1 of [HTTP11]) are not
|
*
|
||||||
* defined for HTTP/3; the Transfer-Encoding header field MUST
|
* An intermediary transforming an HTTP/1.x message to HTTP/3
|
||||||
* NOT be used.
|
* 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("transfer-encoding")))
|
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("transfer-encoding"))) {
|
||||||
continue;
|
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 (qpack_encode_header(&headers_buf, list[hdr].n, list[hdr].v))
|
if (qpack_encode_header(&headers_buf, list[hdr].n, list[hdr].v))
|
||||||
ABORT_NOW();
|
ABORT_NOW();
|
||||||
|
Loading…
Reference in New Issue
Block a user