From c18cb8aede8fc60b88bf499655808c955c59eacd Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sat, 2 Apr 2022 13:01:49 +0200 Subject: [PATCH] Removed any (locally) hardcoded values --- Cargo.lock | 29 ++++++++++++++++++++++++++++- Cargo.toml | 1 + src/main.rs | 48 ++++++++++++++++++++++++++---------------------- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b85559..09e1334 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,6 +204,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + [[package]] name = "h2" version = "0.3.13" @@ -412,7 +423,7 @@ dependencies = [ "log", "miow", "ntapi", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "winapi", ] @@ -635,6 +646,7 @@ dependencies = [ "tower-http", "tracing", "tracing-subscriber", + "uuid", ] [[package]] @@ -881,6 +893,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "uuid" +version = "1.0.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb3ab47baa004111b323696c6eaa2752e7356f7f77cf6b6dc7a2087368ce1ca4" +dependencies = [ + "getrandom", +] + [[package]] name = "valuable" version = "0.1.0" @@ -903,6 +924,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 57222ce..56cefe2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,4 @@ tar = "0.4.38" flate2 = "1.0.22" tokio-util = { version = "0.7.1", features = ["io"] } futures-util = "0.3.21" +uuid = { version = "1.0.0-alpha.1", features = ["v4"] } diff --git a/src/main.rs b/src/main.rs index d30cd4f..40e299b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use axum::{ - extract::BodyStream, + extract::{BodyStream, Extension}, http::StatusCode, response::IntoResponse, routing::{get_service, post}, @@ -16,6 +16,8 @@ use tokio_util::io::StreamReader; use tower_http::{auth::RequireAuthorizationLayer, services::ServeDir, trace::TraceLayer}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; +const STATIC_DIR_NAME: &str = "static"; + #[tokio::main] async fn main() { // Enable tracing @@ -30,8 +32,9 @@ async fn main() { // Get required variables from env vars let api_key = std::env::var("API_KEY").expect("No API_KEY was provided."); let data_dir = std::env::var("DATA_DIR").expect("No DATA_DIR was provided."); + let static_dir = format!("{}/{}", data_dir, STATIC_DIR_NAME); - std::fs::create_dir_all(&data_dir).unwrap(); + std::fs::create_dir_all(&static_dir); let app = Router::new() .route( @@ -39,17 +42,16 @@ async fn main() { post(post_deploy).layer(RequireAuthorizationLayer::bearer(&api_key)), ) // The fallback option is to serve the actual static files - .fallback( - get_service(ServeDir::new(format!("{}/static", data_dir))).handle_error( - |error: std::io::Error| async move { - ( - StatusCode::INTERNAL_SERVER_ERROR, - format!("Unhandled internal error: {}", error), - ) - }, - ), - ) - .layer(TraceLayer::new_for_http()); + .fallback(get_service(ServeDir::new(static_dir)).handle_error( + |error: std::io::Error| async move { + ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Unhandled internal error: {}", error), + ) + }, + )) + .layer(TraceLayer::new_for_http()) + .layer(Extension(data_dir)); let addr = SocketAddr::from(([0, 0, 0, 0], 3000)); tracing::debug!("listening on {}", addr); @@ -59,17 +61,19 @@ async fn main() { .unwrap(); } -async fn post_deploy(res: BodyStream) -> impl IntoResponse { +async fn post_deploy(Extension(data_dir): Extension, res: BodyStream) -> impl IntoResponse { // This converts a stream into something that implements AsyncRead, which we can then use to // asynchronously write the file to disk let mut read = StreamReader::new(res.map_err(|axum_err| std::io::Error::new(ErrorKind::Other, axum_err))); - let mut file = tokio::fs::File::create("test.archive.gz").await.unwrap(); - tokio::io::copy(&mut read, &mut file).await.unwrap(); + let uuid = uuid::Uuid::new_v4(); + let file_path = Path::new(&data_dir).join(uuid.as_hyphenated().to_string()); + let mut file = tokio::fs::File::create(&file_path).await.unwrap(); + tokio::io::copy(&mut read, &mut file).await; // Extract the contents of the tarball synchronously - match tokio::task::spawn_blocking(|| { - let file = match std::fs::File::open("test.archive.gz") { + match tokio::task::spawn_blocking(move || { + let file = match std::fs::File::open(file_path) { Ok(v) => v, Err(_) => return StatusCode::INTERNAL_SERVER_ERROR, }; @@ -84,9 +88,10 @@ async fn post_deploy(res: BodyStream) -> impl IntoResponse { }; // Extract each entry into the output directory + let static_dir = Path::new(&data_dir).join(STATIC_DIR_NAME); for entry_res in entries { if let Ok(mut entry) = entry_res { - if let Err(_) = entry.unpack_in("static") { + if let Err(_) = entry.unpack_in(&static_dir) { return StatusCode::INTERNAL_SERVER_ERROR; } @@ -102,8 +107,7 @@ async fn post_deploy(res: BodyStream) -> impl IntoResponse { let mut items = vec![]; // Start by populating the vec with the initial files - let base_path = Path::new("static"); - let iter = match base_path.read_dir() { + let iter = match static_dir.read_dir() { Ok(v) => v, Err(_) => return StatusCode::INTERNAL_SERVER_ERROR, }; @@ -115,7 +119,7 @@ async fn post_deploy(res: BodyStream) -> impl IntoResponse { let item = items.pop().unwrap(); tracing::debug!("{:?}", item); - if !paths.contains(item.strip_prefix("static/").unwrap()) { + if !paths.contains(item.strip_prefix(&static_dir).unwrap()) { if item.is_dir() { std::fs::remove_dir_all(item); } else {