diff --git a/src/h3.c b/src/h3.c index 9b0c8ad4d..f1b3ec7c5 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1565,6 +1565,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; @@ -1679,7 +1702,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_full; } @@ -1839,7 +1862,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;