diff --git a/Cargo.lock b/Cargo.lock index 937474f..32a66ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,6 +472,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "bitflags" version = "1.3.2" @@ -617,6 +623,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", +] + [[package]] name = "concurrent-queue" version = "2.4.0" @@ -668,6 +688,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crc16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff" + [[package]] name = "crc32fast" version = "1.4.0" @@ -1469,6 +1495,9 @@ dependencies = [ "env_logger", "num_cpus", "rand", + "redis", + "redis-macros", + "rmp-serde", "serde", "thiserror", "tokio", @@ -1844,6 +1873,57 @@ dependencies = [ "bitflags 2.5.0", ] +[[package]] +name = "redis" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6472825949c09872e8f2c50bde59fcefc17748b6be5c90fd67cd8b4daca73bfd" +dependencies = [ + "async-trait", + "bytes", + "combine", + "crc16", + "futures-util", + "itoa", + "percent-encoding", + "pin-project-lite", + "rand", + "rustls", + "rustls-native-certs", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "ryu", + "sha1_smol", + "socket2", + "tokio", + "tokio-rustls", + "tokio-util", + "url", +] + +[[package]] +name = "redis-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b5407866b6626d251b18c878f043d37f43124680f26a806595a61714ab049a" +dependencies = [ + "redis", + "redis-macros-derive", + "serde", + "serde_json", +] + +[[package]] +name = "redis-macros-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dfe1dc77e38e260bbd53e98d3aec64add3cdf5d773e38d344c63660196117f5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -1907,7 +1987,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -1940,6 +2020,43 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rmp" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1982,6 +2099,33 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -1991,6 +2135,33 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.0", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.15" @@ -2112,6 +2283,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 = "sha2" version = "0.10.8" @@ -2157,6 +2334,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "strfmt" version = "0.2.4" @@ -2175,6 +2358,12 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "1.0.109" @@ -2357,6 +2546,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -2478,6 +2678,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -2887,6 +3093,12 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + [[package]] name = "zstd" version = "0.13.1" diff --git a/Cargo.toml b/Cargo.toml index 4f7a39c..eb2191b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ description = "A compatibility layer between lysands official server and activit [dependencies] tokio = { version = "1.20.0", features = ["rt", "macros"] } -serde = { version = "1.0.130", features = ["derive"] } +serde = { version = "1.0.130", features = ["derive", "rc"] } actix-web = "4" env_logger = "0.11.0" clap = { version = "4.3.14", features = ["derive"] } @@ -26,6 +26,9 @@ activitystreams-kinds = "0.3.0" thiserror = "1.0.58" num_cpus = "1.16.0" actix-web-prom = { version = "0.8.0", features = ["process"] } +redis = { version = "0.25.3", features = ["tokio-comp", "tokio-rustls-comp", "cluster"] } +redis-macros = "0.3.0" +rmp-serde = "1.1.2" [build-dependencies] vcpkg = "0.2.15" diff --git a/src/database.rs b/src/database.rs index 7b6c7fa..0485174 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,11 +1,12 @@ use crate::{error::Error, objects::person::DbUser}; use anyhow::anyhow; +use serde::{Deserialize, Serialize}; use std::sync::{Arc, Mutex}; pub type DatabaseHandle = Arc; /// Our "database" which contains all known users (local and federated) -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct Database { pub users: Mutex>, } diff --git a/src/main.rs b/src/main.rs index d5aa981..f4048ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,8 @@ use clap::Parser; use database::Database; use http::{http_get_user, http_post_user_inbox, webfinger}; use objects::person::DbUser; +use redis::{AsyncCommands, Client, ErrorKind, RedisError, RedisResult}; +use redis_macros::{FromRedisValue, ToRedisArgs}; use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, @@ -13,6 +15,7 @@ use std::{ sync::{Arc, Mutex}, }; use tokio::signal; +use tracing::info; mod activities; mod database; @@ -21,7 +24,8 @@ mod http; mod objects; mod utils; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize, FromRedisValue, ToRedisArgs)] +#[redis_serializer(rmp_serde)] struct State { database: Arc, } @@ -57,6 +61,18 @@ async fn main() -> actix_web::Result<(), anyhow::Error> { env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); let server_url = env::var("LISTEN").unwrap_or("127.0.0.1:8080".to_string()); + let redis_url = env::var("REDIS_URL").unwrap_or("redis://localhost:6379/".to_string()); + + let redis_client = redis::Client::open(redis_url)?; + let mut con = redis_client + .get_multiplexed_async_connection() + .await + .map_err(|_| { + RedisError::from(( + ErrorKind::InvalidClientConfig, + "Cannot connect to redis. Try starting a redis-server process or container.", + )) + })?; let local_user = DbUser::new( env::var("FEDERATED_DOMAIN") @@ -68,11 +84,13 @@ async fn main() -> actix_web::Result<(), anyhow::Error> { ) .unwrap(); - let database = Arc::new(Database { + let new_database = Arc::new(Database { users: Mutex::new(vec![local_user]), }); - let state = State { database }; + let state: State = con.get("ap-layer-db").await.unwrap_or(State { + database: new_database, + }); let data = FederationConfig::builder() .domain(env::var("FEDERATED_DOMAIN").expect("FEDERATED_DOMAIN must be set")) @@ -127,5 +145,8 @@ async fn main() -> actix_web::Result<(), anyhow::Error> { } } + info!("memory-saving 'db' in redis.."); + con.set("ap-layer-db", &state); + Ok(()) } diff --git a/src/objects/person.rs b/src/objects/person.rs index d9439ea..0f03810 100644 --- a/src/objects/person.rs +++ b/src/objects/person.rs @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::Debug; use url::Url; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct DbUser { pub name: String, pub ap_id: ObjectId, diff --git a/src/objects/post.rs b/src/objects/post.rs index e49e78b..7ac453c 100644 --- a/src/objects/post.rs +++ b/src/objects/post.rs @@ -13,7 +13,7 @@ use activitystreams_kinds::link::MentionType; use serde::{Deserialize, Serialize}; use url::Url; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct DbPost { pub text: String, pub ap_id: ObjectId,