u/src/routes/upload.rs
2023-04-28 13:19:02 -04:00

57 lines
1.3 KiB
Rust

use crate::{auth::Auth, state::ReqState};
use axum::{
extract::{Multipart, State},
response::IntoResponse,
Json,
};
use hyper::StatusCode;
use serde::Serialize;
#[derive(Serialize)]
struct UploadResponse {
id: String,
revocation_key: String,
}
pub async fn post(
State(state): ReqState,
Auth(_): Auth,
mut multipart: Multipart,
) -> impl IntoResponse {
let mut file = None;
while let Some(field) = multipart.next_field().await.unwrap() {
let bytes = field.bytes().await;
if bytes.is_ok() {
file = Some(bytes.unwrap());
}
}
if file.is_none() {
return Err(StatusCode::BAD_REQUEST);
}
let file = file.unwrap();
let mut id = crate::utils::gen_filename();
while state.files_dir.join(&id).exists() {
id = crate::utils::gen_filename();
}
let path = state.files_dir.join(id.clone());
tokio::fs::write(path, file)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let revocation_key = crate::utils::gen_revocation_key();
sqlx::query!(
"insert into files (id, revocation_key) values ($1, $2)",
id,
revocation_key
)
.execute(&state.db)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(Json(UploadResponse { id, revocation_key }))
}