feat(log): improve quality of debug level logs
This commit is contained in:
		| @@ -1,3 +1,4 @@ | ||||
| use std::fmt; | ||||
| use std::usize; | ||||
| use std::io; | ||||
|  | ||||
| @@ -11,26 +12,12 @@ use self::Kind::{Length, Chunked, Eof}; | ||||
| /// | ||||
| /// If a message body does not include a Transfer-Encoding, it *should* | ||||
| /// include a Content-Length header. | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| #[derive(Clone, PartialEq)] | ||||
| pub struct Decoder { | ||||
|     kind: Kind, | ||||
| } | ||||
|  | ||||
| impl Decoder { | ||||
|     pub fn length(x: u64) -> Decoder { | ||||
|         Decoder { kind: Kind::Length(x) } | ||||
|     } | ||||
|  | ||||
|     pub fn chunked() -> Decoder { | ||||
|         Decoder { kind: Kind::Chunked(ChunkedState::Size, 0) } | ||||
|     } | ||||
|  | ||||
|     pub fn eof() -> Decoder { | ||||
|         Decoder { kind: Kind::Eof(false) } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| #[derive(Debug, Clone, Copy, PartialEq)] | ||||
| enum Kind { | ||||
|     /// A Reader used when a Content-Length header is passed with a positive integer. | ||||
|     Length(u64), | ||||
| @@ -38,6 +25,8 @@ enum Kind { | ||||
|     Chunked(ChunkedState, u64), | ||||
|     /// A Reader used for responses that don't indicate a length or chunked. | ||||
|     /// | ||||
|     /// The bool tracks when EOF is seen on the transport. | ||||
|     /// | ||||
|     /// Note: This should only used for `Response`s. It is illegal for a | ||||
|     /// `Request` to be made with both `Content-Length` and | ||||
|     /// `Transfer-Encoding: chunked` missing, as explained from the spec: | ||||
| @@ -53,7 +42,7 @@ enum Kind { | ||||
|     Eof(bool), | ||||
| } | ||||
|  | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| #[derive(Debug, PartialEq, Clone, Copy)] | ||||
| enum ChunkedState { | ||||
|     Size, | ||||
|     SizeLws, | ||||
| @@ -68,6 +57,22 @@ enum ChunkedState { | ||||
| } | ||||
|  | ||||
| impl Decoder { | ||||
|     // constructors | ||||
|  | ||||
|     pub fn length(x: u64) -> Decoder { | ||||
|         Decoder { kind: Kind::Length(x) } | ||||
|     } | ||||
|  | ||||
|     pub fn chunked() -> Decoder { | ||||
|         Decoder { kind: Kind::Chunked(ChunkedState::Size, 0) } | ||||
|     } | ||||
|  | ||||
|     pub fn eof() -> Decoder { | ||||
|         Decoder { kind: Kind::Eof(false) } | ||||
|     } | ||||
|  | ||||
|     // methods | ||||
|  | ||||
|     pub fn is_eof(&self) -> bool { | ||||
|         trace!("is_eof? {:?}", self); | ||||
|         match self.kind { | ||||
| @@ -77,9 +82,7 @@ impl Decoder { | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Decoder { | ||||
|     pub fn decode<R: MemRead>(&mut self, body: &mut R) -> Poll<Bytes, io::Error> { | ||||
|         match self.kind { | ||||
|             Length(ref mut remaining) => { | ||||
| @@ -131,6 +134,23 @@ impl Decoder { | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| impl fmt::Debug for Decoder { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt::Debug::fmt(&self.kind, f) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Display for Decoder { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         match self.kind { | ||||
|             Kind::Length(n) => write!(f, "content-length ({} bytes)", n), | ||||
|             Kind::Chunked(..) => f.write_str("chunked encoded"), | ||||
|             Kind::Eof(..) => f.write_str("until end-of-file"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| macro_rules! byte ( | ||||
|     ($rdr:ident) => ({ | ||||
|         let buf = try_ready!($rdr.read_mem(1)); | ||||
| @@ -154,7 +174,7 @@ impl ChunkedState { | ||||
|             Size => ChunkedState::read_size(body, size), | ||||
|             SizeLws => ChunkedState::read_size_lws(body), | ||||
|             Extension => ChunkedState::read_extension(body), | ||||
|             SizeLf => ChunkedState::read_size_lf(body, size), | ||||
|             SizeLf => ChunkedState::read_size_lf(body, *size), | ||||
|             Body => ChunkedState::read_body(body, size, buf), | ||||
|             BodyCr => ChunkedState::read_body_cr(body), | ||||
|             BodyLf => ChunkedState::read_body_lf(body), | ||||
| @@ -209,11 +229,17 @@ impl ChunkedState { | ||||
|             _ => Ok(Async::Ready(ChunkedState::Extension)), // no supported extensions | ||||
|         } | ||||
|     } | ||||
|     fn read_size_lf<R: MemRead>(rdr: &mut R, size: &mut u64) -> Poll<ChunkedState, io::Error> { | ||||
|     fn read_size_lf<R: MemRead>(rdr: &mut R, size: u64) -> Poll<ChunkedState, io::Error> { | ||||
|         trace!("Chunk size is {:?}", size); | ||||
|         match byte!(rdr) { | ||||
|             b'\n' if *size > 0 => Ok(Async::Ready(ChunkedState::Body)), | ||||
|             b'\n' if *size == 0 => Ok(Async::Ready(ChunkedState::EndCr)), | ||||
|             b'\n' => { | ||||
|                 if size == 0 { | ||||
|                     Ok(Async::Ready(ChunkedState::EndCr)) | ||||
|                 } else { | ||||
|                     debug!("incoming chunked header: {0:#X} ({0} bytes)", size); | ||||
|                     Ok(Async::Ready(ChunkedState::Body)) | ||||
|                 } | ||||
|             }, | ||||
|             _ => Err(io::Error::new(io::ErrorKind::InvalidInput, "Invalid chunk size LF")), | ||||
|         } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user