1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-13 10:49:26 +00:00

added urlencoded errors

This commit is contained in:
Nikolay Kim 2017-11-26 22:00:25 -08:00
parent fdafb0c848
commit 8e80fed2af
2 changed files with 54 additions and 27 deletions

View file

@ -344,6 +344,31 @@ impl ErrorResponse for WsHandshakeError {
}
}
/// A set of errors that can occur during parsing urlencoded payloads
#[derive(Fail, Debug, PartialEq)]
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")]
Overflow,
/// Payload size is now known
#[fail(display="Payload size is now known")]
UnknownLength,
/// Content type error
#[fail(display="Content type error")]
ContentType,
}
/// Return `BadRequest` for `UrlencodedError`
impl ErrorResponse for UrlencodedError {
fn error_response(&self) -> HttpResponse {
HttpResponse::new(StatusCode::BAD_REQUEST, Body::Empty)
}
}
#[cfg(test)]
mod tests {
use std::error::Error as StdError;

View file

@ -12,7 +12,8 @@ use {Cookie, HttpRange};
use recognizer::Params;
use payload::Payload;
use multipart::Multipart;
use error::{ParseError, PayloadError, MultipartError, CookieParseError, HttpRangeError};
use error::{ParseError, PayloadError,
MultipartError, CookieParseError, HttpRangeError, UrlencodedError};
struct HttpMessage {
version: Version,
@ -306,36 +307,41 @@ impl<S> HttpRequest<S> {
/// * content type is not `application/x-www-form-urlencoded`
/// * transfer encoding is `chunked`.
/// * content-length is greater than 256k
pub fn urlencoded(&self, payload: Payload) -> Result<UrlEncoded, Payload> {
if let Ok(chunked) = self.chunked() {
if chunked {
return Err(payload)
}
pub fn urlencoded(&mut self) -> Result<UrlEncoded, UrlencodedError> {
if let Ok(true) = self.chunked() {
return Err(UrlencodedError::Chunked)
}
if let Some(len) = self.headers().get(header::CONTENT_LENGTH) {
if let Ok(s) = len.to_str() {
if let Ok(len) = s.parse::<u64>() {
if len > 262_144 {
return Err(payload)
return Err(UrlencodedError::Overflow)
}
} else {
return Err(payload)
return Err(UrlencodedError::UnknownLength)
}
} else {
return Err(payload)
return Err(UrlencodedError::UnknownLength)
}
}
if let Some(content_type) = self.0.headers.get(header::CONTENT_TYPE) {
// check content type
let t = if let Some(content_type) = self.0.headers.get(header::CONTENT_TYPE) {
if let Ok(content_type) = content_type.to_str() {
if content_type.to_lowercase() == "application/x-www-form-urlencoded" {
return Ok(UrlEncoded{pl: payload, body: BytesMut::new()})
}
content_type.to_lowercase() == "application/x-www-form-urlencoded"
} else {
false
}
}
} else {
false
};
Err(payload)
if t {
Ok(UrlEncoded{pl: self.take_payload(), body: BytesMut::new()})
} else {
Err(UrlencodedError::ContentType)
}
}
}
@ -409,43 +415,39 @@ mod tests {
let mut headers = HeaderMap::new();
headers.insert(header::TRANSFER_ENCODING,
header::HeaderValue::from_static("chunked"));
let req = HttpRequest::new(
let mut req = HttpRequest::new(
Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new(), Payload::empty());
let (_, payload) = Payload::new(false);
assert!(req.urlencoded(payload).is_err());
assert_eq!(req.urlencoded().err().unwrap(), UrlencodedError::Chunked);
let mut headers = HeaderMap::new();
headers.insert(header::CONTENT_TYPE,
header::HeaderValue::from_static("application/x-www-form-urlencoded"));
headers.insert(header::CONTENT_LENGTH,
header::HeaderValue::from_static("xxxx"));
let req = HttpRequest::new(
let mut req = HttpRequest::new(
Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new(), Payload::empty());
let (_, payload) = Payload::new(false);
assert!(req.urlencoded(payload).is_err());
assert_eq!(req.urlencoded().err().unwrap(), UrlencodedError::UnknownLength);
let mut headers = HeaderMap::new();
headers.insert(header::CONTENT_TYPE,
header::HeaderValue::from_static("application/x-www-form-urlencoded"));
headers.insert(header::CONTENT_LENGTH,
header::HeaderValue::from_static("1000000"));
let req = HttpRequest::new(
let mut req = HttpRequest::new(
Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new(), Payload::empty());
let (_, payload) = Payload::new(false);
assert!(req.urlencoded(payload).is_err());
assert_eq!(req.urlencoded().err().unwrap(), UrlencodedError::Overflow);
let mut headers = HeaderMap::new();
headers.insert(header::CONTENT_TYPE,
header::HeaderValue::from_static("text/plain"));
headers.insert(header::CONTENT_LENGTH,
header::HeaderValue::from_static("10"));
let req = HttpRequest::new(
let mut req = HttpRequest::new(
Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new(), Payload::empty());
let (_, payload) = Payload::new(false);
assert!(req.urlencoded(payload).is_err());
assert_eq!(req.urlencoded().err().unwrap(), UrlencodedError::ContentType);
}
}