diff --git a/Cargo.toml b/Cargo.toml index f298e6b..f9037d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "actix-form-data" description = "Multipart Form Data for Actix Web" -version = "0.3.0" +version = "0.3.1" license = "GPL-3.0" authors = ["asonix "] repository = "https://git.asonix.cloud/asonix/actix-form-data.git" @@ -17,7 +17,7 @@ bytes = "0.4.7" failure = "0.1" futures = "0.1.21" futures-cpupool = "0.1.8" -futures-fs = "0.0.4" +futures-fs = "0.0.5" http = "0.1.5" log = "0.4.1" mime = "0.3.5" diff --git a/README.md b/README.md index 5eaa2bc..d499047 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Add it to your dependencies. [dependencies] actix-web = "0.7.0" -actix-form-data = "0.3.0" +actix-form-data = "0.3.1" ``` Require it in your project. diff --git a/examples/simple.rs b/examples/simple.rs index 9edb849..017fa9e 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -47,7 +47,8 @@ fn main() { server::new(move || { App::with_state(form.clone()) .resource("/upload", |r| r.method(http::Method::POST).with(upload)) - }).bind("127.0.0.1:8080") - .unwrap() - .run(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .run(); } diff --git a/examples/upload.rs b/examples/upload.rs index a8141b4..3e952b8 100644 --- a/examples/upload.rs +++ b/examples/upload.rs @@ -12,10 +12,16 @@ extern crate serde; #[macro_use] extern crate serde_derive; -use std::{env, path::PathBuf, sync::atomic::{AtomicUsize, Ordering}}; +use std::{ + env, + path::PathBuf, + sync::atomic::{AtomicUsize, Ordering}, +}; -use actix_web::{http, server, App, AsyncResponder, HttpMessage, HttpRequest, HttpResponse, State, - error::ResponseError, middleware::Logger}; +use actix_web::{ + error::ResponseError, http, middleware::Logger, server, App, AsyncResponder, HttpMessage, + HttpRequest, HttpResponse, State, +}; use form_data::*; use futures::Future; @@ -120,9 +126,10 @@ fn main() { App::with_state(state.clone()) .middleware(Logger::default()) .resource("/upload", |r| r.method(http::Method::POST).with(upload)) - }).bind("127.0.0.1:8080") - .unwrap() - .start(); + }) + .bind("127.0.0.1:8080") + .unwrap() + .start(); sys.run(); } diff --git a/src/error.rs b/src/error.rs index 0cb81dd..35f1c29 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,9 +17,16 @@ * along with Actix Form Data. If not, see . */ -use std::{io, num::{ParseFloatError, ParseIntError}, string::FromUtf8Error}; +use std::{ + io, + num::{ParseFloatError, ParseIntError}, + string::FromUtf8Error, +}; -use actix_web::{HttpResponse, error::{MultipartError, PayloadError, ResponseError}}; +use actix_web::{ + error::{MultipartError, PayloadError, ResponseError}, + HttpResponse, +}; #[derive(Debug, Fail)] pub enum Error { diff --git a/src/lib.rs b/src/lib.rs index ec7018d..f5b9504 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,8 +47,7 @@ //! } //! //! fn upload( -//! req: HttpRequest
, -//! state: State, +//! (req, state): (HttpRequest, State), //! ) -> Box> { //! handle_multipart(req.multipart(), state.clone()) //! .map(|uploaded_content| { @@ -74,7 +73,7 @@ //! //! server::new(move || { //! App::with_state(form.clone()) -//! .resource("/upload", |r| r.method(http::Method::POST).with2(upload)) +//! .resource("/upload", |r| r.method(http::Method::POST).with(upload)) //! }).bind("127.0.0.1:8080") //! .unwrap(); //! // .run() diff --git a/src/types.rs b/src/types.rs index 801bf20..97f7fca 100644 --- a/src/types.rs +++ b/src/types.rs @@ -17,10 +17,18 @@ * along with Actix Form Data. If not, see . */ -use std::{fmt, collections::{HashMap, VecDeque}, path::PathBuf, sync::Arc}; +use std::{ + collections::{HashMap, VecDeque}, + fmt, + path::PathBuf, + sync::Arc, +}; use bytes::Bytes; -use futures::{Future, future::{ExecuteError, Executor}}; +use futures::{ + future::{ExecuteError, Executor}, + Future, +}; use futures_cpupool::CpuPool; use super::FilenameGenerator; @@ -258,31 +266,41 @@ impl Field { match *self { Field::Array(ref arr) => arr.valid_field(name), Field::Map(ref map) => map.valid_field(name), - Field::File(ref gen) => if name.is_empty() { - Some(FieldTerminator::File(Arc::clone(gen))) - } else { - None - }, - Field::Int => if name.is_empty() { - Some(FieldTerminator::Int) - } else { - None - }, - Field::Float => if name.is_empty() { - Some(FieldTerminator::Float) - } else { - None - }, - Field::Text => if name.is_empty() { - Some(FieldTerminator::Text) - } else { - None - }, - Field::Bytes => if name.is_empty() { - Some(FieldTerminator::Bytes) - } else { - None - }, + Field::File(ref gen) => { + if name.is_empty() { + Some(FieldTerminator::File(Arc::clone(gen))) + } else { + None + } + } + Field::Int => { + if name.is_empty() { + Some(FieldTerminator::Int) + } else { + None + } + } + Field::Float => { + if name.is_empty() { + Some(FieldTerminator::Float) + } else { + None + } + } + Field::Text => { + if name.is_empty() { + Some(FieldTerminator::Text) + } else { + None + } + } + Field::Bytes => { + if name.is_empty() { + Some(FieldTerminator::Bytes) + } else { + None + } + } } } } @@ -359,7 +377,8 @@ impl Map { trace!("Checking {:?} and {:?}", self, name); match name.pop_front() { Some(name_part) => match name_part { - NamePart::Map(part_name) => self.inner + NamePart::Map(part_name) => self + .inner .iter() .find(|&&(ref item, _)| *item == part_name) .and_then(|&(_, ref field)| field.valid_field(name)), diff --git a/src/upload.rs b/src/upload.rs index 79b0a41..7bd90a2 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -17,19 +17,31 @@ * along with Actix Form Data. If not, see . */ -use std::{collections::HashMap, fs::DirBuilder, path::{Path, PathBuf}, - sync::{Arc, atomic::{AtomicUsize, Ordering}}}; +use std::{ + collections::HashMap, + fs::DirBuilder, + path::{Path, PathBuf}, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, +}; -use actix_web::{multipart, error::PayloadError}; +use actix_web::{error::PayloadError, multipart}; use bytes::{Bytes, BytesMut}; -use futures::{Future, Stream, future::{lazy, result, Either, Executor}, sync::oneshot}; +use futures::{ + future::{lazy, result, Either, Executor}, + sync::oneshot, + Future, Stream, +}; use futures_fs::FsPool; use http::header::CONTENT_DISPOSITION; -use error::Error; use super::FilenameGenerator; -use types::{self, ContentDisposition, MultipartContent, MultipartForm, MultipartHash, NamePart, - Value}; +use error::Error; +use types::{ + self, ContentDisposition, MultipartContent, MultipartForm, MultipartHash, NamePart, Value, +}; fn consolidate(mf: MultipartForm) -> Value { mf.into_iter().fold( @@ -184,35 +196,38 @@ where tx.send(res).map_err(|_| ()) }))) { - | Ok(_) => (), + Ok(_) => (), Err(_) => return Box::new(result(Err(Error::MkDir))), }; let counter = Arc::new(AtomicUsize::new(0)); - Box::new(rx.then(|res| match res { - Ok(res) => res, - Err(_) => Err(Error::MkDir), - }).and_then(move |_| { - let write = - FsPool::from_executor(form.pool.clone()).write(stored_as.clone(), Default::default()); - field - .map_err(Error::Multipart) - .and_then(move |bytes| { - let size = counter.fetch_add(bytes.len(), Ordering::Relaxed) + bytes.len(); + Box::new( + rx.then(|res| match res { + Ok(res) => res, + Err(_) => Err(Error::MkDir), + }) + .and_then(move |_| { + let write = FsPool::with_executor(form.pool.clone()) + .write(stored_as.clone(), Default::default()); + field + .map_err(Error::Multipart) + .and_then(move |bytes| { + let size = counter.fetch_add(bytes.len(), Ordering::Relaxed) + bytes.len(); - if size > form.max_file_size { - Err(Error::FileSize) - } else { - Ok(bytes) - } - }) - .forward(write) - .map(move |_| MultipartContent::File { - filename, - stored_as, - }) - })) + if size > form.max_file_size { + Err(Error::FileSize) + } else { + Ok(bytes) + } + }) + .forward(write) + .map(move |_| MultipartContent::File { + filename, + stored_as, + }) + }), + ) } fn handle_form_data(