Bump dependencies
This commit is contained in:
parent
b24ed66ec0
commit
f1aea84569
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-form-data"
|
name = "actix-form-data"
|
||||||
description = "Multipart Form Data for Actix Web"
|
description = "Multipart Form Data for Actix Web"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["asonix <asonix@asonix.dog>"]
|
authors = ["asonix <asonix@asonix.dog>"]
|
||||||
repository = "https://git.asonix.cloud/asonix/actix-form-data.git"
|
repository = "https://git.asonix.cloud/asonix/actix-form-data.git"
|
||||||
|
@ -17,7 +17,7 @@ bytes = "0.4.7"
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
futures = "0.1.21"
|
futures = "0.1.21"
|
||||||
futures-cpupool = "0.1.8"
|
futures-cpupool = "0.1.8"
|
||||||
futures-fs = "0.0.4"
|
futures-fs = "0.0.5"
|
||||||
http = "0.1.5"
|
http = "0.1.5"
|
||||||
log = "0.4.1"
|
log = "0.4.1"
|
||||||
mime = "0.3.5"
|
mime = "0.3.5"
|
||||||
|
|
|
@ -12,7 +12,7 @@ Add it to your dependencies.
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "0.7.0"
|
actix-web = "0.7.0"
|
||||||
actix-form-data = "0.3.0"
|
actix-form-data = "0.3.1"
|
||||||
```
|
```
|
||||||
|
|
||||||
Require it in your project.
|
Require it in your project.
|
||||||
|
|
|
@ -47,7 +47,8 @@ fn main() {
|
||||||
server::new(move || {
|
server::new(move || {
|
||||||
App::with_state(form.clone())
|
App::with_state(form.clone())
|
||||||
.resource("/upload", |r| r.method(http::Method::POST).with(upload))
|
.resource("/upload", |r| r.method(http::Method::POST).with(upload))
|
||||||
}).bind("127.0.0.1:8080")
|
})
|
||||||
.unwrap()
|
.bind("127.0.0.1:8080")
|
||||||
.run();
|
.unwrap()
|
||||||
|
.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,16 @@ extern crate serde;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
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,
|
use actix_web::{
|
||||||
error::ResponseError, middleware::Logger};
|
error::ResponseError, http, middleware::Logger, server, App, AsyncResponder, HttpMessage,
|
||||||
|
HttpRequest, HttpResponse, State,
|
||||||
|
};
|
||||||
use form_data::*;
|
use form_data::*;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
||||||
|
@ -120,9 +126,10 @@ fn main() {
|
||||||
App::with_state(state.clone())
|
App::with_state(state.clone())
|
||||||
.middleware(Logger::default())
|
.middleware(Logger::default())
|
||||||
.resource("/upload", |r| r.method(http::Method::POST).with(upload))
|
.resource("/upload", |r| r.method(http::Method::POST).with(upload))
|
||||||
}).bind("127.0.0.1:8080")
|
})
|
||||||
.unwrap()
|
.bind("127.0.0.1:8080")
|
||||||
.start();
|
.unwrap()
|
||||||
|
.start();
|
||||||
|
|
||||||
sys.run();
|
sys.run();
|
||||||
}
|
}
|
||||||
|
|
11
src/error.rs
11
src/error.rs
|
@ -17,9 +17,16 @@
|
||||||
* along with Actix Form Data. If not, see <http://www.gnu.org/licenses/>.
|
* along with Actix Form Data. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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)]
|
#[derive(Debug, Fail)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
|
|
@ -47,8 +47,7 @@
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! fn upload(
|
//! fn upload(
|
||||||
//! req: HttpRequest<Form>,
|
//! (req, state): (HttpRequest<Form>, State<Form>),
|
||||||
//! state: State<Form>,
|
|
||||||
//! ) -> Box<Future<Item = HttpResponse, Error = Error>> {
|
//! ) -> Box<Future<Item = HttpResponse, Error = Error>> {
|
||||||
//! handle_multipart(req.multipart(), state.clone())
|
//! handle_multipart(req.multipart(), state.clone())
|
||||||
//! .map(|uploaded_content| {
|
//! .map(|uploaded_content| {
|
||||||
|
@ -74,7 +73,7 @@
|
||||||
//!
|
//!
|
||||||
//! server::new(move || {
|
//! server::new(move || {
|
||||||
//! App::with_state(form.clone())
|
//! 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")
|
//! }).bind("127.0.0.1:8080")
|
||||||
//! .unwrap();
|
//! .unwrap();
|
||||||
//! // .run()
|
//! // .run()
|
||||||
|
|
75
src/types.rs
75
src/types.rs
|
@ -17,10 +17,18 @@
|
||||||
* along with Actix Form Data. If not, see <http://www.gnu.org/licenses/>.
|
* along with Actix Form Data. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::{fmt, collections::{HashMap, VecDeque}, path::PathBuf, sync::Arc};
|
use std::{
|
||||||
|
collections::{HashMap, VecDeque},
|
||||||
|
fmt,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::{Future, future::{ExecuteError, Executor}};
|
use futures::{
|
||||||
|
future::{ExecuteError, Executor},
|
||||||
|
Future,
|
||||||
|
};
|
||||||
use futures_cpupool::CpuPool;
|
use futures_cpupool::CpuPool;
|
||||||
|
|
||||||
use super::FilenameGenerator;
|
use super::FilenameGenerator;
|
||||||
|
@ -258,31 +266,41 @@ impl Field {
|
||||||
match *self {
|
match *self {
|
||||||
Field::Array(ref arr) => arr.valid_field(name),
|
Field::Array(ref arr) => arr.valid_field(name),
|
||||||
Field::Map(ref map) => map.valid_field(name),
|
Field::Map(ref map) => map.valid_field(name),
|
||||||
Field::File(ref gen) => if name.is_empty() {
|
Field::File(ref gen) => {
|
||||||
Some(FieldTerminator::File(Arc::clone(gen)))
|
if name.is_empty() {
|
||||||
} else {
|
Some(FieldTerminator::File(Arc::clone(gen)))
|
||||||
None
|
} else {
|
||||||
},
|
None
|
||||||
Field::Int => if name.is_empty() {
|
}
|
||||||
Some(FieldTerminator::Int)
|
}
|
||||||
} else {
|
Field::Int => {
|
||||||
None
|
if name.is_empty() {
|
||||||
},
|
Some(FieldTerminator::Int)
|
||||||
Field::Float => if name.is_empty() {
|
} else {
|
||||||
Some(FieldTerminator::Float)
|
None
|
||||||
} else {
|
}
|
||||||
None
|
}
|
||||||
},
|
Field::Float => {
|
||||||
Field::Text => if name.is_empty() {
|
if name.is_empty() {
|
||||||
Some(FieldTerminator::Text)
|
Some(FieldTerminator::Float)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
}
|
||||||
Field::Bytes => if name.is_empty() {
|
}
|
||||||
Some(FieldTerminator::Bytes)
|
Field::Text => {
|
||||||
} else {
|
if name.is_empty() {
|
||||||
None
|
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);
|
trace!("Checking {:?} and {:?}", self, name);
|
||||||
match name.pop_front() {
|
match name.pop_front() {
|
||||||
Some(name_part) => match name_part {
|
Some(name_part) => match name_part {
|
||||||
NamePart::Map(part_name) => self.inner
|
NamePart::Map(part_name) => self
|
||||||
|
.inner
|
||||||
.iter()
|
.iter()
|
||||||
.find(|&&(ref item, _)| *item == part_name)
|
.find(|&&(ref item, _)| *item == part_name)
|
||||||
.and_then(|&(_, ref field)| field.valid_field(name)),
|
.and_then(|&(_, ref field)| field.valid_field(name)),
|
||||||
|
|
|
@ -17,19 +17,31 @@
|
||||||
* along with Actix Form Data. If not, see <http://www.gnu.org/licenses/>.
|
* along with Actix Form Data. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::{collections::HashMap, fs::DirBuilder, path::{Path, PathBuf},
|
use std::{
|
||||||
sync::{Arc, atomic::{AtomicUsize, Ordering}}};
|
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 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 futures_fs::FsPool;
|
||||||
use http::header::CONTENT_DISPOSITION;
|
use http::header::CONTENT_DISPOSITION;
|
||||||
|
|
||||||
use error::Error;
|
|
||||||
use super::FilenameGenerator;
|
use super::FilenameGenerator;
|
||||||
use types::{self, ContentDisposition, MultipartContent, MultipartForm, MultipartHash, NamePart,
|
use error::Error;
|
||||||
Value};
|
use types::{
|
||||||
|
self, ContentDisposition, MultipartContent, MultipartForm, MultipartHash, NamePart, Value,
|
||||||
|
};
|
||||||
|
|
||||||
fn consolidate(mf: MultipartForm) -> Value {
|
fn consolidate(mf: MultipartForm) -> Value {
|
||||||
mf.into_iter().fold(
|
mf.into_iter().fold(
|
||||||
|
@ -184,35 +196,38 @@ where
|
||||||
|
|
||||||
tx.send(res).map_err(|_| ())
|
tx.send(res).map_err(|_| ())
|
||||||
}))) {
|
}))) {
|
||||||
| Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => return Box::new(result(Err(Error::MkDir))),
|
Err(_) => return Box::new(result(Err(Error::MkDir))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let counter = Arc::new(AtomicUsize::new(0));
|
let counter = Arc::new(AtomicUsize::new(0));
|
||||||
|
|
||||||
Box::new(rx.then(|res| match res {
|
Box::new(
|
||||||
Ok(res) => res,
|
rx.then(|res| match res {
|
||||||
Err(_) => Err(Error::MkDir),
|
Ok(res) => res,
|
||||||
}).and_then(move |_| {
|
Err(_) => Err(Error::MkDir),
|
||||||
let write =
|
})
|
||||||
FsPool::from_executor(form.pool.clone()).write(stored_as.clone(), Default::default());
|
.and_then(move |_| {
|
||||||
field
|
let write = FsPool::with_executor(form.pool.clone())
|
||||||
.map_err(Error::Multipart)
|
.write(stored_as.clone(), Default::default());
|
||||||
.and_then(move |bytes| {
|
field
|
||||||
let size = counter.fetch_add(bytes.len(), Ordering::Relaxed) + bytes.len();
|
.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 {
|
if size > form.max_file_size {
|
||||||
Err(Error::FileSize)
|
Err(Error::FileSize)
|
||||||
} else {
|
} else {
|
||||||
Ok(bytes)
|
Ok(bytes)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.forward(write)
|
.forward(write)
|
||||||
.map(move |_| MultipartContent::File {
|
.map(move |_| MultipartContent::File {
|
||||||
filename,
|
filename,
|
||||||
stored_as,
|
stored_as,
|
||||||
})
|
})
|
||||||
}))
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_form_data<S>(
|
fn handle_form_data<S>(
|
||||||
|
|
Loading…
Reference in a new issue