diff --git a/.gitignore b/.gitignore index 9e5fabefd..0df4d32e1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ cachegrind.out # Generated by Cargo will have compiled files and executables debug/ target/ +target_vscode/ +config/local.toml # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock index eb917cd13..d88d42642 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,24 +4,24 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -32,78 +32,91 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" + [[package]] name = "anstream" -version = "0.6.12" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "asn1-rs" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -111,31 +124,31 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] [[package]] name = "asn1-rs-derive" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", "synstructure", ] [[package]] name = "asn1-rs-impl" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -146,26 +159,26 @@ checksum = "29faa5d4d308266048bd7505ba55484315a890102f9345b9ff4b87de64201592" dependencies = [ "base64 0.13.1", "httparse", - "thiserror", + "thiserror 1.0.69", "tokio", ] [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] name = "async-tungstenite" -version = "0.25.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef0f8d64ef9351752fbe5462f242c625d9c4910d2bc3f7ec44c43857ca123f5d" +checksum = "90e661b6cb0a6eb34d02c520b052daa3aa9ac0cc02495c9d066bbce13ead132b" dependencies = [ "futures-io", "futures-util", @@ -184,43 +197,65 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ - "futures 0.3.30", + "futures 0.3.31", "pharos", "rustc_version", "tokio", ] [[package]] -name = "atty" -version = "0.2.14" +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "aws-lc-rs" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "fe7c2840b66236045acd2607d5866e274380afd87ef99d6226e961e2cb47df45" dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", + "aws-lc-sys", + "mirai-annotations", + "paste", + "zeroize", ] [[package]] -name = "autocfg" -version = "1.1.0" +name = "aws-lc-sys" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ad3a619a9de81e1d7de1f1186dcba4506ed661a0e483d84410fdef0ee87b2f96" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] [[package]] name = "axum" -version = "0.7.4" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", "bytes", "futures-util", - "http 1.0.0", - "http-body 1.0.0", + "http", + "http-body", "http-body-util", - "hyper 1.2.0", + "hyper", "hyper-util", "itoa", "matchit", @@ -233,7 +268,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.2", "tokio", "tower", "tower-layer", @@ -243,20 +278,20 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.0.0", - "http-body 1.0.0", + "http", + "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", @@ -264,17 +299,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -289,12 +324,18 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "benchmarks" version = "0.4.0" dependencies = [ "bytes", - "futures 0.3.30", + "futures 0.3.31", "itoa", "pprof", "pretty_env_logger", @@ -314,6 +355,29 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -322,9 +386,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -340,15 +404,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.3" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.3" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -358,18 +422,32 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.0.88" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] [[package]] name = "cfg-if" @@ -377,11 +455,22 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" -version = "4.5.1" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -389,9 +478,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -401,49 +490,56 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" + +[[package]] +name = "cmake" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +dependencies = [ + "cc", +] [[package]] name = "color-backtrace" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6c04463c99389fff045d2b90ce84f5131332712c7ffbede020f5e9ad1ed685" +checksum = "150fd80a270c0671379f388c8204deb6a746bb4eac8a6c03fe2460b2c0127ea0" dependencies = [ - "atty", "backtrace", "termcolor", ] [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "config" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be" +checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" dependencies = [ "async-trait", "convert_case", "json5", - "lazy_static", "nom", "pathdiff", "ron", @@ -451,14 +547,14 @@ dependencies = [ "serde", "serde_json", "toml", - "yaml-rust", + "yaml-rust2", ] [[package]] name = "const-random" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaf16c9c2c612020bcfd042e170f6e32de9b9d75adb5277cdbbd2e2c8c8299a" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" dependencies = [ "const-random-macro", ] @@ -495,24 +591,24 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpp_demangle" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" dependencies = [ "cfg-if", ] [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -528,9 +624,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -550,9 +646,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "debugid" @@ -565,9 +661,9 @@ dependencies = [ [[package]] name = "der-parser" -version = "8.2.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" dependencies = [ "asn1-rs", "displaydoc", @@ -604,13 +700,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] @@ -622,11 +718,36 @@ dependencies = [ "const-random", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_filter" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] [[package]] name = "env_logger" @@ -641,6 +762,19 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -649,9 +783,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -659,9 +793,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "findshlibs" @@ -689,9 +823,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flume" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", @@ -704,6 +838,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -728,6 +868,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures" version = "0.1.31" @@ -736,9 +882,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -751,9 +897,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -761,15 +907,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -778,38 +924,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures 0.1.31", "futures-channel", @@ -836,9 +982,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -847,22 +993,28 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", - "http 1.0.0", + "http", "indexmap", "slab", "tokio", @@ -872,39 +1024,49 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.13.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" dependencies = [ - "ahash", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", ] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hermit-abi" -version = "0.3.8" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "home" @@ -917,20 +1079,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -939,43 +1090,32 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.11", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.0.0", + "http", ] [[package]] name = "http-body-util" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.0.0", - "http-body 1.0.0", + "http", + "http-body", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -991,88 +1131,231 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", - "http 0.2.11", - "http-body 0.4.6", + "h2", + "http", + "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] -name = "hyper" -version = "1.2.0" +name = "hyper-rustls" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ - "bytes", - "futures-channel", "futures-util", - "h2", - "http 1.0.0", - "http-body 1.0.0", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "smallvec", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", "tokio", + "tokio-native-tls", + "tower-service", ] [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", + "futures-channel", "futures-util", - "http 1.0.0", - "http-body 1.0.0", - "hyper 1.2.0", + "http", + "http-body", + "hyper", "pin-project-lite", "socket2", "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] name = "indexmap" -version = "2.2.3" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.15.1", ] [[package]] name = "inferno" -version = "0.11.19" +version = "0.11.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321f0f839cd44a4686e9504b0a62b4d69a50b62072144c71c68f5873c167b8d9" +checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88" dependencies = [ "ahash", "indexmap", @@ -1088,41 +1371,56 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi 0.3.8", + "hermit-abi 0.4.0", "libc", "windows-sys 0.52.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1140,33 +1438,49 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] -name = "linked-hash-map" -version = "0.5.6" +name = "libloading" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1174,9 +1488,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "matchers" @@ -1201,24 +1515,24 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] [[package]] name = "metrics" -version = "0.22.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd71d9db2e4287c3407fa04378b8c2ee570aebe0854431562cdd89ca091854f4" +checksum = "8ae428771d17306715c5091d446327d1cfdedc82185c65ba8423ab404e45bf10" dependencies = [ "ahash", "portable-atomic", @@ -1226,32 +1540,34 @@ dependencies = [ [[package]] name = "metrics-exporter-prometheus" -version = "0.13.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf4e7146e30ad172c42c39b3246864bd2d3c6396780711a1baf749cfe423e21" +checksum = "85b6f8152da6d7892ff1b7a1c0fa3f435e92b5918ad67035c3bb432111d9a29b" dependencies = [ - "base64 0.21.7", - "hyper 0.14.28", + "base64 0.22.1", + "http-body-util", + "hyper", + "hyper-util", "indexmap", "ipnet", "metrics", "metrics-util", "quanta", - "thiserror", + "thiserror 1.0.69", "tokio", + "tracing", ] [[package]] name = "metrics-util" -version = "0.16.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece71ab046dcf45604e573329966ec1db5ff4b81cfa170a924ff4c959ab5451a" +checksum = "15b482df36c13dd1869d73d14d28cd4855fbd6cfc32294bee109908a9f4a4ed7" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.14.3", + "hashbrown 0.15.1", "metrics", - "num_cpus", "quanta", "sketches-ddsketch", ] @@ -1270,37 +1586,43 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] +[[package]] +name = "mirai-annotations" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" + [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1345,11 +1667,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1381,54 +1702,44 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.8", - "libc", -] - [[package]] name = "object" -version = "0.32.2" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "oid-registry" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" dependencies = [ "asn1-rs", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -1445,7 +1756,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] @@ -1456,9 +1767,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -1468,12 +1779,12 @@ dependencies = [ [[package]] name = "ordered-multimap" -version = "0.6.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" dependencies = [ "dlv-list", - "hashbrown 0.13.2", + "hashbrown 0.14.5", ] [[package]] @@ -1484,9 +1795,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1494,22 +1805,28 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" [[package]] name = "percent-encoding" @@ -1519,20 +1836,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.7" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.7" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -1540,22 +1857,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.7" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] name = "pest_meta" -version = "2.7.7" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -1564,9 +1881,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", "indexmap", @@ -1578,35 +1895,15 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ - "futures 0.3.30", + "futures 0.3.31", "rustc_version", ] -[[package]] -name = "pin-project" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.51", -] - [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -1616,15 +1913,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "powerfmt" @@ -1654,20 +1951,23 @@ dependencies = [ "smallvec", "symbolic-demangle", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -1679,34 +1979,34 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" dependencies = [ - "env_logger", + "env_logger 0.10.2", "log", ] [[package]] name = "prettyplease" -version = "0.2.16" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.51", + "syn", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", "prost-derive", @@ -1714,9 +2014,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", "heck", @@ -1729,38 +2029,37 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.51", + "syn", "tempfile", - "which", ] [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] name = "prost-types" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ "prost", ] [[package]] name = "quanta" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca0b7bac0b97248c40bb77288fc52029cf1459c0461ea1b05ee32ccf011de2c" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" dependencies = [ "crossbeam-utils", "libc", @@ -1782,9 +2081,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1821,32 +2120,32 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.0.1" +version = "11.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] @@ -1860,32 +2159,76 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.12.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - [[package]] name = "rgb" -version = "0.8.37" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" dependencies = [ "bytemuck", ] @@ -1912,7 +2255,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.4.2", + "bitflags 2.6.0", "serde", "serde_derive", ] @@ -1926,10 +2269,11 @@ dependencies = [ "bincode", "bytes", "color-backtrace", + "config", "fixedbitset 0.5.7", "flume", "futures-util", - "http 1.0.0", + "http", "log", "matches", "native-tls", @@ -1939,13 +2283,15 @@ dependencies = [ "rustls-pemfile", "rustls-webpki", "serde", - "thiserror", + "serde_json", + "thiserror 2.0.3", "tokio", "tokio-native-tls", "tokio-rustls", "tokio-stream", "tokio-util", "url", + "uuid", "ws_stream_tungstenite", ] @@ -1958,21 +2304,26 @@ dependencies = [ "bytes", "clap", "config", + "env_logger 0.11.5", "flume", "futures-util", + "lazy_static", + "log", "metrics", "metrics-exporter-prometheus", "parking_lot", "pretty_assertions", "pretty_env_logger", "rand", + "regex", + "reqwest", "rustls-pemfile", "rustls-webpki", "serde", "serde_json", "slab", "subtle", - "thiserror", + "thiserror 2.0.3", "tokio", "tokio-native-tls", "tokio-rustls", @@ -1986,9 +2337,9 @@ dependencies = [ [[package]] name = "rust-ini" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" +checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" dependencies = [ "cfg-if", "ordered-multimap", @@ -1996,15 +2347,21 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -2020,11 +2377,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -2033,12 +2390,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.4" +version = "0.23.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" dependencies = [ + "aws-lc-rs", "log", - "ring", + "once_cell", "rustls-pki-types", "rustls-webpki", "subtle", @@ -2047,9 +2405,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -2060,26 +2418,26 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c333bb734fcdedcea57de1602543590f545f127dc8b533324318fd492c5c70b" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.21.7", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -2087,23 +2445,23 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2114,11 +2472,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -2127,9 +2485,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -2137,46 +2495,47 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_path_to_error" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", @@ -2184,9 +2543,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -2234,11 +2593,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -2250,15 +2615,15 @@ dependencies = [ "bytes", "log", "pretty_env_logger", - "thiserror", + "thiserror 1.0.69", "tokio", ] [[package]] name = "sketches-ddsketch" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" +checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "slab" @@ -2271,15 +2636,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2308,21 +2673,21 @@ checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.8.0" +version = "12.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cccfffbc6bb3bb2d3a26cd2077f4d055f6808d266f9d4d158797a4c60510dfe" +checksum = "3d4d73159efebfb389d819fd479afb2dbd57dcb3e3f4b7fcfa0e675f5a46c1cb" dependencies = [ "debugid", "memmap2", @@ -2332,9 +2697,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.8.0" +version = "12.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a99812da4020a67e76c4eb41f08c87364c14170495ff780f30dd519c221a68" +checksum = "a767859f6549c665011970874c3f541838b4835d5aaaa493d3ee383918be9f10" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -2343,9 +2708,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.109" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -2353,44 +2718,63 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.51" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" -version = "0.12.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", - "unicode-xid", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] name = "tempfile" -version = "3.10.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2404,22 +2788,42 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] @@ -2473,48 +2877,42 @@ dependencies = [ ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.36.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] @@ -2529,9 +2927,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls", "rustls-pki-types", @@ -2540,9 +2938,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -2551,23 +2949,22 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.10" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -2577,18 +2974,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.6" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -2599,14 +2996,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.4.13" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" dependencies = [ "futures-core", "futures-util", - "pin-project", "pin-project-lite", + "sync_wrapper 0.1.2", "tokio", "tower-layer", "tower-service", @@ -2615,15 +3012,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -2645,7 +3042,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", ] [[package]] @@ -2695,22 +3092,21 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.21.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.0.0", + "http", "httparse", "log", "rand", "rustls", "rustls-pki-types", "sha1", - "thiserror", - "url", + "thiserror 1.0.69", "utf-8", ] @@ -2722,42 +3118,21 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode-xid" -version = "0.2.4" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "untrusted" @@ -2767,9 +3142,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", "idna", @@ -2782,17 +3157,29 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.7.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ "getrandom", "rand", @@ -2812,9 +3199,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "want" @@ -2833,34 +3220,47 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.51", + "syn", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2868,28 +3268,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -2925,11 +3325,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -2939,155 +3339,147 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "windows-targets 0.48.5", + "windows-result", + "windows-strings", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.52.3", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-result", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.52.3" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows_aarch64_gnullvm 0.52.3", - "windows_aarch64_msvc 0.52.3", - "windows_i686_gnu 0.52.3", - "windows_i686_msvc 0.52.3", - "windows_x86_64_gnu 0.52.3", - "windows_x86_64_gnullvm 0.52.3", - "windows_x86_64_msvc 0.52.3", + "windows-targets", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.3" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] [[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.3" +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" +name = "winnow" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] [[package]] -name = "windows_x86_64_msvc" -version = "0.52.3" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] -name = "winnow" -version = "0.6.2" +name = "writeable" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4191c47f15cc3ec71fcb4913cb83d58def65dd3787610213c649283b5ce178" -dependencies = [ - "memchr", -] +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "ws_stream_tungstenite" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a198f414f083fb19fcc1bffcb0fa0cf46d33ccfa229adf248cac12c180e91609" +checksum = "ed39ff9f8b2eda91bf6390f9f49eee93d655489e15708e3bb638c1c4f07cecb4" dependencies = [ "async-tungstenite", "async_io_stream", - "bitflags 2.4.2", + "bitflags 2.6.0", "futures-core", "futures-io", "futures-sink", @@ -3101,9 +3493,9 @@ dependencies = [ [[package]] name = "x509-parser" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ "asn1-rs", "data-encoding", @@ -3112,47 +3504,117 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] [[package]] -name = "yaml-rust" -version = "0.4.5" +name = "yaml-rust2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8" dependencies = [ - "linked-hash-map", + "arraydeque", + "encoding_rs", + "hashlink", ] [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn", + "synstructure", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..6ce7743d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +SHELL=/bin/bash +CARGO_HOME=${HOME}/cargo_homes/ubidots_rumqtt/ + + +.PHONY: help build push all + +help: + @echo "Makefile commands:" + @echo "test" + @echo "check" + @echo "all" + +.DEFAULT_GOAL := all + +test: + CARGO_HOME=${CARGO_HOME} cargo test -- --nocapture + +fmt: + CARGO_HOME=${CARGO_HOME} cargo fmt + +clippy: + CARGO_HOME=${CARGO_HOME} cargo clippy + +update: + CARGO_HOME=${CARGO_HOME} cargo update + +check: + CARGO_HOME=${CARGO_HOME} cargo check --all-targets --profile=test --workspace --all-features + +check_release: + CARGO_HOME=${CARGO_HOME} cargo check --all-targets --release --workspace --all-features + +validate_code: fmt check clippy test + +fetch: + CARGO_HOME=${CARGO_HOME} cargo fetch + +build_release: + CARGO_HOME=${CARGO_HOME} cargo build --release diff --git a/config/default.toml b/config/default.toml new file mode 100644 index 000000000..29e69d3a8 --- /dev/null +++ b/config/default.toml @@ -0,0 +1,148 @@ +id = 0 + +# A commitlog read will pull full segment. Make sure that a segment isn't +# too big as async tcp writes readiness of one connection might affect tail +# latencies of other connection. Not a problem with preempting runtimes +[router] +id = 0 +max_connections = 10010 +max_outgoing_packet_count = 200 +max_segment_size = 104857600 +max_segment_count = 10 +# shared_subscriptions_strategy = "random" # "sticky" | "roundrobin" ( default ) | "random" +# Any filters that match to configured filter will have custom segment size. + # [router.custom_segment.'/office/+/devices/status'] + # max_segment_size = 102400 + # max_segment_count = 2 + # [router.custom_segment.'/home/+/devices/status'] + # max_segment_size = 51200 + # max_segment_count = 2 + +# [bridge] +# name = "bridge-1" +# addr = "localhost:1883" +# qos = 0 +# sub_path = "#" +# reconnection_delay = 5 +# ping_delay = 5 +# timeout_delay = 5 +# [bridge.connections] +# connection_timeout_ms = 60000 +# max_payload_size = 20480 +# max_inflight_count = 500 +# dynamic_filters = true +# [bridge.transport.tls] +# ca = "ca.cert.pem" +# client_auth = { certs = "test-1.cert.pem", key = "test-1.key.pem" } + +# Configuration of server and connections that it accepts +[v4.1] +name = "v4-1" +listen = "0.0.0.0:1883" +next_connection_delay_ms = 1 + [v4.1.connections] + connection_timeout_ms = 60000 + max_payload_size = 20480 + max_inflight_count = 100 + dynamic_filters = true + # auth = { user1 = "p@ssw0rd", user2 = "password" } + # [v4.1.connections.auth] + # user1 = "p@ssw0rd" + # user2 = "password" + +# [v4.2] +# name = "v4-2" +# listen = "0.0.0.0:8883" +# next_connection_delay_ms = 10 +# # tls config for rustls +# [v4.2.tls] +# capath = "/etc/tls/ca.cert.pem" +# certpath = "/etc/tls/server.cert.pem" +# keypath = "/etc/tls/server.key.pem" +# # settings for all the connections on this server +# [v4.2.connections] +# connection_timeout_ms = 60000 +# throttle_delay_ms = 0 +# max_payload_size = 20480 +# max_inflight_count = 100 +# max_inflight_size = 1024 + +[v5.1] +name = "v5-1" +listen = "0.0.0.0:1884" +next_connection_delay_ms = 1 + [v5.1.connections] + connection_timeout_ms = 60000 + max_payload_size = 20480 + max_inflight_count = 100 + +[prometheus] +listen = "127.0.0.1:9044" +interval = 1 + +[ws.1] +name = "ws-1" +listen = "0.0.0.0:8083" +next_connection_delay_ms = 1 + [ws.1.connections] + connection_timeout_ms = 60000 + max_client_id_len = 256 + throttle_delay_ms = 0 + max_payload_size = 20480 + max_inflight_count = 500 + max_inflight_size = 1024 + +# [ws.2] +# name = "ws-2" +# listen = "0.0.0.0:8081" +# next_connection_delay_ms = 1 +# [ws.2.tls] +# capath = "/etc/tls/ca.cert.pem" +# certpath = "/etc/tls/server.cert.pem" +# keypath = "/etc/tls/server.key.pem" +# [ws.2.connections] +# connection_timeout_ms = 60000 +# max_client_id_len = 256 +# throttle_delay_ms = 0 +# max_payload_size = 20480 +# max_inflight_count = 500 +# max_inflight_size = 1024 + +[console] +listen = "0.0.0.0:3030" + +# [metrics] +# [metrics.alerts] +# push_interval = 1 +# [metrics.meters] +# push_interval = 1 + +[webhook] +authentication_protocol = "http" +authentication_host = "localhost" +authentication_port = "8000" +authentication_endpoint = "/authentication" +authorization_protocol = "http" +authorization_host = "localhost" +authorization_port = "8000" +authorization_endpoint = "/authorization" +webhook_protocol = "http" +webhook_host = "localhost" +webhook_port = "8000" +webhook_endpoint = "/webhook" +retained_protocol = "http" +retained_host = "localhost" +retained_port = "8000" +retained_endpoint = "/retained" +metrics_protocol = "http" +metrics_host = "localhost" +metrics_port = "8000" +metrics_endpoint = "/metrics" + +[health_check] +health_check_username = "health_check_username" +health_check_password = "health_check_password" +health_check_client_id = "health_check_client_id" +health_check_topic = "health/check" +health_check_port = 1885 +health_check_host = "localhost" \ No newline at end of file diff --git a/rumqttc/Cargo.toml b/rumqttc/Cargo.toml index 2e2bae14e..3efb81c90 100644 --- a/rumqttc/Cargo.toml +++ b/rumqttc/Cargo.toml @@ -23,41 +23,45 @@ websocket = ["dep:async-tungstenite", "dep:ws_stream_tungstenite", "dep:http"] proxy = ["dep:async-http-proxy"] [dependencies] -futures-util = { version = "0.3", default-features = false, features = ["std", "sink"] } -tokio = { version = "1.36", features = ["rt", "macros", "io-util", "net", "time"] } -tokio-util = { version = "0.7", features = ["codec"] } -bytes = "1.5" -log = "0.4" -flume = { version = "0.11", default-features = false, features = ["async"] } -thiserror = "1" +futures-util = { version = "^0.3.31", default-features = false, features = ["std", "sink"] } +tokio = { version = "^1.41.1", features = ["rt", "macros", "io-util", "net", "time"] } +tokio-util = { version = "^0.7.12", features = ["codec"] } +bytes = "^1.8.0" +log = "^0.4.22" +flume = { version = "^0.11.1", default-features = false, features = ["async"] } +thiserror = "^2.0.3" +config = "^0.14.1" +serde = { version = "^1.0.215", features = ["derive"] } +serde_json = "^1.0.133" +uuid = {version = "^1.11.0", features = ["v4", "fast-rng"]} # Optional # rustls -tokio-rustls = { version = "0.25.0", optional = true } -rustls-webpki = { version = "0.102.2", optional = true } -rustls-pemfile = { version = "2.1.0", optional = true } -rustls-native-certs = { version = "0.7.0", optional = true } +tokio-rustls = { version = "^0.26.0", optional = true } +rustls-webpki = { version = "^0.102.8", optional = true } +rustls-pemfile = { version = "^2.2.0", optional = true } +rustls-native-certs = { version = "^0.8.0", optional = true } # websockets -async-tungstenite = { version = "0.25.0", default-features = false, features = ["tokio-rustls-native-certs"], optional = true } -ws_stream_tungstenite = { version= "0.13.0", default-features = false, features = ["tokio_io"], optional = true } -http = { version = "1.0.0", optional = true } +async-tungstenite = { version = "^0.28.0", default-features = false, features = ["tokio-rustls-native-certs"], optional = true } +ws_stream_tungstenite = { version= "^0.14.0", default-features = false, features = ["tokio_io"], optional = true } +http = { version = "^1.1.0", optional = true } # native-tls -tokio-native-tls = { version = "0.3.1", optional = true } -native-tls = { version = "0.2.11", optional = true } +tokio-native-tls = { version = "^0.3.1", optional = true } +native-tls = { version = "^0.2.12", optional = true } # url -url = { version = "2", default-features = false, optional = true } +url = { version = "^2.5.3", default-features = false, optional = true } # proxy -async-http-proxy = { version = "1.2.5", features = ["runtime-tokio", "basic-auth"], optional = true } -tokio-stream = "0.1.15" -fixedbitset = "0.5.7" +async-http-proxy = { version = "^1.2.5", features = ["runtime-tokio", "basic-auth"], optional = true } +tokio-stream = "^0.1.16" +fixedbitset = "^0.5.7" [dev-dependencies] -bincode = "1.3.3" -color-backtrace = "0.5" -matches = "0.1" -pretty_assertions = "1" -pretty_env_logger = "0.5" -serde = { version = "1", features = ["derive"] } +bincode = "^1.3.3" +color-backtrace = "^0.6.1" +matches = "^0.1.10" +pretty_assertions = "^1.4.1" +pretty_env_logger = "^0.5" +serde = { version = "^1.0.215", features = ["derive"] } [[example]] name = "tls" @@ -83,3 +87,7 @@ required-features = ["websocket"] name = "websocket_proxy" path = "examples/websocket_proxy.rs" required-features = ["websocket", "proxy"] + +[[bin]] +name = "health_check" +path = "health_check.rs" diff --git a/rumqttc/health_check.rs b/rumqttc/health_check.rs new file mode 100644 index 000000000..758ad35e2 --- /dev/null +++ b/rumqttc/health_check.rs @@ -0,0 +1,106 @@ +use bytes::Bytes; +use rumqttc::settings::get_settings; +use rumqttc::{ + AsyncClient, ConnAck, ConnectReturnCode, Event, MqttOptions, Outgoing, Packet, QoS, SubAck, + SubscribeReasonCode, +}; +use std::error::Error; +use std::time::Duration; +use tokio::task; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<(), Box> { + let config = get_settings(); + let mut mqtt_options = MqttOptions::new( + config.health_check.health_check_client_id.to_string(), + config.health_check.health_check_host.to_string(), + config.health_check.health_check_port, + ); + mqtt_options.set_keep_alive(Duration::from_secs(5)); + mqtt_options.set_credentials( + config.health_check.health_check_username.to_string(), + config.health_check.health_check_password.to_string(), + ); + + let publish_count = 10; + let events_count = publish_count * 2 + 3; + let expected_topic = config.health_check.health_check_topic.to_owned(); + let topic = config.health_check.health_check_topic.to_owned(); + + let (client, mut event_loop) = AsyncClient::new(mqtt_options, 10); + task::spawn(async move { + requests(client, publish_count, &topic).await; + }); + let mut publish_ids = vec![]; + let mut subscribe_ids = vec![]; + let mut payloads = vec![]; + let mut topics = vec![]; + for _ in 0..events_count { + let event = event_loop.poll().await; + match &event { + Ok(event) => { + match event { + Event::Incoming(incoming) => { + if let Packet::ConnAck(conn_ack) = incoming { + assert!( + conn_ack + == &ConnAck { + session_present: false, + code: ConnectReturnCode::Success + } + ); + } + if let Packet::SubAck(sub_ack) = incoming { + assert_eq!( + sub_ack, + &SubAck { + pkid: 1, + return_codes: vec![SubscribeReasonCode::Success( + QoS::AtMostOnce + )], + } + ); + } + if let Packet::Publish(publish) = incoming { + payloads.push(publish.payload.clone()); + topics.push(publish.topic.clone()); + } + } + Event::Outgoing(outgoing) => { + if let Outgoing::Subscribe(subscribe) = outgoing { + subscribe_ids.push(*subscribe); + } + if let Outgoing::Publish(publish) = outgoing { + publish_ids.push(*publish); + } + } + }; + } + Err(error) => { + panic!("Error connecting to server. {:?}", error); + } + } + } + assert_eq!(publish_ids.len(), publish_count); + assert_eq!(subscribe_ids.len(), 1); + let mut expected_payload: Vec = vec![]; + let mut expected_topics = vec![]; + for i in 0..publish_count { + expected_payload.push(Bytes::from(vec![1; i])); + expected_topics.push(expected_topic.to_owned()); + } + assert_eq!(payloads, expected_payload); + assert_eq!(topics, expected_topics); + Ok(()) +} + +async fn requests(client: AsyncClient, publish_count: usize, topic: &str) { + client.subscribe(topic, QoS::AtMostOnce).await.unwrap(); + + for i in 0..publish_count { + client + .publish(topic, QoS::AtMostOnce, false, vec![1; i]) + .await + .unwrap(); + } +} diff --git a/rumqttc/src/lib.rs b/rumqttc/src/lib.rs index 07694ffaf..83d5d0614 100644 --- a/rumqttc/src/lib.rs +++ b/rumqttc/src/lib.rs @@ -109,6 +109,7 @@ mod client; mod eventloop; mod framed; pub mod mqttbytes; +pub mod settings; mod state; pub mod v5; diff --git a/rumqttc/src/settings.rs b/rumqttc/src/settings.rs new file mode 100644 index 000000000..273b49bc6 --- /dev/null +++ b/rumqttc/src/settings.rs @@ -0,0 +1,39 @@ +use std::path::Path; + +use config::{builder::DefaultState, ConfigBuilder, Environment, File}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct HealthCheckSettings { + pub health_check_username: String, + pub health_check_password: String, + pub health_check_client_id: String, + pub health_check_topic: String, + pub health_check_port: u16, + pub health_check_host: String, +} + +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct Config { + pub health_check: HealthCheckSettings, +} + +fn update_settings( + builder: ConfigBuilder, + file_path: &str, +) -> ConfigBuilder { + if Path::new(file_path).exists() { + return builder.add_source(File::with_name(file_path)); + } + builder +} + +pub fn get_settings() -> Config { + let mut config_builder = config::Config::builder(); + config_builder = + config_builder.add_source(Environment::with_prefix("DYNACONF").separator("__")); + config_builder = update_settings(config_builder, "config/default.toml"); + config_builder = update_settings(config_builder, "config/local.toml"); + let result: Config = config_builder.build().unwrap().try_deserialize().unwrap(); + result +} diff --git a/rumqttc/src/v5/state.rs b/rumqttc/src/v5/state.rs index 0f08a33b8..9a7485f3b 100644 --- a/rumqttc/src/v5/state.rs +++ b/rumqttc/src/v5/state.rs @@ -242,7 +242,7 @@ impl MqttState { } _ => { warn!("SubAck Pkid = {:?}, Reason = {:?}", suback.pkid, reason); - }, + } } } Ok(None) @@ -364,7 +364,10 @@ impl MqttState { if puback.reason != PubAckReason::Success && puback.reason != PubAckReason::NoMatchingSubscribers { - warn!("PubAck Pkid = {:?}, reason: {:?}", puback.pkid, puback.reason); + warn!( + "PubAck Pkid = {:?}, reason: {:?}", + puback.pkid, puback.reason + ); return Ok(None); } @@ -397,7 +400,10 @@ impl MqttState { if pubrec.reason != PubRecReason::Success && pubrec.reason != PubRecReason::NoMatchingSubscribers { - warn!("PubRec Pkid = {:?}, reason: {:?}", pubrec.pkid, pubrec.reason); + warn!( + "PubRec Pkid = {:?}, reason: {:?}", + pubrec.pkid, pubrec.reason + ); return Ok(None); } @@ -417,7 +423,10 @@ impl MqttState { self.incoming_pub.set(pubrel.pkid as usize, false); if pubrel.reason != PubRelReason::Success { - warn!("PubRel Pkid = {:?}, reason: {:?}", pubrel.pkid, pubrel.reason); + warn!( + "PubRel Pkid = {:?}, reason: {:?}", + pubrel.pkid, pubrel.reason + ); return Ok(None); } @@ -444,7 +453,10 @@ impl MqttState { self.outgoing_rel.set(pubcomp.pkid as usize, false); if pubcomp.reason != PubCompReason::Success { - warn!("PubComp Pkid = {:?}, reason: {:?}", pubcomp.pkid, pubcomp.reason); + warn!( + "PubComp Pkid = {:?}, reason: {:?}", + pubcomp.pkid, pubcomp.reason + ); return Ok(None); } diff --git a/rumqttd/Cargo.toml b/rumqttd/Cargo.toml index 8d1fd604b..63429ddab 100644 --- a/rumqttd/Cargo.toml +++ b/rumqttd/Cargo.toml @@ -12,33 +12,38 @@ license.workspace = true authors.workspace = true [dependencies] -tokio = { version = "1.36", features = ["rt", "time", "net", "io-util", "macros"]} -serde = { version = "1.0.196", features = ["derive"] } -serde_json = "1.0.113" -bytes = { version = "1", features = ["serde"] } -flume = { version = "0.11.0", default-features = false, features = ["async"]} -slab = "0.4.9" -thiserror = "1.0.57" -tokio-util = { version = "0.7", features = ["codec"], optional = true } -tokio-rustls = { version = "0.25.0", optional = true } -rustls-webpki = { version = "0.102.2", optional = true } -tokio-native-tls = { version = "0.3.1", optional = true } -rustls-pemfile = { version = "2.1.0", optional = true } -async-tungstenite = { version = "0.25", default-features = false, features = ["tokio-runtime"], optional = true } -ws_stream_tungstenite = { version= "0.13", default-features = false, features = ["tokio_io"], optional = true } -x509-parser = {version= "0.15.1", optional = true} -futures-util = { version = "0.3.30", optional = true} -parking_lot = "0.12.1" -config = "0.14" -tracing = { version="0.1", features=["log"] } -tracing-subscriber = { version="0.3.18", features=["env-filter"] } -metrics = "0.22.1" -metrics-exporter-prometheus = { version = "0.13.1", default-features = false, features = ["http-listener"] } -clap = { version = "4.4", features = ["derive"] } -axum = "0.7.4" -rand = "0.8.5" -uuid = { version = "1.7.0", features = ["v4", "fast-rng"] } -subtle = "2.5" +tokio = { version = "^1.41.1", features = ["rt", "time", "net", "io-util", "macros"]} +serde = { version = "^1.0.215", features = ["derive"] } +serde_json = "^1.0.133" +bytes = { version = "^1.8.0", features = ["serde"] } +flume = { version = "^0.11.1", default-features = false, features = ["async"]} +slab = "^0.4.9" +thiserror = "^2.0.3" +tokio-util = { version = "^0.7.12", features = ["codec"], optional = true } +tokio-rustls = { version = "^0.26.0", optional = true } +rustls-webpki = { version = "^0.102.8", optional = true } +tokio-native-tls = { version = "^0.3.1", optional = true } +rustls-pemfile = { version = "^2.2.0", optional = true } +async-tungstenite = { version = "^0.28.0", default-features = false, features = ["tokio-runtime"], optional = true } +ws_stream_tungstenite = { version= "^0.14.0", default-features = false, features = ["tokio_io"], optional = true } +x509-parser = {version= "^0.16.0", optional = true} +futures-util = { version = "^0.3.31", optional = true} +parking_lot = "^0.12.3" +config = "^0.14.1" +tracing = { version="^0.1.40", features=["log"] } +tracing-subscriber = { version="^0.3.18", features=["env-filter"] } +metrics = "^0.24.0" +metrics-exporter-prometheus = { version = "^0.16.0", default-features = false, features = ["http-listener"] } +clap = { version = "^4.5.21", features = ["derive"] } +axum = "^0.7.9" +rand = "^0.8.5" +uuid = { version = "^1.11.0", features = ["v4", "fast-rng"] } +subtle = "^2.6.1" +regex = "^1.1.1" +reqwest = { version = "^0.12.9", features = ["json", "blocking"] } +log = "^0.4.22" +env_logger = "^0.11.5" +lazy_static = "^1.5.0" [features] default = ["use-rustls", "websocket"] @@ -51,5 +56,9 @@ allow-duplicate-clientid = [] [dev-dependencies] pretty_env_logger = "0.5.0" -config = "0.14" -pretty_assertions = "1.4.0" +config = "0.14.1" +pretty_assertions = "1.4.1" + +[[bin]] +name = "show_settings" +path = "show_settings.rs" diff --git a/rumqttd/rumqttd.toml b/rumqttd/rumqttd.toml index ecc741e06..cc1ccfb50 100644 --- a/rumqttd/rumqttd.toml +++ b/rumqttd/rumqttd.toml @@ -38,7 +38,7 @@ max_segment_count = 10 # Configuration of server and connections that it accepts [v4.1] name = "v4-1" -listen = "0.0.0.0:1883" +listen = "0.0.0.0:1885" next_connection_delay_ms = 1 [v4.1.connections] connection_timeout_ms = 60000 @@ -77,7 +77,7 @@ next_connection_delay_ms = 1 max_inflight_count = 100 [prometheus] -listen = "127.0.0.1:9042" +listen = "127.0.0.1:9044" interval = 1 [ws.1] @@ -116,3 +116,21 @@ listen = "0.0.0.0:3030" # push_interval = 1 # [metrics.meters] # push_interval = 1 + +[webhook] +authentication_protocol = "http" +authentication_host = "localhost" +authentication_port = "8000" +authentication_endpoint = "/authentication" +authorization_protocol = "http" +authorization_host = "localhost" +authorization_port = "8000" +authorization_endpoint = "/authorization" +webhook_protocol = "http" +webhook_host = "localhost" +webhook_port = "8000" +webhook_endpoint = "/webhook" +retained_protocol = "http" +retained_host = "localhost" +retained_port = "8000" +retained_endpoint = "/retained" diff --git a/rumqttd/show_settings.rs b/rumqttd/show_settings.rs new file mode 100644 index 000000000..082a97e92 --- /dev/null +++ b/rumqttd/show_settings.rs @@ -0,0 +1,6 @@ +use rumqttd::requests::utils_settings; + +fn main() { + let settings = utils_settings::get_settings(); + println!("{settings:#?}"); +} diff --git a/rumqttd/src/lib.rs b/rumqttd/src/lib.rs index 405a1a243..21f89a578 100644 --- a/rumqttd/src/lib.rs +++ b/rumqttd/src/lib.rs @@ -6,6 +6,9 @@ use std::pin::Pin; use std::sync::Arc; use std::{collections::HashMap, path::Path}; +#[macro_use] +extern crate lazy_static; + use serde::{Deserialize, Serialize}; use tracing_subscriber::{ filter::EnvFilter, @@ -29,6 +32,7 @@ pub use self::router::shared_subs::Strategy; mod link; pub mod protocol; +pub mod requests; mod router; mod segments; mod server; @@ -45,11 +49,22 @@ pub type Cursor = (u64, u64); pub type ClientId = String; pub type AuthUser = String; pub type AuthPass = String; +pub type AuthUrl = String; pub type AuthHandler = Arc< dyn Fn(ClientId, AuthUser, AuthPass) -> Pin + Send>> + Send + Sync, >; +pub type WebhookAuthHandler = Arc< + dyn Fn( + AuthUrl, + ClientId, + AuthUser, + AuthPass, + ) -> Pin + Send>> + + Send + + Sync, +>; #[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct Config { @@ -63,6 +78,18 @@ pub struct Config { pub bridge: Option, pub prometheus: Option, pub metrics: Option>, + pub webhook: Option, + pub health_check: HealthCheckSettings, +} + +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct HealthCheckSettings { + pub health_check_username: String, + pub health_check_password: String, + pub health_check_client_id: String, + pub health_check_topic: String, + pub health_check_port: u16, + pub health_check_host: String, } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -127,6 +154,27 @@ impl ServerSettings { { self.connections.set_auth_handler(auth_fn) } + + pub fn set_webhook_auth_handler( + &mut self, + auth_fn: F, + authentication_url: String, + webhook_url: String, + authorization_url: String, + retained_url: String, + ) where + F: Fn(AuthUrl, ClientId, AuthUser, AuthPass) -> O + Send + Sync + 'static, + O: IntoFuture + 'static, + O::IntoFuture: Send, + { + self.connections.set_webhook_auth_handler( + auth_fn, + authentication_url, + webhook_url, + authorization_url, + retained_url, + ) + } } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -150,6 +198,16 @@ pub struct ConnectionSettings { pub auth: Option>, #[serde(skip)] pub external_auth: Option, + #[serde(skip)] + pub webhook_external_auth: Option, + #[serde(skip)] + pub authentication_url: Option, + #[serde(skip)] + pub webhook_url: Option, + #[serde(skip)] + pub authorization_url: Option, + #[serde(skip)] + pub retained_url: Option, #[serde(default)] pub dynamic_filters: bool, } @@ -166,6 +224,30 @@ impl ConnectionSettings { Box::pin(auth) })); } + + pub fn set_webhook_auth_handler( + &mut self, + auth_fn: F, + authentication_url: String, + webhook_url: String, + authorization_url: String, + retained_url: String, + ) where + F: Fn(AuthUrl, ClientId, AuthUser, AuthPass) -> O + Send + Sync + 'static, + O: IntoFuture + 'static, + O::IntoFuture: Send, + { + self.authentication_url = Some(authentication_url); + self.webhook_url = Some(webhook_url); + self.authorization_url = Some(authorization_url); + self.retained_url = Some(retained_url); + self.webhook_external_auth = Some(Arc::new( + move |webhook_url, client_id, username, password| { + let auth = auth_fn(webhook_url, client_id, username, password).into_future(); + Box::pin(auth) + }, + )); + } } impl fmt::Debug for ConnectionSettings { @@ -204,6 +286,30 @@ pub struct RouterConfig { pub shared_subscriptions_strategy: Strategy, } +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct WebhookConfig { + authentication_protocol: String, + authentication_host: String, + authentication_port: String, + authentication_endpoint: String, + authorization_protocol: String, + authorization_host: String, + authorization_port: String, + authorization_endpoint: String, + webhook_protocol: String, + webhook_host: String, + webhook_port: String, + webhook_endpoint: String, + retained_protocol: String, + retained_host: String, + retained_port: String, + retained_endpoint: String, + metrics_protocol: String, + metrics_host: String, + metrics_port: String, + metrics_endpoint: String, +} + #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct SegmentConfig { pub max_segment_size: usize, diff --git a/rumqttd/src/link/bridge.rs b/rumqttd/src/link/bridge.rs index 0c6b193be..327442bba 100644 --- a/rumqttd/src/link/bridge.rs +++ b/rumqttd/src/link/bridge.rs @@ -48,6 +48,10 @@ pub async fn start

