1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 09:42:40 +01:00

fix limit usage for Request/Response Body future

This commit is contained in:
Nikolay Kim 2018-01-30 12:44:14 -08:00
parent 5cbaf3a1b8
commit 9739168d48
5 changed files with 31 additions and 29 deletions

View File

@ -25,9 +25,12 @@ use server::IoStream;
#[derive(Debug)] #[derive(Debug)]
/// `Connect` type represents message that can be send to `ClientConnector`
/// with connection request.
pub struct Connect(pub Uri); pub struct Connect(pub Uri);
impl Connect { impl Connect {
/// Create `Connect` message for specified `Uri`
pub fn new<U>(uri: U) -> Result<Connect, HttpError> where Uri: HttpTryFrom<U> { pub fn new<U>(uri: U) -> Result<Connect, HttpError> where Uri: HttpTryFrom<U> {
Ok(Connect(Uri::try_from(uri).map_err(|e| e.into())?)) Ok(Connect(Uri::try_from(uri).map_err(|e| e.into())?))
} }
@ -38,6 +41,7 @@ impl ResponseType for Connect {
type Error = ClientConnectorError; type Error = ClientConnectorError;
} }
/// A set of errors that can occur during connecting to a http host
#[derive(Fail, Debug)] #[derive(Fail, Debug)]
pub enum ClientConnectorError { pub enum ClientConnectorError {
/// Invalid url /// Invalid url

View File

@ -6,6 +6,6 @@ mod writer;
pub(crate) use self::writer::HttpClientWriter; pub(crate) use self::writer::HttpClientWriter;
pub use self::request::{ClientRequest, ClientRequestBuilder}; pub use self::request::{ClientRequest, ClientRequestBuilder};
pub use self::response::ClientResponse; pub use self::response::{ClientResponse, JsonResponse};
pub use self::parser::{HttpResponseParser, HttpResponseParserError}; pub(crate) use self::parser::{HttpResponseParser, HttpResponseParserError};
pub use self::connect::{Connect, Connection, ClientConnector, ClientConnectorError}; pub use self::connect::{Connect, Connection, ClientConnector, ClientConnectorError};

View File

@ -170,7 +170,7 @@ impl fmt::Debug for ClientRequest {
} }
/// An HTTP client request builder /// An HTTP Client request builder
/// ///
/// This type can be used to construct an instance of `ClientRequest` through a /// This type can be used to construct an instance of `ClientRequest` through a
/// builder-like pattern. /// builder-like pattern.

View File

@ -39,6 +39,7 @@ impl Default for ClientMessage {
} }
} }
/// An HTTP Client response
pub struct ClientResponse(Rc<UnsafeCell<ClientMessage>>); pub struct ClientResponse(Rc<UnsafeCell<ClientMessage>>);
impl ClientResponse { impl ClientResponse {
@ -288,8 +289,8 @@ impl Future for ResponseBody {
if let Some(resp) = self.resp.take() { if let Some(resp) = self.resp.take() {
if let Some(len) = resp.headers().get(header::CONTENT_LENGTH) { if let Some(len) = resp.headers().get(header::CONTENT_LENGTH) {
if let Ok(s) = len.to_str() { if let Ok(s) = len.to_str() {
if let Ok(len) = s.parse::<u64>() { if let Ok(len) = s.parse::<usize>() {
if len > 262_144 { if len > self.limit {
return Err(PayloadError::Overflow); return Err(PayloadError::Overflow);
} }
} else { } else {
@ -321,7 +322,7 @@ impl Future for ResponseBody {
} }
} }
/// Client response payload json parser that resolves to a deserialized `T` value. /// Client response json parser that resolves to a deserialized `T` value.
/// ///
/// Returns error: /// Returns error:
/// ///

View File

@ -700,36 +700,21 @@ pub struct RequestBody {
pl: ReadAny, pl: ReadAny,
body: BytesMut, body: BytesMut,
limit: usize, limit: usize,
error: Option<PayloadError>, req: Option<HttpRequest<()>>,
} }
impl RequestBody { impl RequestBody {
/// Create `RequestBody` for request. /// Create `RequestBody` for request.
pub fn from_request<S>(req: &HttpRequest<S>) -> RequestBody { pub fn from_request<S>(req: &HttpRequest<S>) -> RequestBody {
let mut body = RequestBody { let pl = req.payload().readany();
pl: req.payload().readany(), RequestBody {
pl: pl,
body: BytesMut::new(), body: BytesMut::new(),
limit: 262_144, limit: 262_144,
error: None req: Some(req.clone_without_state())
};
if let Some(len) = req.headers().get(header::CONTENT_LENGTH) {
if let Ok(s) = len.to_str() {
if let Ok(len) = s.parse::<u64>() {
if len > 262_144 {
body.error = Some(PayloadError::Overflow);
}
} else {
body.error = Some(PayloadError::UnknownLength);
}
} else {
body.error = Some(PayloadError::UnknownLength);
}
} }
}
body
}
/// Change max size of payload. By default max size is 256Kb /// Change max size of payload. By default max size is 256Kb
pub fn limit(mut self, limit: usize) -> Self { pub fn limit(mut self, limit: usize) -> Self {
@ -743,8 +728,20 @@ impl Future for RequestBody {
type Error = PayloadError; type Error = PayloadError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
if let Some(err) = self.error.take() { if let Some(req) = self.req.take() {
return Err(err) if let Some(len) = req.headers().get(header::CONTENT_LENGTH) {
if let Ok(s) = len.to_str() {
if let Ok(len) = s.parse::<usize>() {
if len > self.limit {
return Err(PayloadError::Overflow);
}
} else {
return Err(PayloadError::UnknownLength);
}
} else {
return Err(PayloadError::UnknownLength);
}
}
} }
loop { loop {