From 2fa3f145976685c780409de77518c9995633dd93 Mon Sep 17 00:00:00 2001 From: blek Date: Sun, 1 Oct 2023 10:14:35 +1000 Subject: [PATCH] stateful warp controllers --- filed/Cargo.lock | 33 +++++++++++++++++++++++++++++++++ filed/Cargo.toml | 1 + filed/src/db.rs | 12 ++++++++++++ filed/src/env.rs | 20 ++++++++++++++++++-- filed/src/main.rs | 1 + filed/src/web/forms.rs | 12 ++++++++---- filed/src/web/mod.rs | 15 +++++++++++---- filed/src/web/pages.rs | 4 +++- filed/src/web/state.rs | 7 +++++++ 9 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 filed/src/db.rs create mode 100644 filed/src/web/state.rs diff --git a/filed/Cargo.lock b/filed/Cargo.lock index e3fd44e..dcf75ad 100644 --- a/filed/Cargo.lock +++ b/filed/Cargo.lock @@ -130,6 +130,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -215,6 +225,7 @@ dependencies = [ "femme", "futures-util", "log", + "redis", "tokio", "warp", ] @@ -696,6 +707,22 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redis" +version = "0.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f49cdc0bb3f412bf8e7d1bd90fe1d9eb10bc5c399ba90973c14662a27b3f8ba" +dependencies = [ + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1_smol", + "socket2 0.4.9", + "tokio", + "url", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -786,6 +813,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "slab" version = "0.4.9" diff --git a/filed/Cargo.toml b/filed/Cargo.toml index 94f065b..78067f3 100644 --- a/filed/Cargo.toml +++ b/filed/Cargo.toml @@ -12,5 +12,6 @@ dotenvy = "0.15.7" femme = "2.2.1" futures-util = "0.3.28" log = "0.4.20" +redis = { version = "0.23.3", features = ["tokio"] } tokio = { version = "1.32.0", features = ["rt", "macros", "rt-multi-thread"] } warp = "0.3.6" diff --git a/filed/src/db.rs b/filed/src/db.rs new file mode 100644 index 0000000..c7cef52 --- /dev/null +++ b/filed/src/db.rs @@ -0,0 +1,12 @@ +/* + db.rs - The database adapter +*/ + +use redis::{Client, RedisError}; + +use crate::env::Env; + +pub fn redis_conn(env: Env) -> Result { + log::info!("Connecting to redis DB on {}", env.redis.host); + redis::Client::open(format!("redis://{}:{}/", env.redis.host, env.redis.port)) +} \ No newline at end of file diff --git a/filed/src/env.rs b/filed/src/env.rs index d5cf79a..8df99bf 100644 --- a/filed/src/env.rs +++ b/filed/src/env.rs @@ -5,9 +5,19 @@ use std::{env::var, net::SocketAddr}; +#[derive(Debug, Clone)] +pub struct Redis { + pub pass: String, + pub host: String, + pub port: u16, + pub prefix: String +} + +#[derive(Debug, Clone)] pub struct Env { pub logging: bool, - pub listen: SocketAddr + pub listen: SocketAddr, + pub redis: Redis, } fn get_var, O: From>(name: T) -> Result { @@ -23,7 +33,13 @@ pub fn loadenv() -> Result> { Ok( Env { logging: get_var::<&str, String>("APP_LOGGING")?.to_lowercase() == "true", - listen: get_var::<&str, String>("APP_HOST")?.parse::().unwrap() + listen: get_var::<&str, String>("APP_HOST")?.parse::().unwrap(), + redis: Redis { + pass: get_var("REDIS_PASS")?, + host: get_var("REDIS_HOST")?, + port: get_var::<&str, String>("REDIS_PORT")?.parse().unwrap(), + prefix: get_var("REDIS_PREFIX")? + } } ) } \ No newline at end of file diff --git a/filed/src/main.rs b/filed/src/main.rs index 2e253dd..e5f4b01 100644 --- a/filed/src/main.rs +++ b/filed/src/main.rs @@ -4,6 +4,7 @@ mod env; mod web; +mod db; #[tokio::main] async fn main() { diff --git a/filed/src/web/forms.rs b/filed/src/web/forms.rs index 28ed684..1aafa80 100644 --- a/filed/src/web/forms.rs +++ b/filed/src/web/forms.rs @@ -5,11 +5,13 @@ use std::collections::HashMap; -use warp::{Filter, reply::{Html, Reply}, reject::Rejection, filters::multipart::FormData}; +use warp::{Filter, reply::Reply, reject::Rejection, filters::multipart::FormData}; use futures_util::TryStreamExt; use bytes::BufMut; -pub async fn upload(form: FormData) -> Result, Rejection> { +use super::state::SharedState; + +pub async fn upload(form: FormData, _state: SharedState) -> Result, Rejection> { let params: HashMap = form.and_then(|mut field| async move { let mut bytes: Vec = vec![]; @@ -23,8 +25,10 @@ pub async fn upload(form: FormData) -> Result, Rejection> { Ok(Box::new(warp::reply::json(¶ms))) } -pub fn get_routes() -> impl Filter + Clone { +pub fn get_routes(state: SharedState) -> impl Filter + Clone { warp::post().and( - warp::multipart::form().and_then(upload) + warp::multipart::form() + .and(warp::any().map(move || state.clone())) + .and_then(upload) ) } \ No newline at end of file diff --git a/filed/src/web/mod.rs b/filed/src/web/mod.rs index 3384853..521786b 100644 --- a/filed/src/web/mod.rs +++ b/filed/src/web/mod.rs @@ -10,13 +10,16 @@ use crate::env::Env; mod pages; mod forms; +mod state; -pub fn routes() -> impl Filter + Clone { +use state::SharedState; + +pub fn routes(state: SharedState) -> impl Filter + Clone { let staticpath = current_dir().unwrap(); let staticpath = staticpath.to_str().unwrap().to_string() + "/static"; - pages::get_routes() - .or(forms::get_routes()) + pages::get_routes(state.clone()) + .or(forms::get_routes(state)) .or(warp::fs::dir(staticpath.to_string())) } @@ -27,5 +30,9 @@ pub async fn serve(env: Env) { log::info!("Listening on {}", env.listen.to_string()); - warp::serve(routes()).run(env.listen).await; + let state = SharedState { + redis_cli: crate::db::redis_conn(env.clone()).unwrap() + }; + + warp::serve(routes(state)).run(env.listen).await; } \ No newline at end of file diff --git a/filed/src/web/pages.rs b/filed/src/web/pages.rs index 5fc35c3..3a91a8a 100644 --- a/filed/src/web/pages.rs +++ b/filed/src/web/pages.rs @@ -5,6 +5,8 @@ use warp::{reply::{Reply, Html}, Filter, reject::Rejection}; use askama::Template; +use super::state::SharedState; + #[derive(Template)] #[template( path = "index.html" )] struct Index {} @@ -14,7 +16,7 @@ pub fn index() -> Html { warp::reply::html(rendered.render().unwrap()) } -pub fn get_routes() -> impl Filter + Clone { +pub fn get_routes(_state: SharedState) -> impl Filter + Clone { let index_r = warp::path::end().map(index); warp::any().and(index_r) diff --git a/filed/src/web/state.rs b/filed/src/web/state.rs new file mode 100644 index 0000000..78f93f6 --- /dev/null +++ b/filed/src/web/state.rs @@ -0,0 +1,7 @@ + +use redis::Client; + +#[derive(Debug, Clone)] +pub struct SharedState { + pub redis_cli: Client +}