From 4d89adce6122af1650165337d9d814314e7ee409 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Wed, 11 Jan 2023 17:00:59 -0500 Subject: [PATCH] fix(body): set an internal max to reserve in `to_bytes` Previously, `to_bytes` would reserve extra space if after two chunks, there was more remaining. It used to reserve however much space the peer advertized. This changes now only reserves up to ~16kb. This way, a slow message with a big body doesn't reserve so much memory, until the data has actually been received. The existing warning to check for a length before calling the function is still the best approach. --- src/body/to_bytes.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/body/to_bytes.rs b/src/body/to_bytes.rs index 62b15a54a9..038c6fd0f3 100644 --- a/src/body/to_bytes.rs +++ b/src/body/to_bytes.rs @@ -63,8 +63,13 @@ where return Ok(first.copy_to_bytes(first.remaining())); }; + // Don't pre-emptively reserve *too* much. + let rest = (body.size_hint().lower() as usize).min(1024 * 16); + let cap = first + .remaining() + .saturating_add(second.remaining()) + .saturating_add(rest); // With more than 1 buf, we gotta flatten into a Vec first. - let cap = first.remaining() + second.remaining() + body.size_hint().lower() as usize; let mut vec = Vec::with_capacity(cap); vec.put(first); vec.put(second);