From 3a7d58305f8b9680e3a3b1e11944a83b28a0fc41 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Wed, 16 Apr 2025 17:29:41 +0200 Subject: [PATCH] BUG/MEDIUM: h3: trim whitespaces in header value prior to QPACK encoding This commit does a similar job than the previous one, but it acts now on the response path. Any leading or trailing whitespaces characters from a HTX block header value are removed, prior to the header encoding via QPACK. This must be backported up to 2.6. (cherry picked from commit bd3587574dae43cc019d8e9998e0996c75550de4) Signed-off-by: Aurelien DARRAGON (cherry picked from commit a4f7bfa029ada954c8fae75c1426555a3a4012d4) [ada: ctx adjt] Signed-off-by: Aurelien DARRAGON --- src/h3.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/h3.c b/src/h3.c index bfa1ea2..9745611 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1583,6 +1583,29 @@ static int h3_control_send(struct qcs *qcs, void *ctx) return -1; } +/* Encode header field name value into buffer using QPACK. Strip + * any leading/trailing WS in value prior to encoding. + * + * Returns 0 on success else non zero. + */ +static int h3_encode_header(struct buffer *buf, + const struct ist n, const struct ist v) +{ + struct ist v_strip; + char *ptr; + + /* trim leading/trailing LWS */ + for (v_strip = v; istlen(v_strip); --v_strip.len) { + ptr = istptr(v_strip); + if (unlikely(HTTP_IS_LWS(*ptr))) + ++v_strip.ptr; + else if (!unlikely(HTTP_IS_LWS(ptr[istlen(v_strip) - 1]))) + break; + } + + return qpack_encode_header(buf, n, v_strip); +} + static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx) { int err; @@ -1693,7 +1716,7 @@ static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx) list[hdr].v = ist("trailers"); } - if (qpack_encode_header(&headers_buf, list[hdr].n, list[hdr].v)) + if (h3_encode_header(&headers_buf, list[hdr].n, list[hdr].v)) goto err; } @@ -1847,7 +1870,7 @@ static int h3_resp_trailers_send(struct qcs *qcs, struct htx *htx) continue; } - if (qpack_encode_header(&headers_buf, list[hdr].n, list[hdr].v)) { + if (h3_encode_header(&headers_buf, list[hdr].n, list[hdr].v)) { TRACE_STATE("not enough room for all trailers", H3_EV_TX_FRAME|H3_EV_TX_HDR, qcs->qcc->conn, qcs); if (qcc_release_stream_txbuf(qcs)) goto end; -- 1.7.10.4