1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-12-01 02:54:36 +01:00

fix body decoding

This commit is contained in:
Nikolay Kim 2018-11-05 19:32:03 -08:00
parent da82e24954
commit f1587243c2
5 changed files with 94 additions and 12 deletions

View File

@ -37,6 +37,7 @@ cell = ["actix-net/cell"]
[dependencies] [dependencies]
actix = "0.7.5" actix = "0.7.5"
#actix-net = "0.1.1" #actix-net = "0.1.1"
#actix-net = { path="../actix-net/" }
actix-net = { git="https://github.com/actix/actix-net.git" } actix-net = { git="https://github.com/actix/actix-net.git" }
base64 = "0.9" base64 = "0.9"

View File

@ -42,6 +42,12 @@ pub struct Codec {
te: ResponseEncoder, te: ResponseEncoder,
} }
impl Default for Codec {
fn default() -> Self {
Codec::new(ServiceConfig::default())
}
}
impl fmt::Debug for Codec { impl fmt::Debug for Codec {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "h1::Codec({:?})", self.flags) write!(f, "h1::Codec({:?})", self.flags)
@ -247,7 +253,10 @@ impl Decoder for Codec {
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)) => Some(Message::Chunk(Some(chunk))),
Some(PayloadItem::Eof) => Some(Message::Chunk(None)), Some(PayloadItem::Eof) => {
self.payload.take();
Some(Message::Chunk(None))
}
None => None, None => None,
}) })
} else if self.flags.contains(Flags::UNHANDLED) { } else if self.flags.contains(Flags::UNHANDLED) {
@ -297,3 +306,55 @@ impl Encoder for Codec {
Ok(()) Ok(())
} }
} }
#[cfg(test)]
mod tests {
use std::{cmp, io};
use bytes::{Buf, Bytes, BytesMut};
use http::{Method, Version};
use tokio_io::{AsyncRead, AsyncWrite};
use super::*;
use error::ParseError;
use h1::Message;
use httpmessage::HttpMessage;
use request::Request;
#[test]
fn test_http_request_chunked_payload_and_next_message() {
let mut codec = Codec::default();
let mut buf = BytesMut::from(
"GET /test HTTP/1.1\r\n\
transfer-encoding: chunked\r\n\r\n",
);
let item = codec.decode(&mut buf).unwrap().unwrap();
let req = item.message();
assert_eq!(req.method(), Method::GET);
assert!(req.chunked().unwrap());
buf.extend(
b"4\r\ndata\r\n4\r\nline\r\n0\r\n\r\n\
POST /test2 HTTP/1.1\r\n\
transfer-encoding: chunked\r\n\r\n"
.iter(),
);
let msg = codec.decode(&mut buf).unwrap().unwrap();
assert_eq!(msg.chunk().as_ref(), b"data");
let msg = codec.decode(&mut buf).unwrap().unwrap();
assert_eq!(msg.chunk().as_ref(), b"line");
let msg = codec.decode(&mut buf).unwrap().unwrap();
assert!(msg.eof());
// decode next message
let item = codec.decode(&mut buf).unwrap().unwrap();
let req = item.message();
assert_eq!(*req.method(), Method::POST);
assert!(req.chunked().unwrap());
}
}

View File

@ -648,9 +648,7 @@ mod tests {
use super::*; use super::*;
use error::ParseError; use error::ParseError;
use h1::Message;
use httpmessage::HttpMessage; use httpmessage::HttpMessage;
use request::Request;
impl PayloadType { impl PayloadType {
fn unwrap(self) -> PayloadDecoder { fn unwrap(self) -> PayloadDecoder {
@ -668,15 +666,6 @@ mod tests {
} }
} }
impl Message<Request> {
fn message(self) -> Request {
match self {
Message::Item(req) => req,
_ => panic!("error"),
}
}
}
impl PayloadItem { impl PayloadItem {
fn chunk(self) -> Bytes { fn chunk(self) -> Bytes {
match self { match self {

View File

@ -370,6 +370,7 @@ where
Response::InternalServerError().finish(), Response::InternalServerError().finish(),
)); ));
self.error = Some(DispatchError::InternalError); self.error = Some(DispatchError::InternalError);
break;
} }
} }
Message::Chunk(None) => { Message::Chunk(None) => {
@ -382,6 +383,7 @@ where
Response::InternalServerError().finish(), Response::InternalServerError().finish(),
)); ));
self.error = Some(DispatchError::InternalError); self.error = Some(DispatchError::InternalError);
break;
} }
} }
} }

View File

@ -46,3 +46,32 @@ pub enum MessageType {
Payload, Payload,
Unhandled, Unhandled,
} }
#[cfg(test)]
mod tests {
use super::*;
impl Message<Request> {
pub fn message(self) -> Request {
match self {
Message::Item(req) => req,
_ => panic!("error"),
}
}
pub fn chunk(self) -> Bytes {
match self {
Message::Chunk(Some(data)) => data,
_ => panic!("error"),
}
}
pub fn eof(self) -> bool {
match self {
Message::Chunk(None) => true,
Message::Chunk(Some(_)) => false,
_ => panic!("error"),
}
}
}
}