From 94c5d4d641cd7073fab05991fac2fe132808de88 Mon Sep 17 00:00:00 2001 From: asonix Date: Sun, 19 May 2024 19:24:37 -0500 Subject: [PATCH] Drop buffers in clear if 'too big' --- actix-http/src/h1/big_bytes.rs | 12 +++++++++++- actix-http/src/h1/dispatcher.rs | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/actix-http/src/h1/big_bytes.rs b/actix-http/src/h1/big_bytes.rs index b845d917..04ae8a6c 100644 --- a/actix-http/src/h1/big_bytes.rs +++ b/actix-http/src/h1/big_bytes.rs @@ -2,6 +2,9 @@ use std::collections::VecDeque; use bytes::{Buf, BufMut, Bytes, BytesMut}; +// 64KB max capacity (arbitrarily chosen) +const MAX_CAPACITY: usize = 1024 * 64; + pub(crate) struct BigBytes { buffer: BytesMut, frozen: VecDeque, @@ -18,10 +21,17 @@ impl BigBytes { } // Clear the internal queue and buffer, resetting length to zero - pub(super) fn clear(&mut self) { + // + // if the internal buffer capacity exceeds 64KB or new_capacity, whichever is greater, it will + // be freed and a new buffer of capacity `new_capacity` will be allocated + pub(super) fn clear(&mut self, new_capacity: usize) { std::mem::take(&mut self.frozen); self.frozen_len = 0; self.buffer.clear(); + + if self.buffer.capacity() > new_capacity.max(MAX_CAPACITY) { + self.buffer = BytesMut::with_capacity(new_capacity); + } } // Return a mutable reference to the underlying buffer. This should only be used when dealing diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index 64a5d460..d1bff8db 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -347,7 +347,7 @@ where } // everything has written to I/O; clear buffer - write_buf.clear(); + write_buf.clear(HW_BUFFER_SIZE); // flush the I/O and check if get blocked io.poll_flush(cx)