1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-12-30 03:50:42 +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)] #[cfg(test)]
mod tests { mod tests {
use std::error::Error as StdError; use std::error::Error as StdError;

View file

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