diff --git a/Cargo.toml b/Cargo.toml index 9793c19..a0e652b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bodyparser" -version = "0.8.0" +version = "0.9.0-pre" license = "MIT" description = "Body parsing middleware for Iron." repository = "https://github.com/iron/body-parser" diff --git a/examples/bodyparser.rs b/examples/bodyparser.rs index cf3a4cb..be8727c 100644 --- a/examples/bodyparser.rs +++ b/examples/bodyparser.rs @@ -6,7 +6,7 @@ extern crate serde; extern crate serde_derive; use persistent::Read; -use iron::status; +use iron::StatusCode; use iron::prelude::*; #[derive(Deserialize, Debug, Clone)] @@ -37,7 +37,7 @@ fn log_body(req: &mut Request) -> IronResult { Err(err) => println!("Error: {:?}", err) } - Ok(Response::with(status::Ok)) + Ok(Response::with(StatusCode::OK)) } const MAX_BODY_LENGTH: usize = 1024 * 1024 * 10; @@ -51,5 +51,5 @@ const MAX_BODY_LENGTH: usize = 1024 * 1024 * 10; fn main() { let mut chain = Chain::new(log_body); chain.link_before(Read::::one(MAX_BODY_LENGTH)); - Iron::new(chain).http("localhost:3000").unwrap(); + Iron::new(chain).http("localhost:3000"); } diff --git a/src/errors.rs b/src/errors.rs index c0d92b4..897dd1a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,6 +1,5 @@ use std::error::Error as StdError; use std::fmt; -use std::io; use std::str; use serde_json; @@ -8,7 +7,7 @@ use serde_json; #[derive(Debug)] pub enum BodyErrorCause { Utf8Error(str::Utf8Error), - IoError(io::Error), + IoError(iron::error::HttpError), JsonError(serde_json::Error), } diff --git a/src/lib.rs b/src/lib.rs index 0c274c8..643f9bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,21 +17,19 @@ use iron::mime; use iron::prelude::*; use iron::headers; use iron::typemap::{Key}; -use std::io::Read; use std::any::Any; use std::marker; pub use self::errors::{BodyError, BodyErrorCause}; -pub use self::limit_reader::{LimitReader}; mod errors; -mod limit_reader; -fn read_body_as_utf8(req: &mut Request, limit: usize) -> Result { - let mut bytes = Vec::new(); - match LimitReader::new(req.body.by_ref(), limit).read_to_end(&mut bytes) { - Ok(_) => { - match String::from_utf8(bytes) { +/// This implementation currently ignores the limit parameter, since irons +/// request::get_body_contents() reads the data unlimited. +fn read_body_as_utf8(req: &mut Request, _limit: usize) -> Result { + match req.get_body_contents() { + Ok(bytes) => { + match String::from_utf8(bytes.to_vec()) { Ok(e) => Ok(e), Err(err) => Err(errors::BodyError { detail: "Invalid UTF-8 sequence".to_string(), @@ -62,15 +60,13 @@ impl Key for Raw { const DEFAULT_BODY_LIMIT: usize = 1024 * 1024 * 100; -impl<'a, 'b> plugin::Plugin> for Raw { +impl plugin::Plugin for Raw { type Error = BodyError; fn eval(req: &mut Request) -> Result, BodyError> { - let need_read = req.headers.get::().map(|header| { - match **header { - mime::Mime(mime::TopLevel::Multipart, mime::SubLevel::FormData, _) => false, - _ => true - } + let need_read = req.headers.get(headers::CONTENT_TYPE).map(|header| { + header.to_str().unwrap().parse::().unwrap() + != "multipart/form-data".parse::().unwrap() }).unwrap_or(false); if need_read { @@ -96,7 +92,7 @@ impl Key for Json { type Value = Option; } -impl<'a, 'b> plugin::Plugin> for Json { +impl plugin::Plugin for Json { type Error = BodyError; fn eval(req: &mut Request) -> Result, BodyError> { @@ -122,7 +118,7 @@ impl Key for Struct where T: for<'a> Deserialize<'a> + Any { type Value = Option; } -impl<'a, 'b, T> plugin::Plugin> for Struct +impl plugin::Plugin for Struct where T: for<'c> Deserialize<'c> + Any { type Error = BodyError; diff --git a/src/limit_reader.rs b/src/limit_reader.rs deleted file mode 100644 index b794943..0000000 --- a/src/limit_reader.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::io; -use std::cmp; - -/// [Original impl](https://github.com/rust-lang/rust/blob/17bc7d8d5be3be9674d702ccad2fa88c487d23b0/src/libstd/old_io/util.rs#L20) -/// -/// The LimitReader from the `std` just stops to read when reaches a limit, but we don't want -/// to return partially readed body to the client code because it is useless. This modified LimitReader -/// returns `IoError` with `IoErrorKind::InvalidInput` when it reaches the limit. -#[derive(Debug)] -pub struct LimitReader { - limit: usize, - inner: R -} - -impl LimitReader { - pub fn new(r: R, limit: usize) -> LimitReader { - LimitReader { limit: limit, inner: r } - } - - pub fn into_inner(self) -> R { self.inner } - pub fn limit(&self) -> usize { self.limit } -} - -impl io::Read for LimitReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - if self.limit == 0 { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, "Body is too big")) - } - - let len = cmp::min(self.limit, buf.len()); - let res = self.inner.read(&mut buf[..len]); - match res { - Ok(len) => self.limit -= len, - _ => {} - } - res - } -} \ No newline at end of file