1
0
mirror of https://github.com/actix/examples synced 2024-12-03 18:22:14 +01:00
examples/multipart/src/main.rs

98 lines
3.0 KiB
Rust
Raw Normal View History

2018-07-16 08:36:53 +02:00
use std::cell::Cell;
2019-04-14 19:34:41 +02:00
use std::fs;
2018-06-08 06:34:14 +02:00
use std::io::Write;
2019-04-14 19:34:41 +02:00
use actix_multipart::{Field, Multipart, MultipartError};
2019-03-29 21:43:03 +01:00
use actix_web::{error, middleware, web, App, Error, HttpResponse, HttpServer};
use futures::future::{err, Either};
2018-05-08 20:08:43 +02:00
use futures::{Future, Stream};
2018-06-20 17:03:56 +02:00
pub struct AppState {
pub counter: Cell<usize>,
}
2019-04-08 08:39:45 +02:00
pub fn save_file(field: Field) -> impl Future<Item = i64, Error = Error> {
2018-06-08 06:34:14 +02:00
let file_path_string = "upload.png";
2019-04-21 18:36:31 +02:00
let file = match fs::File::create(file_path_string) {
2018-06-08 06:34:14 +02:00
Ok(file) => file,
2019-04-14 19:34:41 +02:00
Err(e) => return Either::A(err(error::ErrorInternalServerError(e))),
2018-06-08 06:34:14 +02:00
};
2019-03-29 21:43:03 +01:00
Either::B(
2018-06-08 06:34:14 +02:00
field
2019-04-21 18:36:31 +02:00
.fold((file, 0i64), move |(mut file, mut acc), bytes| {
// fs operations are blocking, we have to execute writes
// on threadpool
web::block(move || {
2019-05-05 06:52:24 +02:00
file.write_all(bytes.as_ref()).map_err(|e| {
println!("file.write_all failed: {:?}", e);
MultipartError::Payload(error::PayloadError::Io(e))
})?;
2019-04-22 15:10:25 +02:00
acc += bytes.len() as i64;
2019-04-21 18:36:31 +02:00
Ok((file, acc))
})
.map_err(|e: error::BlockingError<MultipartError>| {
match e {
error::BlockingError::Error(e) => e,
error::BlockingError::Canceled => MultipartError::Incomplete,
}
})
2018-06-08 06:34:14 +02:00
})
2019-04-21 18:36:31 +02:00
.map(|(_, acc)| acc)
2018-06-08 06:34:14 +02:00
.map_err(|e| {
println!("save_file failed, {:?}", e);
error::ErrorInternalServerError(e)
}),
)
}
2019-03-29 21:43:03 +01:00
pub fn upload(
2019-04-08 08:39:45 +02:00
multipart: Multipart,
2019-03-29 21:43:03 +01:00
counter: web::Data<Cell<usize>>,
) -> impl Future<Item = HttpResponse, Error = Error> {
counter.set(counter.get() + 1);
println!("{:?}", counter.get());
2019-03-29 21:43:03 +01:00
multipart
.map_err(error::ErrorInternalServerError)
2019-04-14 19:34:41 +02:00
.map(|field| save_file(field).into_stream())
.flatten()
2019-03-29 21:43:03 +01:00
.collect()
.map(|sizes| HttpResponse::Ok().json(sizes))
.map_err(|e| {
println!("failed: {}", e);
e
2019-03-29 21:43:03 +01:00
})
2018-06-08 06:34:14 +02:00
}
2019-03-29 21:43:03 +01:00
fn index() -> HttpResponse {
2018-06-08 06:34:14 +02:00
let html = r#"<html>
<head><title>Upload Test</title></head>
<body>
<form target="/" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" value="Submit"></button>
</form>
</body>
</html>"#;
2019-03-29 21:43:03 +01:00
HttpResponse::Ok().body(html)
}
2019-03-29 21:43:03 +01:00
fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_server=info,actix_web=info");
2018-06-08 06:34:14 +02:00
env_logger::init();
2019-03-29 21:43:03 +01:00
HttpServer::new(|| {
App::new()
.data(Cell::new(0usize))
.wrap(middleware::Logger::default())
.service(
web::resource("/")
.route(web::get().to(index))
.route(web::post().to_async(upload)),
)
2019-03-10 03:03:09 +01:00
})
2019-03-29 21:43:03 +01:00
.bind("127.0.0.1:8080")?
.run()
}