1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

properly allocate read buffer

This commit is contained in:
Nikolay Kim 2019-04-02 11:11:32 -07:00
parent d067b1d5f1
commit 49a499ce74
3 changed files with 23 additions and 13 deletions

View File

@ -10,7 +10,7 @@ use http::header::{
use http::{Method, Version}; use http::{Method, Version};
use super::decoder::{PayloadDecoder, PayloadItem, PayloadType}; use super::decoder::{PayloadDecoder, PayloadItem, PayloadType};
use super::{decoder, encoder}; use super::{decoder, encoder, reserve_readbuf};
use super::{Message, MessageType}; use super::{Message, MessageType};
use crate::body::BodySize; use crate::body::BodySize;
use crate::config::ServiceConfig; use crate::config::ServiceConfig;
@ -150,6 +150,7 @@ impl Decoder for ClientCodec {
} else { } else {
self.inner.payload = None; self.inner.payload = None;
} }
reserve_readbuf(src);
Ok(Some(req)) Ok(Some(req))
} else { } else {
Ok(None) Ok(None)
@ -168,7 +169,10 @@ impl Decoder for ClientPayloadCodec {
); );
Ok(match self.inner.payload.as_mut().unwrap().decode(src)? { 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) => { Some(PayloadItem::Eof) => {
self.inner.payload.take(); self.inner.payload.take();
Some(None) Some(None)

View File

@ -9,7 +9,7 @@ use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCOD
use http::{Method, StatusCode, Version}; use http::{Method, StatusCode, Version};
use super::decoder::{PayloadDecoder, PayloadItem, PayloadType}; use super::decoder::{PayloadDecoder, PayloadItem, PayloadType};
use super::{decoder, encoder}; use super::{decoder, encoder, reserve_readbuf};
use super::{Message, MessageType}; use super::{Message, MessageType};
use crate::body::BodySize; use crate::body::BodySize;
use crate::config::ServiceConfig; use crate::config::ServiceConfig;
@ -19,9 +19,6 @@ use crate::message::{ConnectionType, Head, ResponseHead};
use crate::request::Request; use crate::request::Request;
use crate::response::Response; use crate::response::Response;
const LW: usize = 2 * 1024;
const HW: usize = 32 * 1024;
bitflags! { bitflags! {
struct Flags: u8 { struct Flags: u8 {
const HEAD = 0b0000_0001; const HEAD = 0b0000_0001;
@ -108,14 +105,12 @@ impl Decoder for Codec {
type Error = ParseError; type Error = ParseError;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> { fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
let cap = src.capacity();
if cap < LW {
src.reserve(HW - cap);
}
if self.payload.is_some() { if self.payload.is_some() {
Ok(match self.payload.as_mut().unwrap().decode(src)? { 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) => { Some(PayloadItem::Eof) => {
self.payload.take(); self.payload.take();
Some(Message::Chunk(None)) Some(Message::Chunk(None))
@ -140,6 +135,7 @@ impl Decoder for Codec {
self.flags.insert(Flags::STREAM); self.flags.insert(Flags::STREAM);
} }
} }
reserve_readbuf(src);
Ok(Some(Message::Item(req))) Ok(Some(Message::Item(req)))
} else { } else {
Ok(None) Ok(None)

View File

@ -1,5 +1,5 @@
//! HTTP/1 implementation //! HTTP/1 implementation
use bytes::Bytes; use bytes::{Bytes, BytesMut};
mod client; mod client;
mod codec; mod codec;
@ -38,6 +38,16 @@ pub enum MessageType {
Stream, 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;