diff --git a/CHANGES.md b/CHANGES.md index d1e4e6f6c..367354a9b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,6 +25,8 @@ ### Fixed +* Support chunked encoding for UrlEncoded body #262 + * `HttpRequest::url_for()` for a named route with no variables segments #265 diff --git a/src/error.rs b/src/error.rs index 481cf3268..cfb6a0287 100644 --- a/src/error.rs +++ b/src/error.rs @@ -293,8 +293,18 @@ impl From for PayloadError { } } -/// `InternalServerError` for `PayloadError` -impl ResponseError for PayloadError {} +/// `PayloadError` returns two possible results: +/// +/// - `Overflow` returns `PayloadTooLarge` +/// - Other errors returns `BadRequest` +impl ResponseError for PayloadError { + fn error_response(&self) -> HttpResponse { + match *self { + PayloadError::Overflow => HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE), + _ => HttpResponse::new(StatusCode::BAD_REQUEST), + } + } +} /// Return `BadRequest` for `cookie::ParseError` impl ResponseError for cookie::ParseError { @@ -417,8 +427,10 @@ pub enum UrlencodedError { /// Can not decode chunked transfer encoding #[fail(display = "Can not decode chunked transfer encoding")] Chunked, - /// Payload size is bigger than 256k - #[fail(display = "Payload size is bigger than 256k")] + /// Payload size is bigger than allowed. (default: 256kB) + #[fail( + display = "Urlencoded payload size is bigger than allowed. (default: 256kB)" + )] Overflow, /// Payload size is now known #[fail(display = "Payload size is now known")] @@ -458,8 +470,8 @@ impl From for UrlencodedError { /// A set of errors that can occur during parsing json payloads #[derive(Fail, Debug)] pub enum JsonPayloadError { - /// Payload size is bigger than 256k - #[fail(display = "Payload size is bigger than 256k")] + /// Payload size is bigger than allowed. (default: 256kB) + #[fail(display = "Json payload size is bigger than allowed. (default: 256kB)")] Overflow, /// Content type error #[fail(display = "Content type error")] diff --git a/src/extractor.rs b/src/extractor.rs index 3d77853a5..175e948b8 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; -use std::str; +use std::{fmt, str}; use bytes::Bytes; use encoding::all::UTF_8; @@ -115,6 +115,18 @@ where } } +impl fmt::Debug for Path { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.inner.fmt(f) + } +} + +impl fmt::Display for Path { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.inner.fmt(f) + } +} + /// Extract typed information from from the request's query. /// /// ## Example @@ -175,13 +187,24 @@ where #[inline] fn from_request(req: &HttpRequest, _: &Self::Config) -> Self::Result { - let req = req.clone(); serde_urlencoded::from_str::(req.query_string()) .map_err(|e| e.into()) .map(Query) } } +impl fmt::Debug for Query { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Display for Query { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + /// Extract typed information from the request's body. /// /// To extract typed information from request's body, the type `T` must @@ -252,6 +275,18 @@ where } } +impl fmt::Debug for Form { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Display for Form { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + /// Form extractor configuration /// /// ```rust diff --git a/src/httpmessage.rs b/src/httpmessage.rs index 1e57d3867..a9d68d3ab 100644 --- a/src/httpmessage.rs +++ b/src/httpmessage.rs @@ -149,7 +149,6 @@ pub trait HttpMessage { /// Returns error: /// /// * content type is not `application/x-www-form-urlencoded` - /// * transfer encoding is `chunked`. /// * content-length is greater than 256k /// /// ## Server example @@ -367,9 +366,7 @@ where fn poll(&mut self) -> Poll { if let Some(req) = self.req.take() { - if req.chunked().unwrap_or(false) { - return Err(UrlencodedError::Chunked); - } else if let Some(len) = req.headers().get(header::CONTENT_LENGTH) { + if let Some(len) = req.headers().get(header::CONTENT_LENGTH) { if let Ok(s) = len.to_str() { if let Ok(len) = s.parse::() { if len > 262_144 { @@ -577,13 +574,6 @@ mod tests { #[test] fn test_urlencoded_error() { - let req = - TestRequest::with_header(header::TRANSFER_ENCODING, "chunked").finish(); - assert_eq!( - req.urlencoded::().poll().err().unwrap(), - UrlencodedError::Chunked - ); - let req = TestRequest::with_header( header::CONTENT_TYPE, "application/x-www-form-urlencoded", diff --git a/src/httprequest.rs b/src/httprequest.rs index 1d9f6245f..d852bc743 100644 --- a/src/httprequest.rs +++ b/src/httprequest.rs @@ -283,9 +283,9 @@ impl HttpRequest { /// Generate url for named resource /// /// ```rust - /// //#### # extern crate actix_web; - /// //#### # use actix_web::{App, HttpRequest, HttpResponse, http}; - /// //#### # + /// # extern crate actix_web; + /// # use actix_web::{App, HttpRequest, HttpResponse, http}; + /// # /// fn index(req: HttpRequest) -> HttpResponse { /// let url = req.url_for("foo", &["1", "2", "3"]); // <- generate url for "foo" resource /// HttpResponse::Ok().into() diff --git a/src/lib.rs b/src/lib.rs index 2772309e0..5d3767a29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,10 +2,10 @@ //! for Rust. //! //! ```rust -//! use actix_web::{server, App, Path}; +//! use actix_web::{server, App, Path, Responder}; //! # use std::thread; //! -//! fn index(info: Path<(String, u32)>) -> String { +//! fn index(info: Path<(String, u32)>) -> impl Responder { //! format!("Hello {}! id:{}", info.0, info.1) //! } //! diff --git a/src/middleware/identity.rs b/src/middleware/identity.rs index d1e52d463..706dd9fc8 100644 --- a/src/middleware/identity.rs +++ b/src/middleware/identity.rs @@ -3,7 +3,7 @@ //! [**IdentityService**](struct.IdentityService.html) middleware can be //! used with different policies types to store identity information. //! -//! Bu default, only cookie identity policy is implemented. Other backend +//! By default, only cookie identity policy is implemented. Other backend //! implementations can be added separately. //! //! [**CookieIdentityPolicy**](struct.CookieIdentityPolicy.html)