From 7ae389f3b165a7b4f9b17ef96545f5430cfcd7bc Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 19 Mar 2025 00:22:01 +0100 Subject: delay module --- Cargo.lock | 109 ++++++++++++++++++++++++++++++++++++++---------- Cargo.toml | 1 + src/modules/delay.rs | 47 +++++++++++++++++++++ src/modules/fallback.rs | 1 + src/modules/mod.rs | 4 +- 5 files changed, 140 insertions(+), 22 deletions(-) create mode 100644 src/modules/delay.rs diff --git a/Cargo.lock b/Cargo.lock index 1767171..e848aab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -425,7 +425,7 @@ version = "0.2.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" dependencies = [ - "getrandom", + "getrandom 0.2.15", "hybrid-array", "rand_core 0.6.4", ] @@ -638,10 +638,22 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + [[package]] name = "gimli" version = "0.29.0" @@ -684,7 +696,8 @@ dependencies = [ "percent-encoding", "pin-project", "quinn", - "rand 0.9.0-alpha.2", + "rand 0.9.0", + "rand_distr", "regex", "ring", "rustls", @@ -1137,7 +1150,7 @@ checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -1177,6 +1190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1296,7 +1310,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -1344,7 +1358,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", - "getrandom", + "getrandom 0.2.15", "rand 0.8.5", "ring", "rustc-hash 2.1.1", @@ -1381,6 +1395,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -1394,13 +1414,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0-alpha.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e256ff62cee3e03def855c4d4260106d2bb1696fdc01af03e9935b993720a5" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ - "rand_chacha 0.9.0-alpha.2", - "rand_core 0.9.0-alpha.2", - "zerocopy", + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy 0.8.23", ] [[package]] @@ -1415,12 +1435,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.9.0-alpha.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d299e9db34f6623b2a9e86c015d6e173d5f46d64d4b9b8cc46ae8a982a50b04c" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.0-alpha.2", + "rand_core 0.9.3", ] [[package]] @@ -1429,17 +1449,26 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] name = "rand_core" -version = "0.9.0-alpha.2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "rand_distr" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e93f5a5e3c528cda9acb0928c31b2ba868c551cc46e67b778075e34aab9906" +checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" dependencies = [ - "getrandom", - "zerocopy", + "num-traits", + "rand 0.9.0", ] [[package]] @@ -1488,7 +1517,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -2028,6 +2057,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -2207,6 +2245,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -2214,7 +2261,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +dependencies = [ + "zerocopy-derive 0.8.23", ] [[package]] @@ -2228,6 +2284,17 @@ dependencies = [ "syn", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zeroize" version = "1.8.1" diff --git a/Cargo.toml b/Cargo.toml index 2dad279..aa27597 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,7 @@ aes-gcm-siv = "0.11.1" argon2 = "0.6.0-pre.1" sha2 = "0.11.0-pre.4" rand = "0.9.0-alpha.2" +rand_distr = "0.5.1" # Other helpers and stuff bytes = "1.7.1" diff --git a/src/modules/delay.rs b/src/modules/delay.rs new file mode 100644 index 0000000..ab46a90 --- /dev/null +++ b/src/modules/delay.rs @@ -0,0 +1,47 @@ +use super::{Node, NodeContext, NodeKind, NodeRequest, NodeResponse}; +use crate::{config::DynNode, error::ServiceError}; +use anyhow::Result; +use rand_distr::Distribution; +use serde::Deserialize; +use serde_yml::Value; +use std::{future::Future, pin::Pin, sync::Arc, time::Duration}; +use tokio::time::sleep; + +pub struct DelayKind; + +#[derive(Deserialize)] +struct Delay { + duration: u64, + stdev: u64, + next: DynNode, +} + +impl NodeKind for DelayKind { + fn name(&self) -> &'static str { + "delay" + } + fn instanciate(&self, config: Value) -> Result> { + Ok(Arc::new(serde_yml::from_value::(config)?)) + } +} +impl Node for Delay { + fn handle<'a>( + &'a self, + context: &'a mut NodeContext, + request: NodeRequest, + ) -> Pin> + Send + Sync + 'a>> { + Box::pin(async move { + sleep(Duration::from_millis(if self.stdev == 0 { + self.duration + } else { + self.duration.saturating_add_signed( + rand_distr::Normal::new(0., self.stdev as f32) + .unwrap() + .sample(&mut rand::rng()) as i64, + ) + })) + .await; + self.next.handle(context, request).await + }) + } +} diff --git a/src/modules/fallback.rs b/src/modules/fallback.rs index 6a5caaa..22ae1ef 100644 --- a/src/modules/fallback.rs +++ b/src/modules/fallback.rs @@ -20,6 +20,7 @@ impl NodeKind for FallbackKind { Ok(Arc::new(serde_yml::from_value::(config)?)) } } + impl Node for Fallback { fn handle<'a>( &'a self, diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 283c86a..c9a7708 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -12,6 +12,7 @@ mod auth; mod cache; mod cgi; mod debug; +mod delay; mod error; mod fallback; mod file; @@ -19,13 +20,13 @@ mod files; mod headers; mod hosts; mod inspect; +mod limits; mod loadbalance; mod paths; mod proxy; mod redirect; mod switch; mod upgrade_insecure; -mod limits; pub type NodeRequest = Request>; pub type NodeResponse = Response>; @@ -52,6 +53,7 @@ pub static MODULES: &[&dyn NodeKind] = &[ &inspect::InspectKind, &fallback::FallbackKind, &limits::LimitsKind, + &delay::DelayKind, ]; pub struct NodeContext { -- cgit v1.2.3-70-g09d2