From 0d7356ec1f3c012f7f0ce18712205b0885a44684 Mon Sep 17 00:00:00 2001 From: tuxmain Date: Sat, 29 Oct 2022 11:03:37 +0200 Subject: [PATCH] opti: Replace Arc with &'static --- Cargo.lock | 7 ++++ Cargo.toml | 1 + src/cleaner.rs | 8 ++-- src/main.rs | 10 +++-- src/notify.rs | 11 ++---- src/server.rs | 105 ++++++++++++++++++------------------------------- 6 files changed, 61 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a35e4f6..375a1a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2529,6 +2529,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "static-rc" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91d0104a7b28aeda24b30919f83222570111ac0bf1aab23aaffb8f59330e654" + [[package]] name = "stdweb" version = "0.4.20" @@ -3209,6 +3215,7 @@ dependencies = [ "serde", "sha2 0.10.6", "sled", + "static-rc", "tera", "tide", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 75f5ca6..c5bd4d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ rpassword = "7.1.0" serde = { version = "1.0.147", features = ["derive", "rc"] } sha2 = "0.10.6" sled = "0.34.7" +static-rc = "0.6.1" tera = { version = "1.17.1", features = ["builtins", "date-locale"] } tide = { version = "0.16.0", default-features = false, features = ["h1-server", "cookies", "logger"] } tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] } diff --git a/src/cleaner.rs b/src/cleaner.rs index a1017f6..82c8c34 100644 --- a/src/cleaner.rs +++ b/src/cleaner.rs @@ -1,8 +1,8 @@ use crate::{config::Config, db::*}; -use std::{sync::Arc, time::Duration}; +use std::time::Duration; -pub async fn run_cleaner(config: Arc, dbs: Dbs) { +pub async fn run_cleaner(config: &Config, dbs: Dbs) { let mut last_db_clean = 0; loop { let time = std::time::SystemTime::now() @@ -11,7 +11,7 @@ pub async fn run_cleaner(config: Arc, dbs: Dbs) { .as_secs(); if time > last_db_clean + 3600 { - clean_antispam(config.clone(), dbs.clone(), time); + clean_antispam(config, dbs.clone(), time); last_db_clean = time; } @@ -19,7 +19,7 @@ pub async fn run_cleaner(config: Arc, dbs: Dbs) { } } -fn clean_antispam(config: Arc, dbs: Dbs, time: u64) { +fn clean_antispam(config: &Config, dbs: Dbs, time: u64) { for (addr, (last_mutation, _mutation_count)) in dbs.client_mutation.iter().filter_map(|o| o.ok()) { diff --git a/src/main.rs b/src/main.rs index 68171f4..d02f6c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,6 @@ use argon2::{ Argon2, }; use clap::Parser; -use std::sync::Arc; #[tokio::main] async fn main() { @@ -25,9 +24,12 @@ async fn main() { } cli::MainSubcommand::Start(subopt) => { let (config, dbs, templates) = init_all(opt.opt, subopt); - let config = Arc::new(config); - let templates = Arc::new(templates); - tokio::spawn(cleaner::run_cleaner(config.clone(), dbs.clone())); + + // These will never be dropped nor mutated + let templates = Box::leak(Box::new(templates)); + let config = Box::leak(Box::new(config)); + + tokio::spawn(cleaner::run_cleaner(config, dbs.clone())); server::run_server(config, dbs, templates).await; } cli::MainSubcommand::Psw => { diff --git a/src/notify.rs b/src/notify.rs index 129ae39..50f5791 100644 --- a/src/notify.rs +++ b/src/notify.rs @@ -3,10 +3,7 @@ use crate::config::Config; use crossbeam_channel::Receiver; use log::error; use matrix_sdk::ruma; -use std::{ - sync::Arc, - time::{Duration, SystemTime}, -}; +use std::time::{Duration, SystemTime}; enum OptionSince { Some(T), @@ -80,10 +77,10 @@ impl Notifier { } } -pub async fn run_notifier(config: Arc, recv: Receiver<()>) { - let mut notifier = Notifier::new(&config).await; +pub async fn run_notifier(config: &Config, recv: Receiver<()>) { + let mut notifier = Notifier::new(config).await; for () in recv { - notifier.notify(&config).await; + notifier.notify(config).await; } } diff --git a/src/server.rs b/src/server.rs index 43b9232..33b8cdb 100644 --- a/src/server.rs +++ b/src/server.rs @@ -3,65 +3,40 @@ use crate::{config::*, db::*, helpers, queries::*, templates::*}; use argon2::{Argon2, PasswordHash, PasswordVerifier}; use crossbeam_channel::Sender; use log::{error, warn}; -use std::sync::Arc; use tera::Context; -pub async fn run_server(config: Arc, dbs: Dbs, templates: Arc) { +pub async fn run_server(config: &'static Config, dbs: Dbs, templates: &'static Templates) { tide::log::start(); let (notify_send, notify_recv) = crossbeam_channel::bounded(10); - tokio::spawn(crate::notify::run_notifier(config.clone(), notify_recv)); + tokio::spawn(crate::notify::run_notifier(config, notify_recv)); let mut app = tide::new(); app.at(&format!("{}t/:topic", config.root_url)).get({ - let config = config.clone(); - let templates = templates.clone(); let dbs = dbs.clone(); move |req: tide::Request<()>| { - serve_comments( - req, - config.clone(), - templates.clone(), - dbs.clone(), - Context::new(), - 200, - ) + serve_comments(req, config, templates, dbs.clone(), Context::new(), 200) } }); app.at(&format!("{}t/:topic", config.root_url)).post({ - let config = config.clone(); - let templates = templates.clone(); let dbs = dbs.clone(); move |req: tide::Request<()>| { - handle_post_comments( - req, - config.clone(), - templates.clone(), - dbs.clone(), - notify_send.clone(), - ) + handle_post_comments(req, config, templates, dbs.clone(), notify_send.clone()) } }); - app.at(&format!("{}admin", config.root_url)).get({ - let config = config.clone(); - let templates = templates.clone(); - move |req: tide::Request<()>| serve_admin_login(req, config.clone(), templates.clone()) - }); + app.at(&format!("{}admin", config.root_url)) + .get(move |req: tide::Request<()>| serve_admin_login(req, config, templates)); app.at(&format!("{}admin", config.root_url)).post({ - let config = config.clone(); - let templates = templates.clone(); let dbs = dbs.clone(); - move |req: tide::Request<()>| { - handle_post_admin(req, config.clone(), templates.clone(), dbs.clone()) - } + move |req: tide::Request<()>| handle_post_admin(req, config, templates, dbs.clone()) }); app.listen(config.listen).await.unwrap(); } async fn serve_comments<'a>( req: tide::Request<()>, - config: Arc, - templates: Arc, + config: &Config, + templates: &Templates, dbs: Dbs, mut context: Context, status_code: u16, @@ -71,7 +46,7 @@ async fn serve_comments<'a>( }; let admin = req.cookie("admin").map_or(false, |psw| { - check_admin_password_hash(&config, &String::from(psw.value())) + check_admin_password_hash(config, &String::from(psw.value())) }); let topic_hash = TopicHash::from_topic(topic); @@ -142,8 +117,8 @@ async fn serve_comments<'a>( async fn serve_admin<'a>( _req: tide::Request<()>, - config: Arc, - templates: Arc, + config: &Config, + templates: &Templates, dbs: Dbs, ) -> tide::Result { let mut context = Context::new(); @@ -187,8 +162,8 @@ async fn serve_admin<'a>( async fn serve_admin_login( _req: tide::Request<()>, - config: Arc, - templates: Arc, + config: &Config, + templates: &Templates, ) -> tide::Result { let mut context = Context::new(); context.insert("config", &config); @@ -201,17 +176,17 @@ async fn serve_admin_login( async fn handle_post_comments( mut req: tide::Request<()>, - config: Arc, - templates: Arc, + config: &Config, + templates: &Templates, dbs: Dbs, notify_send: Sender<()>, ) -> tide::Result { let admin = req.cookie("admin").map_or(false, |psw| { - check_admin_password_hash(&config, &String::from(psw.value())) + check_admin_password_hash(config, &String::from(psw.value())) }); let client_addr = if !admin && config.antispam_enable { - match helpers::get_client_addr(&config, &req) { + match helpers::get_client_addr(config, &req) { Some(Ok(addr)) => { if config.antispam_whitelist.contains(&addr) { None @@ -241,11 +216,11 @@ async fn handle_post_comments( return Err(tide::Error::from_str(404, "No topic")) }; - helpers::check_comment(&config, &query.comment, &mut errors); + helpers::check_comment(config, &query.comment, &mut errors); if let Some(client_addr) = &client_addr { if let Some(antispam_timeout) = - helpers::antispam_check_client_mutation(client_addr, &dbs, &config).unwrap() + helpers::antispam_check_client_mutation(client_addr, &dbs, config).unwrap() { errors.push(format!( "The edition quota from your IP is reached. You will be unblocked in {}s.", @@ -294,7 +269,7 @@ async fn handle_post_comments( return Err(tide::Error::from_str(403, "Forbidden")); } - helpers::check_comment(&config, &query.comment, &mut errors); + helpers::check_comment(config, &query.comment, &mut errors); let comment_id = if let Ok(comment_id) = CommentId::from_base64(&query.id) { comment_id @@ -310,7 +285,7 @@ async fn handle_post_comments( if let Some(client_addr) = &client_addr { if let Some(antispam_timeout) = - helpers::antispam_check_client_mutation(client_addr, &dbs, &config).unwrap() + helpers::antispam_check_client_mutation(client_addr, &dbs, config).unwrap() { errors.push(format!( "The edition quota from your IP is reached. You will be unblocked in {}s.", @@ -361,12 +336,12 @@ async fn handle_post_comments( async fn handle_post_admin( mut req: tide::Request<()>, - config: Arc, - templates: Arc, + config: &Config, + templates: &Templates, dbs: Dbs, ) -> tide::Result { if let Some(psw) = req.cookie("admin") { - if check_admin_password(&config, &String::from(psw.value())).is_some() { + if check_admin_password(config, &String::from(psw.value())).is_some() { #[allow(clippy::match_single_binding)] match req.body_form::().await? { _ => serve_admin(req, config, templates, dbs).await, @@ -375,22 +350,20 @@ async fn handle_post_admin( serve_admin_login(req, config, templates).await } } else if let AdminQuery::Login(query) = req.body_form::().await? { - if let Some(password_hash) = check_admin_password(&config, &query.psw) { - serve_admin(req, config.clone(), templates, dbs) - .await - .map(|mut r| { - let mut cookie = tide::http::Cookie::new("admin", password_hash); - cookie.set_http_only(Some(true)); - cookie.set_path(config.root_url.clone()); - if let Some(domain) = &config.cookies_domain { - cookie.set_domain(domain.clone()); - } - if config.cookies_https_only { - cookie.set_secure(Some(true)); - } - r.insert_cookie(cookie); - r - }) + if let Some(password_hash) = check_admin_password(config, &query.psw) { + serve_admin(req, config, templates, dbs).await.map(|mut r| { + let mut cookie = tide::http::Cookie::new("admin", password_hash); + cookie.set_http_only(Some(true)); + cookie.set_path(config.root_url.clone()); + if let Some(domain) = &config.cookies_domain { + cookie.set_domain(domain.clone()); + } + if config.cookies_https_only { + cookie.set_secure(Some(true)); + } + r.insert_cookie(cookie); + r + }) } else { serve_admin_login(req, config, templates).await }