2020-06-06 02:40:44 +00:00
|
|
|
use actix_form_data::{Error, Field, Form, Value};
|
2018-10-09 23:35:10 +00:00
|
|
|
use actix_web::{
|
2020-06-06 02:40:44 +00:00
|
|
|
http::StatusCode,
|
2019-05-08 23:11:26 +00:00
|
|
|
middleware::Logger,
|
2020-06-06 02:40:44 +00:00
|
|
|
web::{post, resource},
|
2019-05-08 23:11:26 +00:00
|
|
|
App, HttpResponse, HttpServer, ResponseError,
|
2018-10-09 23:35:10 +00:00
|
|
|
};
|
2020-06-06 02:40:44 +00:00
|
|
|
use bytes::Bytes;
|
|
|
|
use futures::stream::{Stream, TryStreamExt};
|
2019-05-08 23:11:26 +00:00
|
|
|
use log::info;
|
2020-06-06 02:40:44 +00:00
|
|
|
use std::{
|
|
|
|
env,
|
|
|
|
pin::Pin,
|
|
|
|
sync::{
|
|
|
|
atomic::{AtomicUsize, Ordering},
|
|
|
|
Arc,
|
|
|
|
},
|
|
|
|
};
|
2018-04-29 22:31:06 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
struct AppState {
|
|
|
|
form: Form,
|
|
|
|
}
|
|
|
|
|
2020-06-06 02:40:44 +00:00
|
|
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
2018-04-29 22:31:06 +00:00
|
|
|
struct JsonError {
|
|
|
|
msg: String,
|
|
|
|
}
|
|
|
|
|
2020-06-06 02:40:44 +00:00
|
|
|
impl<T> From<T> for JsonError
|
|
|
|
where
|
|
|
|
T: std::error::Error,
|
|
|
|
{
|
|
|
|
fn from(e: T) -> Self {
|
2018-04-29 22:31:06 +00:00
|
|
|
JsonError {
|
|
|
|
msg: format!("{}", e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-06 02:40:44 +00:00
|
|
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, thiserror::Error)]
|
|
|
|
#[error("Errors occurred")]
|
2018-04-29 22:31:06 +00:00
|
|
|
struct Errors {
|
|
|
|
errors: Vec<JsonError>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<JsonError> for Errors {
|
|
|
|
fn from(e: JsonError) -> Self {
|
|
|
|
Errors { errors: vec![e] }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ResponseError for Errors {
|
2020-06-06 02:40:44 +00:00
|
|
|
fn status_code(&self) -> StatusCode {
|
|
|
|
StatusCode::BAD_REQUEST
|
|
|
|
}
|
|
|
|
|
2018-04-29 22:31:06 +00:00
|
|
|
fn error_response(&self) -> HttpResponse {
|
|
|
|
HttpResponse::BadRequest().json(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-06 02:40:44 +00:00
|
|
|
async fn upload(uploaded_content: Value) -> HttpResponse {
|
|
|
|
info!("Uploaded Content: {:#?}", uploaded_content);
|
|
|
|
|
|
|
|
HttpResponse::Created().finish()
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn save_file(
|
|
|
|
stream: Pin<Box<dyn Stream<Item = Result<Bytes, Error>>>>,
|
|
|
|
count: usize,
|
|
|
|
) -> Result<(), JsonError> {
|
|
|
|
let stream = stream.err_into::<JsonError>();
|
|
|
|
let filename = format!("examples/filename{}.png", count);
|
|
|
|
|
|
|
|
info!("Creating {}", filename);
|
|
|
|
let file = actix_fs::create(filename.clone()).await?;
|
|
|
|
|
|
|
|
info!("Writing to file");
|
|
|
|
if let Err(e) = actix_fs::write_stream(file, stream).await {
|
|
|
|
info!("Error writing, deleting file");
|
|
|
|
actix_fs::remove(filename.clone()).await?;
|
|
|
|
return Err(e);
|
|
|
|
}
|
|
|
|
info!("Written!");
|
|
|
|
|
|
|
|
Ok(())
|
2018-04-29 22:31:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-06 02:40:44 +00:00
|
|
|
#[actix_rt::main]
|
|
|
|
async fn main() -> Result<(), anyhow::Error> {
|
2018-04-29 22:31:06 +00:00
|
|
|
env::set_var("RUST_LOG", "upload=info");
|
|
|
|
env_logger::init();
|
|
|
|
|
2020-06-06 02:40:44 +00:00
|
|
|
let file_count = Arc::new(AtomicUsize::new(0));
|
2018-04-29 22:31:06 +00:00
|
|
|
|
|
|
|
let form = Form::new()
|
|
|
|
.field("Hey", Field::text())
|
|
|
|
.field(
|
|
|
|
"Hi",
|
|
|
|
Field::map()
|
|
|
|
.field("One", Field::int())
|
|
|
|
.field("Two", Field::float())
|
|
|
|
.finalize(),
|
|
|
|
)
|
2020-06-06 02:40:44 +00:00
|
|
|
.field(
|
|
|
|
"files",
|
|
|
|
Field::array(Field::file(move |_filename, _content_type, stream| {
|
|
|
|
let count = file_count.clone().fetch_add(1, Ordering::Relaxed);
|
|
|
|
async move { save_file(stream, count).await.map_err(Errors::from) }
|
|
|
|
})),
|
|
|
|
);
|
2018-04-29 22:31:06 +00:00
|
|
|
|
2020-06-06 02:40:44 +00:00
|
|
|
info!("{:#?}", form);
|
2018-04-29 22:31:06 +00:00
|
|
|
|
2019-05-08 23:11:26 +00:00
|
|
|
HttpServer::new(move || {
|
|
|
|
App::new()
|
2020-06-06 02:40:44 +00:00
|
|
|
.wrap(form.clone())
|
2019-05-08 23:11:26 +00:00
|
|
|
.wrap(Logger::default())
|
|
|
|
.service(resource("/upload").route(post().to(upload)))
|
2018-10-09 23:35:10 +00:00
|
|
|
})
|
2019-05-08 23:11:26 +00:00
|
|
|
.bind("127.0.0.1:8080")?
|
2020-06-06 02:40:44 +00:00
|
|
|
.run()
|
|
|
|
.await?;
|
2019-05-08 23:11:26 +00:00
|
|
|
|
|
|
|
Ok(())
|
2018-04-29 22:31:06 +00:00
|
|
|
}
|