( config: BridgeConfig, router_tx: Sender<(ConnectionId, Event)>, protocol: P, + username: Option, + webhook_url: Option, + retained_url: Option, + authorization_url: Option, ) -> Result<(), BridgeError> where P: Protocol + Clone + Send + 'static, @@ -61,15 +65,22 @@ where "Starting bridge with subscription on filter \"{}\"", &config.sub_path, ); - let (mut tx, mut rx, _ack) = LinkBuilder::new(&config.name, router_tx) - .dynamic_filters(true) - .build()?; + let (mut tx, mut rx, _ack) = LinkBuilder::new( + &config.name, + router_tx, + username, + webhook_url, + retained_url, + authorization_url, + ) + .dynamic_filters(true) + .build()?; 'outer: loop { let mut network = match network_connect(&config, &config.addr, protocol.clone()).await { Ok(v) => v, Err(e) => { - error!(error=?e, "Error, retrying"); + info!(error=?e, "Error, retrying"); sleep(Duration::from_secs(config.reconnection_delay)).await; continue; } diff --git a/rumqttd/src/link/console.rs b/rumqttd/src/link/console.rs index 9f03f8a1e..74879a76c 100644 --- a/rumqttd/src/link/console.rs +++ b/rumqttd/src/link/console.rs @@ -22,12 +22,26 @@ pub struct ConsoleLink { impl ConsoleLink { /// Requires the corresponding Router to be running to complete - pub fn new(config: ConsoleSettings, router_tx: Sender<(ConnectionId, Event)>) -> ConsoleLink { + pub fn new( + config: ConsoleSettings, + router_tx: Sender<(ConnectionId, Event)>, + username: Option, + webhook_url: Option, + retained_url: Option, + authorization_url: Option, + ) -> ConsoleLink { let tx = router_tx.clone(); - let (link_tx, link_rx, _ack) = LinkBuilder::new("console", tx) - .dynamic_filters(true) - .build() - .unwrap(); + let (link_tx, link_rx, _ack) = LinkBuilder::new( + "console", + tx, + username, + webhook_url, + retained_url, + authorization_url, + ) + .dynamic_filters(true) + .build() + .unwrap(); let connection_id = link_tx.connection_id; ConsoleLink { config, diff --git a/rumqttd/src/link/local.rs b/rumqttd/src/link/local.rs index 212630b46..affab2cbc 100644 --- a/rumqttd/src/link/local.rs +++ b/rumqttd/src/link/local.rs @@ -2,11 +2,11 @@ use crate::protocol::{ Filter, LastWill, LastWillProperties, Packet, Publish, QoS, RetainForwardRule, Subscribe, Unsubscribe, }; -use crate::router::Ack; use crate::router::{ iobufs::{Incoming, Outgoing}, Connection, Event, Notification, ShadowRequest, }; +use crate::router::{Ack, WebhookConnectionProperties}; use crate::ConnectionId; use bytes::Bytes; use flume::{Receiver, RecvError, RecvTimeoutError, SendError, Sender, TrySendError}; @@ -49,10 +49,21 @@ pub struct LinkBuilder<'a> { dynamic_filters: bool, // default to 0, indicating to not use topic alias topic_alias_max: u16, + username: Option, + webhook_url: Option, + retained_url: Option, + authorization_url: Option, } impl<'a> LinkBuilder<'a> { - pub fn new(client_id: &'a str, router_tx: Sender<(ConnectionId, Event)>) -> Self { + pub fn new( + client_id: &'a str, + router_tx: Sender<(ConnectionId, Event)>, + username: Option, + webhook_url: Option, + retained_url: Option, + authorization_url: Option, + ) -> Self { LinkBuilder { client_id, router_tx, @@ -62,6 +73,10 @@ impl<'a> LinkBuilder<'a> { last_will_properties: None, dynamic_filters: false, topic_alias_max: 0, + username, + webhook_url, + retained_url, + authorization_url, } } @@ -106,6 +121,12 @@ impl<'a> LinkBuilder<'a> { self.client_id.to_owned(), self.clean_session, self.dynamic_filters, + WebhookConnectionProperties { + username: self.username, + webhook_url: self.webhook_url, + retained_url: self.retained_url, + authorization_url: self.authorization_url, + }, ); connection diff --git a/rumqttd/src/link/remote.rs b/rumqttd/src/link/remote.rs index e289802de..9bb0efb1c 100644 --- a/rumqttd/src/link/remote.rs +++ b/rumqttd/src/link/remote.rs @@ -6,6 +6,7 @@ use crate::protocol::{ConnAck, Connect, ConnectReturnCode, Login, Packet, Protoc use crate::router::{Event, Notification}; use crate::{ConnectionId, ConnectionSettings}; +use crate::requests::utils_webhook; use flume::{RecvError, SendError, Sender, TrySendError}; use std::cmp::min; use std::collections::VecDeque; @@ -58,6 +59,16 @@ pub struct RemoteLink

{ link_rx: LinkRx, notifications: VecDeque, pub(crate) will_delay_interval: u32, + username: Option, + client_id: String, + webhook_url: Option, +} + +pub struct WebhookProperties { + pub username: Option, + pub webhook_url: Option, + pub retained_url: Option, + pub authorization_url: Option, } impl RemoteLink

{ @@ -68,6 +79,7 @@ impl RemoteLink

{ connect_packet: Packet, dynamic_filters: bool, assigned_client_id: Option, + webhook_properties: WebhookProperties, ) -> Result, Error> { let Packet::Connect(connect, props, lastwill, lastwill_props, _) = connect_packet else { return Err(Error::NotConnectPacket(connect_packet)); @@ -76,6 +88,7 @@ impl RemoteLink

{ // Register this connection with the router. Router replys with ack which if ok will // start the link. Router can sometimes reject the connection (ex max connection limit) let client_id = assigned_client_id.as_ref().unwrap_or(&connect.client_id); + let connection_client_id = client_id.to_string(); let clean_session = connect.clean_session; let topic_alias_max = props.as_ref().and_then(|p| p.topic_alias_max); @@ -93,14 +106,21 @@ impl RemoteLink

{ // the Will Delay Interval has passed or the Session ends, whichever happens first let will_delay_interval = min(session_expiry, delay_interval); - let (link_tx, link_rx, notification) = LinkBuilder::new(client_id, router_tx) - .tenant_id(tenant_id) - .clean_session(clean_session) - .last_will(lastwill) - .last_will_properties(lastwill_props) - .dynamic_filters(dynamic_filters) - .topic_alias_max(topic_alias_max.unwrap_or(0)) - .build()?; + let (link_tx, link_rx, notification) = LinkBuilder::new( + client_id, + router_tx, + webhook_properties.username.to_owned(), + webhook_properties.webhook_url.to_owned(), + webhook_properties.retained_url.to_owned(), + webhook_properties.authorization_url.to_owned(), + ) + .tenant_id(tenant_id) + .clean_session(clean_session) + .last_will(lastwill) + .last_will_properties(lastwill_props) + .dynamic_filters(dynamic_filters) + .topic_alias_max(topic_alias_max.unwrap_or(0)) + .build()?; let id = link_rx.id(); Span::current().record("connection_id", id); @@ -122,6 +142,9 @@ impl RemoteLink

{ link_rx, notifications: VecDeque::with_capacity(100), will_delay_interval, + username: webhook_properties.username, + client_id: connection_client_id, + webhook_url: webhook_properties.webhook_url, }) } @@ -134,6 +157,11 @@ impl RemoteLink

{ select! { o = self.network.read() => { let packet = o?; + let client_id = self.client_id.to_owned(); + let username = self.username.to_owned(); + let webhook_url = self.webhook_url.to_owned(); + utils_webhook::call_webhook_from_packet(packet.clone(), client_id, username, webhook_url).await; + let len = { let mut buffer = self.link_tx.buffer(); buffer.push_back(packet); @@ -198,7 +226,7 @@ where handle_auth(config.clone(), login.as_ref(), &connect.client_id).await?; // When keep_alive feature is disabled client can live forever, which is not good in - // distributed broker context so currenlty we don't allow it. + // distributed broker context so currently we don't allow it. if connect.keep_alive == 0 { return Err(Error::ZeroKeepAlive); } @@ -227,7 +255,10 @@ async fn handle_auth( login: Option<&Login>, client_id: &str, ) -> Result<(), Error> { - if config.auth.is_none() && config.external_auth.is_none() { + if config.auth.is_none() + && config.external_auth.is_none() + && config.webhook_external_auth.is_none() + { return Ok(()); } @@ -254,6 +285,22 @@ async fn handle_auth( return Ok(()); } + if let Some(auth) = &config.webhook_external_auth { + if let Some(authentication_url) = &config.authentication_url { + if !auth( + authentication_url.to_owned(), + client_id.to_owned(), + username.to_owned(), + password.to_owned(), + ) + .await + { + return Err(Error::InvalidAuth); + } + return Ok(()); + } + } + if let Some(pairs) = &config.auth { if let Some(stored_password) = pairs.get(username) { if stored_password.as_bytes().ct_eq(password.as_bytes()).into() { @@ -282,6 +329,11 @@ mod tests { max_inflight_count: 0, auth: None, external_auth: None, + webhook_external_auth: None, + authentication_url: None, + webhook_url: None, + authorization_url: None, + retained_url: None, dynamic_filters: false, } } diff --git a/rumqttd/src/main.rs b/rumqttd/src/main.rs index 8b22805f8..e20d984a3 100644 --- a/rumqttd/src/main.rs +++ b/rumqttd/src/main.rs @@ -1,10 +1,11 @@ -use config::FileFormat; +use rumqttd::requests::utils_requests; +use rumqttd::requests::utils_settings; use rumqttd::Broker; use clap::Parser; +use rumqttd::requests::utils_settings::SETTINGS; use tracing::trace; - -static RUMQTTD_DEFAULT_CONFIG: &str = include_str!("../rumqttd.toml"); +use tracing_subscriber::EnvFilter; #[derive(Parser)] #[command(version)] @@ -31,25 +32,13 @@ enum Command { GenerateConfig, } -fn main() { +#[tokio::main(flavor = "current_thread")] +async fn main() { let commandline: CommandLine = CommandLine::parse(); - - if let Some(Command::GenerateConfig) = commandline.command { - println!("{RUMQTTD_DEFAULT_CONFIG}"); - return; - } - if !commandline.quiet { banner(); } - let level = match commandline.verbose { - 0 => "rumqttd=warn", - 1 => "rumqttd=info", - 2 => "rumqttd=debug", - _ => "rumqttd=trace", - }; - // tracing syntax -> let builder = tracing_subscriber::fmt() .pretty() @@ -57,27 +46,20 @@ fn main() { .with_file(false) .with_thread_ids(false) .with_thread_names(false) - .with_env_filter(level) + .with_env_filter(EnvFilter::from_env("RUST_LOG")) .with_filter_reloading(); let reload_handle = builder.reload_handle(); builder .try_init() - .expect("initialized subscriber succesfully"); - - let mut config_builder = config::Config::builder(); - - config_builder = match &commandline.config { - Some(config) => config_builder.add_source(config::File::with_name(config)), - None => config_builder.add_source(config::File::from_str( - RUMQTTD_DEFAULT_CONFIG, - FileFormat::Toml, - )), - }; - - let mut configs: rumqttd::Config = config_builder.build().unwrap().try_deserialize().unwrap(); + .expect("initialized subscriber successfully"); + let mut configs = utils_settings::get_settings(); + let webhook_url = utils_settings::get_webhook_url(&configs); + let authentication_url = utils_settings::get_authentication_url(&configs); + let authorization_url = utils_settings::get_authorization_url(&configs); + let retained_url = utils_settings::get_retained_url(&configs); if let Some(console_config) = configs.console.as_mut() { console_config.set_filter_reload_handle(reload_handle) } @@ -86,10 +68,34 @@ fn main() { // println!("{:#?}", configs); + let server = configs.v4.as_mut().and_then(|v4| v4.get_mut("1")).unwrap(); + server.set_webhook_auth_handler( + auth, + authentication_url.to_string(), + webhook_url.to_string(), + authorization_url.to_string(), + retained_url.to_string(), + ); let mut broker = Broker::new(configs); broker.start().unwrap(); } +async fn auth(webhook_url: String, client_id: String, username: String, password: String) -> bool { + // users can fetch data from DB or tokens and use them! + // do the verification and return true if verified, else false + if client_id == SETTINGS.health_check.health_check_client_id + && username == SETTINGS.health_check.health_check_username + && password == SETTINGS.health_check.health_check_password + { + return true; + } + let result = utils_requests::authenticate_user(&webhook_url, &username, &password).await; + match result.auth_response { + Some(response) => response.result == "allow", + None => false, + } +} + // Do any extra validation that needs to be done before starting the broker here. fn validate_config(configs: &rumqttd::Config) { if let Some(v4) = &configs.v4 { diff --git a/rumqttd/src/protocol/v4/publish.rs b/rumqttd/src/protocol/v4/publish.rs index b64cb3143..76c739851 100644 --- a/rumqttd/src/protocol/v4/publish.rs +++ b/rumqttd/src/protocol/v4/publish.rs @@ -1,5 +1,9 @@ +use crate::requests::utils_webhook::remove_username_from_topic; + use super::*; use bytes::{Buf, Bytes}; +use core::str; +use regex::Regex; fn len(publish: &Publish) -> usize { let len = 2 + publish.topic.len() + publish.payload.len(); @@ -42,7 +46,10 @@ pub fn read(fixed_header: FixedHeader, mut bytes: Bytes) -> Result Result { - let len = publish.len(); + let topic = publish.topic.clone(); + let new_topic = remove_username_from_topic(publish.topic.clone()); + let delta = new_topic.len() - topic.len(); + let len = publish.len() + delta; let dup = publish.dup as u8; let qos = publish.qos as u8; @@ -50,7 +57,7 @@ pub fn write(publish: &Publish, buffer: &mut BytesMut) -> Result { buffer.put_u8(0b0011_0000 | retain | qos << 1 | dup << 3); let count = write_remaining_length(buffer, len)?; - write_mqtt_bytes(buffer, &publish.topic); + write_mqtt_bytes(buffer, &new_topic); if publish.qos != QoS::AtMostOnce { let pkid = publish.pkid; diff --git a/rumqttd/src/requests/mod.rs b/rumqttd/src/requests/mod.rs new file mode 100644 index 000000000..b4fc2c692 --- /dev/null +++ b/rumqttd/src/requests/mod.rs @@ -0,0 +1,3 @@ +pub mod utils_requests; +pub mod utils_settings; +pub mod utils_webhook; diff --git a/rumqttd/src/requests/utils_requests.rs b/rumqttd/src/requests/utils_requests.rs new file mode 100644 index 000000000..d9a1022fc --- /dev/null +++ b/rumqttd/src/requests/utils_requests.rs @@ -0,0 +1,284 @@ +use serde; +use serde::{Deserialize, Serialize}; +use serde_json::json; + +use crate::router::{RouterMeter, SubscriptionMeter}; + +#[derive(Clone, Debug, Deserialize)] +pub struct AuthResponse { + pub result: String, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct AuthResultResponse { + pub auth_response: Option, + pub status_code: u16, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct AuthorizeResponse { + pub result: String, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct AuthorizationResultResponse { + pub auth_response: Option, + pub status_code: u16, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct WebhookResponse { + pub result: String, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct WebhookResultResponse { + pub webhook_response: Option, + pub status_code: u16, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct WebhookPayload { + #[serde(skip_serializing_if = "Option::is_none")] + pub clientid: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub payload: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub topic: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub action: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub username: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub event: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub reason_code: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct MqttRetainedPayload { + #[serde(skip_serializing_if = "Option::is_none")] + pub topic: Option, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug, Eq, Hash, Clone)] +pub struct MqttRetainedResult { + #[serde(skip_serializing_if = "Option::is_none")] + pub topic: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub payload: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct MetricsPayload { + pub server_id: usize, + #[serde(skip_serializing_if = "Option::is_none")] + pub router_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub router_meter: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub subscription_meter: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub topic: Option, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct MetricsResponse { + pub status_code: u16, +} + +#[derive(Clone, Debug, Deserialize)] +pub struct MqttRetainedResponse { + pub mqtt_retained_result: Option>, + pub status_code: u16, +} + +pub async fn authenticate_user( + webhook_url: &str, + username: &str, + password: &str, +) -> AuthResultResponse { + let payload = json!({"username": username, "password": password}); + + let response = reqwest::Client::new() + .post(webhook_url) + .json(&payload) + .send() + .await; + let response = match response { + Ok(response) => response, + Err(_) => { + return AuthResultResponse { + auth_response: None, + status_code: reqwest::StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + }; + } + }; + let status_code = response.status(); + match status_code { + reqwest::StatusCode::OK => { + let result_json: AuthResponse = response.json().await.unwrap(); + AuthResultResponse { + auth_response: Some(result_json), + status_code: status_code.as_u16(), + } + } + _ => AuthResultResponse { + auth_response: None, + status_code: status_code.as_u16(), + }, + } +} + +pub fn authorize_user( + authorization_url: &str, + username: &str, + topic: &str, + action: &str, +) -> AuthorizationResultResponse { + let payload = json!({"username": username, "topic": topic, "action": action}); + + let response = reqwest::blocking::Client::new() + .post(authorization_url) + .json(&payload) + .send(); + let response = match response { + Ok(response) => response, + Err(_) => { + return AuthorizationResultResponse { + auth_response: None, + status_code: reqwest::StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + }; + } + }; + let status_code = response.status(); + match status_code { + reqwest::StatusCode::OK => { + let result_json: AuthResponse = response.json().unwrap(); + AuthorizationResultResponse { + auth_response: Some(result_json), + status_code: status_code.as_u16(), + } + } + _ => AuthorizationResultResponse { + auth_response: None, + status_code: status_code.as_u16(), + }, + } +} + +pub async fn webhook(webhook_url: &str, webhook_payload: WebhookPayload) -> WebhookResultResponse { + let response = reqwest::Client::new() + .post(webhook_url) + .json(&webhook_payload) + .send() + .await; + let response = match response { + Ok(response) => response, + Err(_) => { + return WebhookResultResponse { + webhook_response: None, + status_code: reqwest::StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + }; + } + }; + let status_code = response.status(); + match status_code { + reqwest::StatusCode::OK => WebhookResultResponse { + webhook_response: None, + status_code: status_code.as_u16(), + }, + _ => WebhookResultResponse { + webhook_response: None, + status_code: status_code.as_u16(), + }, + } +} + +pub fn metrics(metrics_url: &str, metrics_payloads: Vec) -> MetricsResponse { + let response = reqwest::blocking::Client::new() + .post(metrics_url) + .json(&metrics_payloads) + .send(); + + let response = match response { + Ok(response) => response, + Err(_) => { + return MetricsResponse { + status_code: reqwest::StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + }; + } + }; + let status_code = response.status(); + match status_code { + reqwest::StatusCode::OK => MetricsResponse { + status_code: status_code.as_u16(), + }, + _ => MetricsResponse { + status_code: status_code.as_u16(), + }, + } +} + +pub fn retained( + retained_url: &str, + mqtt_retained_payload: MqttRetainedPayload, +) -> MqttRetainedResponse { + let response = reqwest::blocking::Client::new() + .post(retained_url) + .json(&mqtt_retained_payload) + .send(); + let response = match response { + Ok(response) => response, + Err(_) => { + return MqttRetainedResponse { + mqtt_retained_result: None, + status_code: reqwest::StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + }; + } + }; + let status_code = response.status(); + match status_code { + reqwest::StatusCode::OK => { + let result_json: Vec = response.json().unwrap(); + MqttRetainedResponse { + mqtt_retained_result: Some(result_json), + status_code: status_code.as_u16(), + } + } + _ => MqttRetainedResponse { + mqtt_retained_result: None, + status_code: status_code.as_u16(), + }, + } +} + +pub fn webhook_blocking( + webhook_url: &str, + webhook_payload: WebhookPayload, +) -> WebhookResultResponse { + let response = reqwest::blocking::Client::new() + .post(webhook_url) + .json(&webhook_payload) + .send(); + let response = match response { + Ok(response) => response, + Err(_) => { + return WebhookResultResponse { + webhook_response: None, + status_code: reqwest::StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + }; + } + }; + let status_code = response.status(); + match status_code { + reqwest::StatusCode::OK => WebhookResultResponse { + webhook_response: None, + status_code: status_code.as_u16(), + }, + _ => WebhookResultResponse { + webhook_response: None, + status_code: status_code.as_u16(), + }, + } +} diff --git a/rumqttd/src/requests/utils_settings.rs b/rumqttd/src/requests/utils_settings.rs new file mode 100644 index 000000000..1032f863a --- /dev/null +++ b/rumqttd/src/requests/utils_settings.rs @@ -0,0 +1,173 @@ +use std::env; +use std::path::Path; + +use config::builder::DefaultState; +use config::Environment; +use config::{ConfigBuilder, File}; + +use crate::Config; + +fn update_settings( + builder: ConfigBuilder, + file_path: &str, +) -> ConfigBuilder { + if Path::new(file_path).exists() { + return builder.add_source(File::with_name(file_path)); + } + builder +} + +lazy_static! { + pub static ref SETTINGS: Config = get_settings(); +} + +pub fn get_settings() -> Config { + let mut config_builder = config::Config::builder(); + config_builder = + config_builder.add_source(Environment::with_prefix("DYNACONF").separator("__")); + config_builder = update_settings(config_builder, "config/default.toml"); + config_builder = update_settings(config_builder, "config/local.toml"); + config_builder = update_settings_from_environment(config_builder); + let result: Config = config_builder.build().unwrap().try_deserialize().unwrap(); + result +} + +pub fn get_authentication_url(config: &Config) -> String { + if let Some(webhook_config) = &config.webhook { + let protocol = webhook_config.authentication_protocol.to_string(); + let host = webhook_config.authentication_host.to_string(); + let port = webhook_config.authentication_port.to_string(); + let endpoint = webhook_config.authentication_endpoint.to_string(); + let result = format!("{protocol}://{host}:{port}{endpoint}"); + return result; + } + "".to_string() +} + +pub fn get_authorization_url(config: &Config) -> String { + if let Some(webhook_config) = &config.webhook { + let protocol = webhook_config.authorization_protocol.to_string(); + let host = webhook_config.authorization_host.to_string(); + let port = webhook_config.authorization_port.to_string(); + let endpoint = webhook_config.authorization_endpoint.to_string(); + let result = format!("{protocol}://{host}:{port}{endpoint}"); + return result; + } + "".to_string() +} + +pub fn get_webhook_url(config: &Config) -> String { + if let Some(webhook_config) = &config.webhook { + let protocol = webhook_config.webhook_protocol.to_string(); + let host = webhook_config.webhook_host.to_string(); + let port = webhook_config.webhook_port.to_string(); + let endpoint = webhook_config.webhook_endpoint.to_string(); + let result = format!("{protocol}://{host}:{port}{endpoint}"); + return result; + } + "".to_string() +} + +pub fn get_retained_url(config: &Config) -> String { + if let Some(webhook_config) = &config.webhook { + let protocol = webhook_config.retained_protocol.to_string(); + let host = webhook_config.retained_host.to_string(); + let port = webhook_config.retained_port.to_string(); + let endpoint = webhook_config.retained_endpoint.to_string(); + let result = format!("{protocol}://{host}:{port}{endpoint}"); + return result; + } + "".to_string() +} + +pub fn get_metrics_url(config: &Config) -> String { + if let Some(webhook_config) = &config.webhook { + let protocol = webhook_config.metrics_protocol.to_string(); + let host = webhook_config.metrics_host.to_string(); + let port = webhook_config.metrics_port.to_string(); + let endpoint = webhook_config.metrics_endpoint.to_string(); + let result = format!("{protocol}://{host}:{port}{endpoint}"); + return result; + } + "".to_string() +} + +fn update_webhook_configuration( + builder: ConfigBuilder, + host_env_variable: &str, + port_env_variable: &str, + default_host_env_variable: &str, + default_port_env_variable: &str, + host_setting: &str, + port_setting: &str, +) -> ConfigBuilder { + let mut builder = builder; + let host_env_variable = match env::var(host_env_variable) { + Ok(host_env_variable) => host_env_variable, + Err(_) => default_host_env_variable.to_string(), + }; + let port_env_variable = match env::var(port_env_variable) { + Ok(port_env_variable) => port_env_variable, + Err(_) => default_port_env_variable.to_string(), + }; + if let Ok(host) = env::var(host_env_variable) { + if let Ok(port) = env::var(port_env_variable) { + builder = builder.set_override(host_setting, host).unwrap(); + builder = builder.set_override(port_setting, port).unwrap(); + } + } + builder +} + +pub fn update_settings_from_environment( + builder: ConfigBuilder, +) -> ConfigBuilder { + let mut builder = builder; + builder = update_webhook_configuration( + builder, + "MQTT_AUTHENTICATION_HOST_ENV_VARIABLE", + "MQTT_AUTHENTICATION_PORT_ENV_VARIABLE", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_HOST", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_PORT", + "webhook.authentication_host", + "webhook.authentication_port", + ); + builder = update_webhook_configuration( + builder, + "MQTT_AUTHORIZATION_HOST_ENV_VARIABLE", + "MQTT_AUTHORIZATION_PORT_ENV_VARIABLE", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_HOST", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_PORT", + "webhook.authorization_host", + "webhook.authorization_port", + ); + builder = update_webhook_configuration( + builder, + "MQTT_WEBHOOK_HOST_ENV_VARIABLE", + "MQTT_WEBHOOK_PORT_ENV_VARIABLE", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_HOST", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_PORT", + "webhook.webhook_host", + "webhook.webhook_port", + ); + + builder = update_webhook_configuration( + builder, + "MQTT_RETAINED_HOST_ENV_VARIABLE", + "MQTT_RETAINED_PORT_ENV_VARIABLE", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_HOST", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_PORT", + "webhook.retained_host", + "webhook.retained_port", + ); + builder = update_webhook_configuration( + builder, + "MQTT_METRICS_HOST_ENV_VARIABLE", + "MQTT_METRICS_PORT_ENV_VARIABLE", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_HOST", + "UBIDOTS_REACTOR_MQTT_SERVER_SERVICE_PORT", + "webhook.metrics_host", + "webhook.metrics_port", + ); + builder +} diff --git a/rumqttd/src/requests/utils_webhook.rs b/rumqttd/src/requests/utils_webhook.rs new file mode 100644 index 000000000..d134b043a --- /dev/null +++ b/rumqttd/src/requests/utils_webhook.rs @@ -0,0 +1,116 @@ +use bytes::Bytes; + +use regex::Regex; + +use crate::protocol::Packet; + +use super::utils_requests::{self, WebhookPayload}; + +pub fn add_username_to_topic(original_topic: &str, username: Option) -> String { + let mut new_topic = original_topic.to_string(); + if let Some(username) = username { + new_topic = new_topic.replace("/v1.6/", &format!("/v1.6/users/{username}/")); + new_topic = new_topic.replace("/v2.0/", &format!("/v2.0/users/{username}/")); + } + new_topic +} + +pub fn remove_username_from_topic(topic: Bytes) -> Bytes { + let re = Regex::new(r"/users/[^/]+").unwrap(); + let topic_string: String = String::from_utf8(topic.to_vec()).unwrap(); + let topic_string = re.replace(&topic_string, ""); + let topic_bytes = topic_string.as_bytes().to_vec(); + Bytes::from(topic_bytes) +} + +pub async fn call_webhook_from_packet( + packet: Packet, + client_id: String, + username: Option, + webhook_url: Option, +) { + match packet.clone() { + Packet::Subscribe(subscribe, _props) => { + for f in subscribe.filters { + let client_id = client_id.to_string(); + let username = username.to_owned(); + let topic = add_username_to_topic(&f.path, username.to_owned()); + if let Some(webhook_url) = webhook_url.to_owned() { + let _response = utils_requests::webhook( + &webhook_url, + WebhookPayload { + clientid: Some(client_id), + payload: None, + topic: Some(topic), + action: None, + username, + event: Some("session.subscribed".to_string()), + reason_code: None, + }, + ) + .await; + } + } + } + Packet::Disconnect(_disconnect, _properties) => { + let client_id = client_id.to_string(); + let username = username.to_owned(); + if let Some(webhook_url) = webhook_url.to_owned() { + let _response = utils_requests::webhook( + &webhook_url, + WebhookPayload { + clientid: Some(client_id), + payload: None, + topic: None, + action: None, + username, + event: Some("client.disconnected".to_string()), + reason_code: None, + }, + ) + .await; + } + } + Packet::Unsubscribe(_unsubscribe, _properties) => { + let client_id = client_id.to_string(); + let username = username.to_owned(); + if let Some(webhook_url) = webhook_url.to_owned() { + let _response = utils_requests::webhook( + &webhook_url, + WebhookPayload { + clientid: Some(client_id), + payload: None, + topic: None, + action: None, + username, + event: Some("session.unsubscribed".to_string()), + reason_code: None, + }, + ) + .await; + } + } + Packet::Publish(publish, _properties) => { + let client_id = client_id.to_string(); + let username = username.to_owned(); + if let Some(webhook_url) = webhook_url.to_owned() { + let topic = String::from_utf8(publish.topic.to_vec()).unwrap(); + let payload = String::from_utf8(publish.payload.to_vec()).unwrap(); + let _response = utils_requests::webhook( + &webhook_url, + WebhookPayload { + clientid: Some(client_id), + topic: Some(topic), + payload: Some(payload), + action: None, + username, + event: Some("message.publish".to_string()), + reason_code: None, + }, + ) + .await; + } + } + _v => {} + } +} diff --git a/rumqttd/src/router/connection.rs b/rumqttd/src/router/connection.rs index 992376cb1..4f457dbac 100644 --- a/rumqttd/src/router/connection.rs +++ b/rumqttd/src/router/connection.rs @@ -33,6 +33,17 @@ pub struct Connection { pub(crate) broker_topic_aliases: Option, /// subscription IDs for a connection pub(crate) subscription_ids: HashMap, + pub username: Option, + pub webhook_url: Option, + pub retained_url: Option, + pub authorization_url: Option, +} + +pub struct WebhookConnectionProperties { + pub username: Option, + pub webhook_url: Option, + pub retained_url: Option, + pub authorization_url: Option, } impl Connection { @@ -42,6 +53,7 @@ impl Connection { client_id: String, clean: bool, dynamic_filters: bool, + webhook_connection_properties: WebhookConnectionProperties, ) -> Connection { // Change client id to -> tenant_id.client_id and derive topic path prefix // to validate topics @@ -66,6 +78,10 @@ impl Connection { topic_aliases: HashMap::new(), broker_topic_aliases: None, subscription_ids: HashMap::new(), + username: webhook_connection_properties.username, + webhook_url: webhook_connection_properties.webhook_url, + authorization_url: webhook_connection_properties.authorization_url, + retained_url: webhook_connection_properties.retained_url, } } diff --git a/rumqttd/src/router/logs.rs b/rumqttd/src/router/logs.rs index 21f59e023..be5020b74 100644 --- a/rumqttd/src/router/logs.rs +++ b/rumqttd/src/router/logs.rs @@ -269,7 +269,7 @@ impl DataLog { self.retained_publishes.remove(&topic); } - pub fn read_retained_messages(&mut self, filter: &str) -> Vec { + pub fn _read_retained_messages(&mut self, filter: &str) -> Vec { trace!(info = "reading retain msg", filter = &filter); let now = Instant::now(); diff --git a/rumqttd/src/router/mod.rs b/rumqttd/src/router/mod.rs index a75cad34f..6f5011360 100644 --- a/rumqttd/src/router/mod.rs +++ b/rumqttd/src/router/mod.rs @@ -27,6 +27,7 @@ mod waiters; pub use alertlog::Alert; pub use connection::Connection; +pub use connection::WebhookConnectionProperties; pub use routing::Router; pub use waiters::Waiters; @@ -116,6 +117,7 @@ pub struct Forward { pub size: usize, pub publish: Publish, pub properties: Option, + pub username: Option, } #[derive(Debug, Clone)] diff --git a/rumqttd/src/router/routing.rs b/rumqttd/src/router/routing.rs index ebf362a71..03e2e4b4e 100644 --- a/rumqttd/src/router/routing.rs +++ b/rumqttd/src/router/routing.rs @@ -4,11 +4,15 @@ use crate::protocol::{ PubRecReason, PubRel, PubRelReason, Publish, PublishProperties, QoS, SubAck, SubscribeReasonCode, UnsubAck, UnsubAckReason, }; +use crate::requests::utils_requests; +use crate::requests::utils_requests::MqttRetainedPayload; +use crate::requests::utils_webhook; use crate::router::alertlog::alert; use crate::router::scheduler::{PauseReason, Tracker}; use crate::router::{ConnectionEvents, Forward}; use crate::segments::Position; use crate::*; +use bytes::Bytes; use flume::{bounded, Receiver, RecvError, Sender, TryRecvError}; use slab::Slab; use std::collections::{HashMap, HashSet, VecDeque}; @@ -50,6 +54,8 @@ pub enum RouterError { InvalidClientId(String), #[error("Disconnection (Reason: {0:?})")] Disconnect(DisconnectReasonCode), + #[error("User Not Authorized {0}")] + UserNotAuthorized(String), } // TODO: set this to some appropriate value @@ -167,7 +173,7 @@ impl Router { router .spawn(move || { let e = self.run(0); - error!(reason=?e, "Router done!"); + info!(reason=?e, "Router done!"); }) .unwrap(); link @@ -215,7 +221,7 @@ impl Router { // A connection should not be scheduled multiple times #[cfg(debug_assertions)] - if let Some(readyqueue) = self.scheduler.check_readyqueue_duplicates() { + if let Some(readyqueue) = self.scheduler._check_readyqueue_duplicates() { warn!( "Connection was scheduled multiple times in readyqueue: {:?}", readyqueue @@ -272,7 +278,7 @@ impl Router { ) { let client_id = outgoing.client_id.clone(); if let Err(err) = validate_clientid(&client_id) { - error!("Invalid client_id: {}", err); + info!("Invalid client_id: {}", err); return; }; @@ -285,7 +291,7 @@ impl Router { let connection_id = self.connection_map.get(&client_id); if let Some(connection_id) = connection_id { - error!( + info!( "Duplicate client_id, dropping previous connection with connection_id: {}", connection_id ); @@ -413,7 +419,7 @@ impl Router { let client_id = match &self.obufs.get(id) { Some(v) => v.client_id.clone(), None => { - error!("no-connection id {} is already gone", id); + info!("no-connection id {} is already gone", id); return; } }; @@ -433,7 +439,7 @@ impl Router { let outgoing = match self.obufs.get_mut(id) { Some(v) => v, None => { - error!("no-connection id {} is already gone", id); + info!("no-connection id {} is already gone", id); return; } }; @@ -532,11 +538,11 @@ impl Router { /// Handles new incoming data on a topic fn handle_device_payload(&mut self, id: ConnectionId) { - // TODO: Retun errors and move error handling to the caller + // TODO: Return errors and move error handling to the caller let incoming = match self.ibufs.get_mut(id) { Some(v) => v, None => { - error!("no-connection id {} is already gone", id); + info!("no-connection id {} is already gone", id); return; } }; @@ -624,7 +630,7 @@ impl Router { } Err(e) => { // Disconnect on bad publishes - error!( + info!( reason = ?e, "Failed to append to commitlog" ); self.router_meters.failed_publishes += 1; @@ -640,7 +646,7 @@ impl Router { let meter = &mut self.ibufs.get_mut(id).unwrap().meter; if let Err(e) = meter.register_publish(&publish) { - error!( + info!( reason = ?e, "Failed to write to incoming meter" ); }; @@ -651,12 +657,16 @@ impl Router { // let len = s.len(); for f in &mut subscribe.filters { + let connection = self.connections.get_mut(id).unwrap(); + f.path = utils_webhook::add_username_to_topic( + &f.path, + connection.username.clone(), + ); let span = tracing::info_span!("subscribe", topic = f.path, pkid = subscribe.pkid); let _guard = span.enter(); info!("Adding subscription on topic {}", f.path); - let connection = self.connections.get_mut(id).unwrap(); if let Err(e) = validate_subscription(connection, f) { warn!(reason = ?e,"Subscription cannot be validated: {}", e); @@ -676,7 +686,7 @@ impl Router { let subscription_id = props.as_ref().and_then(|p| p.id); if subscription_id == Some(0) { - error!("Subscription identifier can't be 0"); + info!("Subscription identifier can't be 0"); disconnect = true; disconnect_reason = Some(DisconnectReasonCode::ProtocolError); break; @@ -767,7 +777,7 @@ impl Router { let outgoing = self.obufs.get_mut(id).unwrap(); let pkid = puback.pkid; if outgoing.register_ack(pkid).is_none() { - error!(pkid, "Unsolicited/ooo ack received for pkid {}", pkid); + info!(pkid, "Unsolicited/ooo ack received for pkid {}", pkid); disconnect = true; break; } @@ -781,7 +791,7 @@ impl Router { let outgoing = self.obufs.get_mut(id).unwrap(); let pkid = pubrec.pkid; if outgoing.register_ack(pkid).is_none() { - error!(pkid, "Unsolicited/ooo ack received for pkid {}", pkid); + info!(pkid, "Unsolicited/ooo ack received for pkid {}", pkid); disconnect = true; break; } @@ -835,7 +845,7 @@ impl Router { } Err(e) => { // Disconnect on bad publishes - error!( + info!( reason = ?e, "Failed to append to commitlog" ); self.router_meters.failed_publishes += 1; @@ -852,7 +862,7 @@ impl Router { let outgoing = self.obufs.get_mut(id).unwrap(); let pkid = pubcomp.pkid; if outgoing.register_pubcomp(pkid).is_none() { - error!( + info!( pkid, "ack received for pkid {}, but the pkid didn't exists!", pkid ); @@ -1003,7 +1013,7 @@ impl Router { let outgoing = match self.obufs.get_mut(id) { Some(v) => v, None => { - error!("Connection is already disconnected"); + info!("Connection is already disconnected"); return Some(()); } }; @@ -1140,7 +1150,7 @@ impl Router { } Err(e) => { // Disconnect on bad publishes - error!( + info!( reason = ?e, "Failed to append to commitlog" ); self.router_meters.failed_publishes += 1; @@ -1164,7 +1174,7 @@ impl Router { if !meters.is_empty() { for (meter_id, link) in self.meters.iter() { if let Err(e) = link.try_send(meters.clone()) { - error!(meter_id, "Failed to send meter. Error = {:?}", e); + info!(meter_id, "Failed to send meter. Error = {:?}", e); } } } @@ -1177,7 +1187,7 @@ impl Router { let alerts: Vec = alerts.into(); for (meter_id, link) in self.alerts.iter() { if let Err(e) = link.try_send(alerts.clone()) { - error!(meter_id, "Failed to send alert. Error = {:?}", e); + info!(meter_id, "Failed to send alert. Error = {:?}", e); } } } @@ -1204,7 +1214,7 @@ fn append_to_commitlog( .as_ref() .is_some_and(|p| !p.subscription_identifiers.is_empty()) { - error!("A PUBLISH packet sent from a Client to a Server MUST NOT contain a Subscription Identifier"); + info!("A PUBLISH packet sent from a Client to a Server MUST NOT contain a Subscription Identifier"); return Err(RouterError::Disconnect( DisconnectReasonCode::MalformedPacket, )); @@ -1263,7 +1273,7 @@ fn append_to_commitlog( o = offset; } - // error!("{:15.15}[E] {:20} topic = {}", connections[id].client_id, "no-filter", topic); + // info!("{:15.15}[E] {:20} topic = {}", connections[id].client_id, "no-filter", topic); Ok(o) } @@ -1279,7 +1289,7 @@ fn append_will_message( .as_ref() .is_some_and(|p| !p.subscription_identifiers.is_empty()) { - error!("A PUBLISH packet sent from a Client to a Server MUST NOT contain a Subscription Identifier"); + info!("A PUBLISH packet sent from a Client to a Server MUST NOT contain a Subscription Identifier"); return Err(RouterError::Disconnect( DisconnectReasonCode::MalformedPacket, )); @@ -1338,7 +1348,7 @@ fn validate_and_set_topic_alias( alias: u16, ) -> Result<(), RouterError> { if alias == 0 || alias > TOPIC_ALIAS_MAX { - error!("Alias must be greater than 0 and <={TOPIC_ALIAS_MAX}"); + info!("Alias must be greater than 0 and <={TOPIC_ALIAS_MAX}"); return Err(RouterError::Disconnect( DisconnectReasonCode::TopicAliasInvalid, )); @@ -1347,7 +1357,7 @@ fn validate_and_set_topic_alias( if publish.topic.is_empty() { // if publish topic is empty, publisher must have set a valid alias let Some(alias_topic) = connection.topic_aliases.get(&alias) else { - error!("Empty topic name with invalid alias"); + info!("Empty topic name with invalid alias"); return Err(RouterError::Disconnect(DisconnectReasonCode::ProtocolError)); }; // set the publish topic before further processing @@ -1465,7 +1475,46 @@ fn forward_device_data( // NOTE: ideally we want to limit the number of read messages // and skip the messages previously read while reading next time. // but for now, we just try to read all messages and drop the excess ones - let mut retained_publishes = datalog.read_retained_messages(&request.filter); + let retained_url = connection.retained_url.to_owned(); + let mut retained_publishes: Vec<(Publish, Option)> = vec![]; + if let Some(retained_url) = retained_url { + let topic = request.filter.to_owned(); + let mqtt_retained_payload = MqttRetainedPayload { topic: Some(topic) }; + let mqtt_retained_response = + utils_requests::retained(&retained_url, mqtt_retained_payload); + if let Some(retained_messages) = mqtt_retained_response.mqtt_retained_result { + retained_publishes = retained_messages + .iter() + .map(|mqtt_retained_result| { + ( + Publish { + dup: false, + qos: QoS::AtMostOnce, + pkid: 1, + retain: true, + topic: Bytes::from( + mqtt_retained_result + .topic + .to_owned() + .unwrap() + .as_bytes() + .to_vec(), + ), + payload: Bytes::from( + mqtt_retained_result + .payload + .to_owned() + .unwrap() + .as_bytes() + .to_vec(), + ), + }, + None, + ) + }) + .collect(); + } + } retained_publishes.truncate(inflight_slots as usize); publishes.extend(retained_publishes.into_iter().map(|p| (p, None))); @@ -1479,7 +1528,7 @@ fn forward_device_data( match datalog.native_readv(request.filter_idx, request.cursor, inflight_slots) { Ok(v) => v, Err(e) => { - error!(error = ?e, "Failed to read from commitlog {}", e); + info!(error = ?e, "Failed to read from commitlog {}", e); return ConsumeStatus::FilterCaughtup; } }; @@ -1587,6 +1636,7 @@ fn forward_device_data( size: 0, publish, properties, + username: connection.username.clone(), } }); @@ -1736,8 +1786,26 @@ fn validate_subscription( if filter.path.starts_with('$') && !filter.path.starts_with("$share") { return Err(RouterError::InvalidFilterPrefix(filter.path.to_owned())); } - - Ok(()) + let action = "subscribe"; + let topic = &filter.path; + let authorization_url = connection.authorization_url.to_owned(); + match authorization_url { + Some(authorization_url) => match connection.username.clone() { + Some(username) => { + let response = + utils_requests::authorize_user(&authorization_url, &username, topic, action); + match response.auth_response { + Some(response) => match response.result.as_str() { + "allow" => Ok(()), + _ => Err(RouterError::UserNotAuthorized(username)), + }, + None => Ok(()), + } + } + None => Ok(()), + }, + None => Ok(()), + } } fn validate_clientid(client_id: &str) -> Result<(), RouterError> { diff --git a/rumqttd/src/router/scheduler.rs b/rumqttd/src/router/scheduler.rs index cca628780..24f0a70d3 100644 --- a/rumqttd/src/router/scheduler.rs +++ b/rumqttd/src/router/scheduler.rs @@ -201,7 +201,7 @@ impl Tracker { // Methods to check duplicates in trackers and schedulers impl Scheduler { // Return a `Some` if duplicate were found, otherwise `None` - pub fn check_readyqueue_duplicates(&self) -> Option<&VecDeque> { + pub fn _check_readyqueue_duplicates(&self) -> Option<&VecDeque> { let readyqueue = &self.readyqueue; // In _worst_ case where all elements are unique, the size of uniq will be same as len of readyqueue let mut uniq = HashSet::with_capacity(readyqueue.len()); diff --git a/rumqttd/src/server/broker.rs b/rumqttd/src/server/broker.rs index 9886541c9..8fddf4a54 100644 --- a/rumqttd/src/server/broker.rs +++ b/rumqttd/src/server/broker.rs @@ -38,6 +38,7 @@ use crate::link::local::{self, LinkRx, LinkTx}; use crate::router::{Event, Router}; use crate::{Config, ConnectionId, ServerSettings}; +use crate::link::remote::WebhookProperties; use tokio::net::{TcpListener, TcpStream}; use tokio::time::error::Elapsed; use tokio::{task, time}; @@ -151,7 +152,7 @@ impl Broker { // Register this connection with the router. Router replies with ack which if ok will // start the link. Router can sometimes reject the connection (ex. max connection limit). let (link_tx, link_rx, _ack) = - LinkBuilder::new(client_id, self.router_tx.clone()).build()?; + LinkBuilder::new(client_id, self.router_tx.clone(), None, None, None, None).build()?; Ok((link_tx, link_rx)) } @@ -194,8 +195,10 @@ impl Broker { let runtime = runtime.enable_all().build().unwrap(); runtime.block_on(async move { - if let Err(e) = bridge::start(bridge_config, router_tx, V4).await { - error!(error=?e, "Bridge Link error"); + if let Err(e) = + bridge::start(bridge_config, router_tx, V4, None, None, None, None).await + { + info!(error=?e, "Bridge Link error"); }; }); })?; @@ -212,7 +215,7 @@ impl Broker { runtime.block_on(async { if let Err(e) = server.start(LinkType::Remote).await { - error!(error=?e, "Server error - V4"); + info!(error=?e, "Server error - V4"); } }); })?; @@ -230,7 +233,7 @@ impl Broker { runtime.block_on(async { if let Err(e) = server.start(LinkType::Remote).await { - error!(error=?e, "Server error - V5"); + info!(error=?e, "Server error - V5"); } }); })?; @@ -255,7 +258,7 @@ impl Broker { runtime.block_on(async { if let Err(e) = server.start(LinkType::Websocket).await { - error!(error=?e, "Server error - WS"); + info!(error=?e, "Server error - WS"); } }); })?; @@ -307,7 +310,8 @@ impl Broker { } if let Some(console) = self.config.console.clone() { - let console_link = ConsoleLink::new(console, self.router_tx.clone()); + let console_link = + ConsoleLink::new(console, self.router_tx.clone(), None, None, None, None); let console_link = Arc::new(console_link); let console_thread = thread::Builder::new().name("Console".to_string()); @@ -395,7 +399,7 @@ impl Server

{ let (stream, addr) = match listener.accept().await { Ok((s, r)) => (s, r), Err(e) => { - error!(error=?e, "Unable to accept socket."); + info!(error=?e, "Unable to accept socket."); continue; } }; @@ -403,7 +407,7 @@ impl Server

{ let (network, tenant_id) = match self.tls_accept(stream).await { Ok(o) => o, Err(e) => { - error!(error=?e, "Tls accept error"); + info!(error=?e, "Tls accept error"); continue; } }; @@ -423,7 +427,7 @@ impl Server

{ let stream = match accept_hdr_async(network, WSCallback).await { Ok(s) => Box::new(WsStream::new(s)), Err(e) => { - error!(error=?e, "Websocket failed handshake"); + info!(error=?e, "Websocket failed handshake"); continue; } }; @@ -497,6 +501,9 @@ async fn remote( protocol: P, will_handlers: Arc>>>, ) { + let webhook_url = config.webhook_url.to_owned(); + let retained_url = config.retained_url.to_owned(); + let authorization_url = config.authorization_url.to_owned(); let mut network = Network::new( stream, config.max_payload_size, @@ -509,14 +516,14 @@ async fn remote( let connect_packet = match mqtt_connect(config, &mut network).await { Ok(p) => p, Err(e) => { - error!(error=?e, "Error while handling MQTT connect packet"); + info!(error=?e, "Error while handling MQTT connect packet"); return; } }; - - let (mut client_id, clean_session) = match &connect_packet { - Packet::Connect(ref connect, _, _, _, _) => { - (connect.client_id.clone(), connect.clean_session) + let (mut client_id, clean_session, username) = match &connect_packet { + Packet::Connect(ref connect, _, _, _, login) => { + let username = login.as_ref().map(|login| login.username.to_string()); + (connect.client_id.clone(), connect.clean_session, username) } _ => unreachable!(), }; @@ -558,12 +565,18 @@ async fn remote( connect_packet, dynamic_filters, assigned_client_id, + WebhookProperties { + username, + webhook_url, + retained_url, + authorization_url, + }, ) .await { Ok(l) => l, Err(e) => { - error!(error=?e, "Remote link error"); + info!(error=?e, "Remote link error"); return; } }; @@ -574,11 +587,11 @@ async fn remote( match link.start().await { // Connection got closed. This shouldn't usually happen. - Ok(_) => error!("connection-stop"), + Ok(_) => info!("connection-stop"), // No need to send a disconnect message when disconnection // originated internally in the router. Err(remote::Error::Link(e)) => { - error!(error=?e, "router-drop"); + info!(error=?e, "router-drop"); send_disconnect = false; } // Connection was closed by peer @@ -589,7 +602,7 @@ async fn remote( } // Any other error Err(e) => { - error!(error=?e, "disconnected"); + info!(error=?e, "disconnected"); } };