1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-02 13:29:24 +00: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 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)

View file

@ -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<Option<Self::Item>, 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)

View file

@ -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::*;