diff --git a/src/h2.c b/src/h2.c index 536240a6d..fa929aece 100644 --- a/src/h2.c +++ b/src/h2.c @@ -318,6 +318,7 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms struct htx_sl *sl = NULL; unsigned int sl_flags = 0; const char *ctl; + struct ist v; lck = ck = -1; // no cookie for now fields = 0; @@ -434,7 +435,15 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms continue; } - if (!htx_add_header(htx, list[idx].n, list[idx].v)) + /* trim leading/trailing LWS as per RC9113#8.2.1 */ + for (v = list[idx].v; v.len; v.len--) { + if (unlikely(HTTP_IS_LWS(*v.ptr))) + v.ptr++; + else if (!unlikely(HTTP_IS_LWS(v.ptr[v.len - 1]))) + break; + } + + if (!htx_add_header(htx, list[idx].n, v)) goto fail; } @@ -623,6 +632,7 @@ int h2_make_htx_response(struct http_hdr *list, struct htx *htx, unsigned int *m struct htx_sl *sl = NULL; unsigned int sl_flags = 0; const char *ctl; + struct ist v; fields = 0; for (idx = 0; list[idx].n.len != 0; idx++) { @@ -702,7 +712,15 @@ int h2_make_htx_response(struct http_hdr *list, struct htx *htx, unsigned int *m isteq(list[idx].n, ist("transfer-encoding"))) goto fail; - if (!htx_add_header(htx, list[idx].n, list[idx].v)) + /* trim leading/trailing LWS as per RC9113#8.2.1 */ + for (v = list[idx].v; v.len; v.len--) { + if (unlikely(HTTP_IS_LWS(*v.ptr))) + v.ptr++; + else if (!unlikely(HTTP_IS_LWS(v.ptr[v.len - 1]))) + break; + } + + if (!htx_add_header(htx, list[idx].n, v)) goto fail; } @@ -781,6 +799,7 @@ int h2_make_htx_response(struct http_hdr *list, struct htx *htx, unsigned int *m int h2_make_htx_trailers(struct http_hdr *list, struct htx *htx) { const char *ctl; + struct ist v; uint32_t idx; int i; @@ -816,7 +835,15 @@ int h2_make_htx_trailers(struct http_hdr *list, struct htx *htx) if (unlikely(ctl) && http_header_has_forbidden_char(list[idx].v, ctl)) goto fail; - if (!htx_add_trailer(htx, list[idx].n, list[idx].v)) + /* trim leading/trailing LWS as per RC9113#8.2.1 */ + for (v = list[idx].v; v.len; v.len--) { + if (unlikely(HTTP_IS_LWS(*v.ptr))) + v.ptr++; + else if (!unlikely(HTTP_IS_LWS(v.ptr[v.len - 1]))) + break; + } + + if (!htx_add_trailer(htx, list[idx].n, v)) goto fail; } diff --git a/src/mux_h2.c b/src/mux_h2.c index 0370d6a13..68ad3eb3d 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1209,11 +1210,20 @@ static inline int h2_encode_header(struct buffer *buf, const struct ist hn, cons uint64_t mask, const struct ist trc_loc, const char *func, const struct h2c *h2c, const struct h2s *h2s) { + struct ist v; int ret; - ret = hpack_encode_header(buf, hn, hv); + /* trim leading/trailing LWS as per RC9113#8.2.1 */ + for (v = hv; v.len; v.len--) { + if (unlikely(HTTP_IS_LWS(*v.ptr))) + v.ptr++; + else if (!unlikely(HTTP_IS_LWS(v.ptr[v.len - 1]))) + break; + } + + ret = hpack_encode_header(buf, hn, v); if (ret) - h2_trace_header(hn, hv, mask, trc_loc, func, h2c, h2s); + h2_trace_header(hn, v, mask, trc_loc, func, h2c, h2s); return ret; }