1
0
mirror of https://github.com/actix/examples synced 2024-12-02 18:02:22 +01:00
examples/multipart/src/main.rs
2019-04-04 11:37:14 -07:00

100 lines
2.9 KiB
Rust

use std::cell::Cell;
use std::fs;
use std::io::Write;
use actix_web::{error, middleware, web, App, Error, HttpResponse, HttpServer};
use futures::future::{err, Either};
use futures::{Future, Stream};
pub struct AppState {
pub counter: Cell<usize>,
}
pub fn save_file(field: web::MultipartField) -> impl Future<Item = i64, Error = Error> {
let file_path_string = "upload.png";
let mut file = match fs::File::create(file_path_string) {
Ok(file) => file,
Err(e) => return Either::A(err(error::ErrorInternalServerError(e))),
};
Either::B(
field
.fold(0i64, move |acc, bytes| {
println!("CHUNK: {:?}", bytes.len());
file.write_all(bytes.as_ref())
.map(|_| acc + bytes.len() as i64)
.map_err(|e| {
println!("file.write_all failed: {:?}", e);
error::MultipartError::Payload(error::PayloadError::Io(e))
})
})
.map_err(|e| {
println!("save_file failed, {:?}", e);
error::ErrorInternalServerError(e)
}),
)
}
pub fn handle_multipart_item(
item: web::MultipartItem,
) -> Box<Stream<Item = i64, Error = Error>> {
match item {
web::MultipartItem::Field(field) => Box::new(save_file(field).into_stream()),
web::MultipartItem::Nested(mp) => Box::new(
mp.map_err(error::ErrorInternalServerError)
.map(handle_multipart_item)
.flatten(),
),
}
}
pub fn upload(
multipart: web::Multipart,
counter: web::Data<Cell<usize>>,
) -> impl Future<Item = HttpResponse, Error = Error> {
counter.set(counter.get() + 1);
println!("{:?}", counter.get());
multipart
.map_err(error::ErrorInternalServerError)
.map(handle_multipart_item)
.flatten()
.collect()
.map(|sizes| HttpResponse::Ok().json(sizes))
.map_err(|e| {
println!("failed: {}", e);
e
})
}
fn index() -> HttpResponse {
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>"#;
HttpResponse::Ok().body(html)
}
fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_server=info,actix_web=info");
env_logger::init();
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)),
)
})
.bind("127.0.0.1:8080")?
.run()
}