diff --git a/src/common/buf.rs b/src/common/buf.rs index d00071551b..ed4a5d7574 100644 --- a/src/common/buf.rs +++ b/src/common/buf.rs @@ -5,18 +5,21 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; pub(crate) struct BufList { bufs: VecDeque, + remaining: usize, } impl BufList { pub(crate) fn new() -> BufList { BufList { bufs: VecDeque::new(), + remaining: 0, } } #[inline] pub(crate) fn push(&mut self, buf: T) { debug_assert!(buf.has_remaining()); + self.remaining += buf.remaining(); self.bufs.push_back(buf); } @@ -29,7 +32,7 @@ impl BufList { impl Buf for BufList { #[inline] fn remaining(&self) -> usize { - self.bufs.iter().map(|buf| buf.remaining()).sum() + self.remaining } #[inline] @@ -39,6 +42,7 @@ impl Buf for BufList { #[inline] fn advance(&mut self, mut cnt: usize) { + self.remaining -= cnt; while cnt > 0 { { let front = &mut self.bufs[0]; @@ -78,12 +82,18 @@ impl Buf for BufList { Some(front) if front.remaining() == len => { let b = front.copy_to_bytes(len); self.bufs.pop_front(); + self.remaining -= len; b } - Some(front) if front.remaining() > len => front.copy_to_bytes(len), + Some(front) if front.remaining() > len => { + self.remaining -= len; + front.copy_to_bytes(len) + } _ => { - assert!(len <= self.remaining(), "`len` greater than remaining"); + assert!(len <= self.remaining, "`len` greater than remaining"); let mut bm = BytesMut::with_capacity(len); + // Note: `self.take(len)` calls `self.advance()` internally, + // which already decrements `self.remaining`. bm.put(self.take(len)); bm.freeze() } @@ -100,6 +110,7 @@ mod tests { fn hello_world_buf() -> BufList { BufList { bufs: vec![Bytes::from("Hello"), Bytes::from(" "), Bytes::from("World")].into(), + remaining: 11, } } diff --git a/src/proto/h1/conn.rs b/src/proto/h1/conn.rs index 3d71ed5bc5..94b2844538 100644 --- a/src/proto/h1/conn.rs +++ b/src/proto/h1/conn.rs @@ -239,7 +239,7 @@ where ParseContext { cached_headers: &mut self.state.cached_headers, req_method: &mut self.state.method, - h1_parser_config: self.state.h1_parser_config.clone(), + h1_parser_config: &self.state.h1_parser_config, h1_max_headers: self.state.h1_max_headers, preserve_header_case: self.state.preserve_header_case, #[cfg(feature = "ffi")] diff --git a/src/proto/h1/io.rs b/src/proto/h1/io.rs index 6a30d73c84..de3a8eb4ff 100644 --- a/src/proto/h1/io.rs +++ b/src/proto/h1/io.rs @@ -68,7 +68,7 @@ where io, partial_len: None, read_blocked: false, - read_buf: BytesMut::with_capacity(0), + read_buf: BytesMut::with_capacity(INIT_BUFFER_SIZE), read_buf_strategy: ReadStrategy::default(), write_buf, } @@ -182,7 +182,7 @@ where ParseContext { cached_headers: parse_ctx.cached_headers, req_method: parse_ctx.req_method, - h1_parser_config: parse_ctx.h1_parser_config.clone(), + h1_parser_config: parse_ctx.h1_parser_config, h1_max_headers: parse_ctx.h1_max_headers, preserve_header_case: parse_ctx.preserve_header_case, #[cfg(feature = "ffi")] @@ -704,7 +704,7 @@ mod tests { let parse_ctx = ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] diff --git a/src/proto/h1/mod.rs b/src/proto/h1/mod.rs index a8f36f5fd9..1fea370cc5 100644 --- a/src/proto/h1/mod.rs +++ b/src/proto/h1/mod.rs @@ -71,7 +71,7 @@ pub(crate) struct ParsedMessage { pub(crate) struct ParseContext<'a> { cached_headers: &'a mut Option, req_method: &'a mut Option, - h1_parser_config: ParserConfig, + h1_parser_config: &'a ParserConfig, h1_max_headers: Option, preserve_header_case: bool, #[cfg(feature = "ffi")] diff --git a/src/proto/h1/role.rs b/src/proto/h1/role.rs index f92092e5a9..92cbcccb88 100644 --- a/src/proto/h1/role.rs +++ b/src/proto/h1/role.rs @@ -1674,7 +1674,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut method, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1702,7 +1702,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut Some(crate::Method::GET), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1726,7 +1726,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1747,7 +1747,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut Some(crate::Method::GET), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1770,7 +1770,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut Some(crate::Method::GET), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1797,7 +1797,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut Some(crate::Method::GET), - h1_parser_config, + h1_parser_config: &h1_parser_config, h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1821,7 +1821,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut Some(crate::Method::GET), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1849,7 +1849,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut method, - h1_parser_config, + h1_parser_config: &h1_parser_config, h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1876,7 +1876,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1896,7 +1896,7 @@ mod tests { let ctx = ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: true, #[cfg(feature = "ffi")] @@ -1935,7 +1935,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -1956,7 +1956,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -2186,7 +2186,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut Some(Method::GET), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -2207,7 +2207,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut Some(m), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -2228,7 +2228,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut Some(Method::GET), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -2798,7 +2798,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut Some(Method::GET), - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -2842,7 +2842,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: max_headers, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -2866,7 +2866,7 @@ mod tests { ParseContext { cached_headers: &mut None, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: max_headers, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -3035,7 +3035,7 @@ mod tests { ParseContext { cached_headers: &mut headers, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")] @@ -3080,7 +3080,7 @@ mod tests { ParseContext { cached_headers: &mut headers, req_method: &mut None, - h1_parser_config: Default::default(), + h1_parser_config: &Default::default(), h1_max_headers: None, preserve_header_case: false, #[cfg(feature = "ffi")]