diff --git a/actix-http/src/h1/client.rs b/actix-http/src/h1/client.rs index 6a50c027..f93bc496 100644 --- a/actix-http/src/h1/client.rs +++ b/actix-http/src/h1/client.rs @@ -10,7 +10,7 @@ use http::header::{ use http::{Method, Version}; use super::decoder::{PayloadDecoder, PayloadItem, PayloadType}; -use super::{decoder, encoder}; +use super::{decoder, encoder, reserve_readbuf}; use super::{Message, MessageType}; use crate::body::BodySize; use crate::config::ServiceConfig; @@ -150,6 +150,7 @@ impl Decoder for ClientCodec { } else { self.inner.payload = None; } + reserve_readbuf(src); Ok(Some(req)) } else { Ok(None) @@ -168,7 +169,10 @@ impl Decoder for ClientPayloadCodec { ); Ok(match self.inner.payload.as_mut().unwrap().decode(src)? { - Some(PayloadItem::Chunk(chunk)) => Some(Some(chunk)), + Some(PayloadItem::Chunk(chunk)) => { + reserve_readbuf(src); + Some(Some(chunk)) + } Some(PayloadItem::Eof) => { self.inner.payload.take(); Some(None) diff --git a/actix-http/src/h1/codec.rs b/actix-http/src/h1/codec.rs index e4895f2d..6e891e7c 100644 --- a/actix-http/src/h1/codec.rs +++ b/actix-http/src/h1/codec.rs @@ -9,7 +9,7 @@ use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCOD use http::{Method, StatusCode, Version}; use super::decoder::{PayloadDecoder, PayloadItem, PayloadType}; -use super::{decoder, encoder}; +use super::{decoder, encoder, reserve_readbuf}; use super::{Message, MessageType}; use crate::body::BodySize; use crate::config::ServiceConfig; @@ -19,9 +19,6 @@ use crate::message::{ConnectionType, Head, ResponseHead}; use crate::request::Request; use crate::response::Response; -const LW: usize = 2 * 1024; -const HW: usize = 32 * 1024; - bitflags! { struct Flags: u8 { const HEAD = 0b0000_0001; @@ -108,14 +105,12 @@ impl Decoder for Codec { type Error = ParseError; fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { - let cap = src.capacity(); - if cap < LW { - src.reserve(HW - cap); - } - if self.payload.is_some() { Ok(match self.payload.as_mut().unwrap().decode(src)? { - Some(PayloadItem::Chunk(chunk)) => Some(Message::Chunk(Some(chunk))), + Some(PayloadItem::Chunk(chunk)) => { + reserve_readbuf(src); + Some(Message::Chunk(Some(chunk))) + } Some(PayloadItem::Eof) => { self.payload.take(); Some(Message::Chunk(None)) @@ -140,6 +135,7 @@ impl Decoder for Codec { self.flags.insert(Flags::STREAM); } } + reserve_readbuf(src); Ok(Some(Message::Item(req))) } else { Ok(None) diff --git a/actix-http/src/h1/mod.rs b/actix-http/src/h1/mod.rs index e3d63c52..472d7347 100644 --- a/actix-http/src/h1/mod.rs +++ b/actix-http/src/h1/mod.rs @@ -1,5 +1,5 @@ //! HTTP/1 implementation -use bytes::Bytes; +use bytes::{Bytes, BytesMut}; mod client; mod codec; @@ -38,6 +38,16 @@ pub enum MessageType { Stream, } +const LW: usize = 2 * 1024; +const HW: usize = 32 * 1024; + +pub(crate) fn reserve_readbuf(src: &mut BytesMut) { + let cap = src.capacity(); + if cap < LW { + src.reserve(HW - cap); + } +} + #[cfg(test)] mod tests { use super::*;