opti: Replace Arc with &'static
This commit is contained in:
parent
81681303b2
commit
0d7356ec1f
6 changed files with 61 additions and 81 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -2529,6 +2529,12 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static-rc"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b91d0104a7b28aeda24b30919f83222570111ac0bf1aab23aaffb8f59330e654"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stdweb"
|
name = "stdweb"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
|
@ -3209,6 +3215,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"sha2 0.10.6",
|
"sha2 0.10.6",
|
||||||
"sled",
|
"sled",
|
||||||
|
"static-rc",
|
||||||
"tera",
|
"tera",
|
||||||
"tide",
|
"tide",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|
|
@ -21,6 +21,7 @@ rpassword = "7.1.0"
|
||||||
serde = { version = "1.0.147", features = ["derive", "rc"] }
|
serde = { version = "1.0.147", features = ["derive", "rc"] }
|
||||||
sha2 = "0.10.6"
|
sha2 = "0.10.6"
|
||||||
sled = "0.34.7"
|
sled = "0.34.7"
|
||||||
|
static-rc = "0.6.1"
|
||||||
tera = { version = "1.17.1", features = ["builtins", "date-locale"] }
|
tera = { version = "1.17.1", features = ["builtins", "date-locale"] }
|
||||||
tide = { version = "0.16.0", default-features = false, features = ["h1-server", "cookies", "logger"] }
|
tide = { version = "0.16.0", default-features = false, features = ["h1-server", "cookies", "logger"] }
|
||||||
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{config::Config, db::*};
|
use crate::{config::Config, db::*};
|
||||||
|
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::time::Duration;
|
||||||
|
|
||||||
pub async fn run_cleaner(config: Arc<Config>, dbs: Dbs) {
|
pub async fn run_cleaner(config: &Config, dbs: Dbs) {
|
||||||
let mut last_db_clean = 0;
|
let mut last_db_clean = 0;
|
||||||
loop {
|
loop {
|
||||||
let time = std::time::SystemTime::now()
|
let time = std::time::SystemTime::now()
|
||||||
|
@ -11,7 +11,7 @@ pub async fn run_cleaner(config: Arc<Config>, dbs: Dbs) {
|
||||||
.as_secs();
|
.as_secs();
|
||||||
|
|
||||||
if time > last_db_clean + 3600 {
|
if time > last_db_clean + 3600 {
|
||||||
clean_antispam(config.clone(), dbs.clone(), time);
|
clean_antispam(config, dbs.clone(), time);
|
||||||
last_db_clean = time;
|
last_db_clean = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ pub async fn run_cleaner(config: Arc<Config>, dbs: Dbs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_antispam(config: Arc<Config>, dbs: Dbs, time: u64) {
|
fn clean_antispam(config: &Config, dbs: Dbs, time: u64) {
|
||||||
for (addr, (last_mutation, _mutation_count)) in
|
for (addr, (last_mutation, _mutation_count)) in
|
||||||
dbs.client_mutation.iter().filter_map(|o| o.ok())
|
dbs.client_mutation.iter().filter_map(|o| o.ok())
|
||||||
{
|
{
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -13,7 +13,6 @@ use argon2::{
|
||||||
Argon2,
|
Argon2,
|
||||||
};
|
};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
@ -25,9 +24,12 @@ async fn main() {
|
||||||
}
|
}
|
||||||
cli::MainSubcommand::Start(subopt) => {
|
cli::MainSubcommand::Start(subopt) => {
|
||||||
let (config, dbs, templates) = init_all(opt.opt, subopt);
|
let (config, dbs, templates) = init_all(opt.opt, subopt);
|
||||||
let config = Arc::new(config);
|
|
||||||
let templates = Arc::new(templates);
|
// These will never be dropped nor mutated
|
||||||
tokio::spawn(cleaner::run_cleaner(config.clone(), dbs.clone()));
|
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;
|
server::run_server(config, dbs, templates).await;
|
||||||
}
|
}
|
||||||
cli::MainSubcommand::Psw => {
|
cli::MainSubcommand::Psw => {
|
||||||
|
|
|
@ -3,10 +3,7 @@ use crate::config::Config;
|
||||||
use crossbeam_channel::Receiver;
|
use crossbeam_channel::Receiver;
|
||||||
use log::error;
|
use log::error;
|
||||||
use matrix_sdk::ruma;
|
use matrix_sdk::ruma;
|
||||||
use std::{
|
use std::time::{Duration, SystemTime};
|
||||||
sync::Arc,
|
|
||||||
time::{Duration, SystemTime},
|
|
||||||
};
|
|
||||||
|
|
||||||
enum OptionSince<T> {
|
enum OptionSince<T> {
|
||||||
Some(T),
|
Some(T),
|
||||||
|
@ -80,10 +77,10 @@ impl Notifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_notifier(config: Arc<Config>, recv: Receiver<()>) {
|
pub async fn run_notifier(config: &Config, recv: Receiver<()>) {
|
||||||
let mut notifier = Notifier::new(&config).await;
|
let mut notifier = Notifier::new(config).await;
|
||||||
for () in recv {
|
for () in recv {
|
||||||
notifier.notify(&config).await;
|
notifier.notify(config).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,65 +3,40 @@ use crate::{config::*, db::*, helpers, queries::*, templates::*};
|
||||||
use argon2::{Argon2, PasswordHash, PasswordVerifier};
|
use argon2::{Argon2, PasswordHash, PasswordVerifier};
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use log::{error, warn};
|
use log::{error, warn};
|
||||||
use std::sync::Arc;
|
|
||||||
use tera::Context;
|
use tera::Context;
|
||||||
|
|
||||||
pub async fn run_server(config: Arc<Config>, dbs: Dbs, templates: Arc<Templates>) {
|
pub async fn run_server(config: &'static Config, dbs: Dbs, templates: &'static Templates) {
|
||||||
tide::log::start();
|
tide::log::start();
|
||||||
|
|
||||||
let (notify_send, notify_recv) = crossbeam_channel::bounded(10);
|
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();
|
let mut app = tide::new();
|
||||||
app.at(&format!("{}t/:topic", config.root_url)).get({
|
app.at(&format!("{}t/:topic", config.root_url)).get({
|
||||||
let config = config.clone();
|
|
||||||
let templates = templates.clone();
|
|
||||||
let dbs = dbs.clone();
|
let dbs = dbs.clone();
|
||||||
move |req: tide::Request<()>| {
|
move |req: tide::Request<()>| {
|
||||||
serve_comments(
|
serve_comments(req, config, templates, dbs.clone(), Context::new(), 200)
|
||||||
req,
|
|
||||||
config.clone(),
|
|
||||||
templates.clone(),
|
|
||||||
dbs.clone(),
|
|
||||||
Context::new(),
|
|
||||||
200,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.at(&format!("{}t/:topic", config.root_url)).post({
|
app.at(&format!("{}t/:topic", config.root_url)).post({
|
||||||
let config = config.clone();
|
|
||||||
let templates = templates.clone();
|
|
||||||
let dbs = dbs.clone();
|
let dbs = dbs.clone();
|
||||||
move |req: tide::Request<()>| {
|
move |req: tide::Request<()>| {
|
||||||
handle_post_comments(
|
handle_post_comments(req, config, templates, dbs.clone(), notify_send.clone())
|
||||||
req,
|
|
||||||
config.clone(),
|
|
||||||
templates.clone(),
|
|
||||||
dbs.clone(),
|
|
||||||
notify_send.clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.at(&format!("{}admin", config.root_url)).get({
|
app.at(&format!("{}admin", config.root_url))
|
||||||
let config = config.clone();
|
.get(move |req: tide::Request<()>| serve_admin_login(req, config, templates));
|
||||||
let templates = templates.clone();
|
|
||||||
move |req: tide::Request<()>| serve_admin_login(req, config.clone(), templates.clone())
|
|
||||||
});
|
|
||||||
app.at(&format!("{}admin", config.root_url)).post({
|
app.at(&format!("{}admin", config.root_url)).post({
|
||||||
let config = config.clone();
|
|
||||||
let templates = templates.clone();
|
|
||||||
let dbs = dbs.clone();
|
let dbs = dbs.clone();
|
||||||
move |req: tide::Request<()>| {
|
move |req: tide::Request<()>| handle_post_admin(req, config, templates, dbs.clone())
|
||||||
handle_post_admin(req, config.clone(), templates.clone(), dbs.clone())
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
app.listen(config.listen).await.unwrap();
|
app.listen(config.listen).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn serve_comments<'a>(
|
async fn serve_comments<'a>(
|
||||||
req: tide::Request<()>,
|
req: tide::Request<()>,
|
||||||
config: Arc<Config>,
|
config: &Config,
|
||||||
templates: Arc<Templates>,
|
templates: &Templates,
|
||||||
dbs: Dbs,
|
dbs: Dbs,
|
||||||
mut context: Context,
|
mut context: Context,
|
||||||
status_code: u16,
|
status_code: u16,
|
||||||
|
@ -71,7 +46,7 @@ async fn serve_comments<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let admin = req.cookie("admin").map_or(false, |psw| {
|
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);
|
let topic_hash = TopicHash::from_topic(topic);
|
||||||
|
@ -142,8 +117,8 @@ async fn serve_comments<'a>(
|
||||||
|
|
||||||
async fn serve_admin<'a>(
|
async fn serve_admin<'a>(
|
||||||
_req: tide::Request<()>,
|
_req: tide::Request<()>,
|
||||||
config: Arc<Config>,
|
config: &Config,
|
||||||
templates: Arc<Templates>,
|
templates: &Templates,
|
||||||
dbs: Dbs,
|
dbs: Dbs,
|
||||||
) -> tide::Result<tide::Response> {
|
) -> tide::Result<tide::Response> {
|
||||||
let mut context = Context::new();
|
let mut context = Context::new();
|
||||||
|
@ -187,8 +162,8 @@ async fn serve_admin<'a>(
|
||||||
|
|
||||||
async fn serve_admin_login(
|
async fn serve_admin_login(
|
||||||
_req: tide::Request<()>,
|
_req: tide::Request<()>,
|
||||||
config: Arc<Config>,
|
config: &Config,
|
||||||
templates: Arc<Templates>,
|
templates: &Templates,
|
||||||
) -> tide::Result<tide::Response> {
|
) -> tide::Result<tide::Response> {
|
||||||
let mut context = Context::new();
|
let mut context = Context::new();
|
||||||
context.insert("config", &config);
|
context.insert("config", &config);
|
||||||
|
@ -201,17 +176,17 @@ async fn serve_admin_login(
|
||||||
|
|
||||||
async fn handle_post_comments(
|
async fn handle_post_comments(
|
||||||
mut req: tide::Request<()>,
|
mut req: tide::Request<()>,
|
||||||
config: Arc<Config>,
|
config: &Config,
|
||||||
templates: Arc<Templates>,
|
templates: &Templates,
|
||||||
dbs: Dbs,
|
dbs: Dbs,
|
||||||
notify_send: Sender<()>,
|
notify_send: Sender<()>,
|
||||||
) -> tide::Result<tide::Response> {
|
) -> tide::Result<tide::Response> {
|
||||||
let admin = req.cookie("admin").map_or(false, |psw| {
|
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 {
|
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)) => {
|
Some(Ok(addr)) => {
|
||||||
if config.antispam_whitelist.contains(&addr) {
|
if config.antispam_whitelist.contains(&addr) {
|
||||||
None
|
None
|
||||||
|
@ -241,11 +216,11 @@ async fn handle_post_comments(
|
||||||
return Err(tide::Error::from_str(404, "No topic"))
|
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(client_addr) = &client_addr {
|
||||||
if let Some(antispam_timeout) =
|
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!(
|
errors.push(format!(
|
||||||
"The edition quota from your IP is reached. You will be unblocked in {}s.",
|
"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"));
|
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) {
|
let comment_id = if let Ok(comment_id) = CommentId::from_base64(&query.id) {
|
||||||
comment_id
|
comment_id
|
||||||
|
@ -310,7 +285,7 @@ async fn handle_post_comments(
|
||||||
|
|
||||||
if let Some(client_addr) = &client_addr {
|
if let Some(client_addr) = &client_addr {
|
||||||
if let Some(antispam_timeout) =
|
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!(
|
errors.push(format!(
|
||||||
"The edition quota from your IP is reached. You will be unblocked in {}s.",
|
"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(
|
async fn handle_post_admin(
|
||||||
mut req: tide::Request<()>,
|
mut req: tide::Request<()>,
|
||||||
config: Arc<Config>,
|
config: &Config,
|
||||||
templates: Arc<Templates>,
|
templates: &Templates,
|
||||||
dbs: Dbs,
|
dbs: Dbs,
|
||||||
) -> tide::Result<tide::Response> {
|
) -> tide::Result<tide::Response> {
|
||||||
if let Some(psw) = req.cookie("admin") {
|
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)]
|
#[allow(clippy::match_single_binding)]
|
||||||
match req.body_form::<AdminQuery>().await? {
|
match req.body_form::<AdminQuery>().await? {
|
||||||
_ => serve_admin(req, config, templates, dbs).await,
|
_ => serve_admin(req, config, templates, dbs).await,
|
||||||
|
@ -375,10 +350,8 @@ async fn handle_post_admin(
|
||||||
serve_admin_login(req, config, templates).await
|
serve_admin_login(req, config, templates).await
|
||||||
}
|
}
|
||||||
} else if let AdminQuery::Login(query) = req.body_form::<AdminQuery>().await? {
|
} else if let AdminQuery::Login(query) = req.body_form::<AdminQuery>().await? {
|
||||||
if let Some(password_hash) = check_admin_password(&config, &query.psw) {
|
if let Some(password_hash) = check_admin_password(config, &query.psw) {
|
||||||
serve_admin(req, config.clone(), templates, dbs)
|
serve_admin(req, config, templates, dbs).await.map(|mut r| {
|
||||||
.await
|
|
||||||
.map(|mut r| {
|
|
||||||
let mut cookie = tide::http::Cookie::new("admin", password_hash);
|
let mut cookie = tide::http::Cookie::new("admin", password_hash);
|
||||||
cookie.set_http_only(Some(true));
|
cookie.set_http_only(Some(true));
|
||||||
cookie.set_path(config.root_url.clone());
|
cookie.set_path(config.root_url.clone());
|
||||||
|
|
Loading…
Reference in a new issue