From 6ef9c60361d00b66437e88e0b4b449ac909f7a9b Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sun, 25 Feb 2018 21:26:58 +0300 Subject: [PATCH] add Read and AsyncRead impl to HttpRequest --- src/error.rs | 3 +-- src/httprequest.rs | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/error.rs b/src/error.rs index a37727cbd..b63206ff1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -96,8 +96,7 @@ impl From for Error { /// Compatibility for `failure::Error` impl ResponseError for failure::Compat - where T: fmt::Display + fmt::Debug + Sync + Send + 'static -{ } + where T: fmt::Display + fmt::Debug + Sync + Send + 'static { } impl From for Error { fn from(err: failure::Error) -> Error { diff --git a/src/httprequest.rs b/src/httprequest.rs index 279b7d979..0d721c87f 100644 --- a/src/httprequest.rs +++ b/src/httprequest.rs @@ -1,16 +1,18 @@ //! HTTP Request message related code. -use std::{str, fmt, mem}; +use std::{io, cmp, str, fmt, mem}; use std::rc::Rc; use std::net::SocketAddr; use std::collections::HashMap; use bytes::{Bytes, BytesMut}; use cookie::Cookie; -use futures::{Future, Stream, Poll}; +use futures::{Async, Future, Stream, Poll}; use http_range::HttpRange; use serde::de::DeserializeOwned; use mime::Mime; +use failure; use url::{Url, form_urlencoded}; use http::{header, Uri, Method, Version, HeaderMap, Extensions}; +use tokio_io::AsyncRead; use info::ConnectionInfo; use param::Params; @@ -611,6 +613,38 @@ impl Stream for HttpRequest { } } +impl io::Read for HttpRequest { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + match self.payload_mut().poll() { + Ok(Async::Ready(Some(mut b))) => { + let i = cmp::min(b.len(), buf.len()); + buf.copy_from_slice(&b.split_to(i)[..i]); + + if !b.is_empty() { + self.payload_mut().unread_data(b); + } + + if i < buf.len() { + match self.read(&mut buf[i..]) { + Ok(n) => Ok(i + n), + Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(i), + Err(e) => Err(e), + } + } else { + Ok(i) + } + } + Ok(Async::Ready(None)) => Ok(0), + Ok(Async::NotReady) => + Err(io::Error::new(io::ErrorKind::WouldBlock, "Not ready")), + Err(e) => + Err(io::Error::new(io::ErrorKind::Other, failure::Error::from(e).compat())), + } + } +} + +impl AsyncRead for HttpRequest {} + impl fmt::Debug for HttpRequest { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let res = write!(f, "\nHttpRequest {:?} {}:{}\n",