From edebf5f2648b329a4f0d6c3a8f8ce30bcf1d8e2b Mon Sep 17 00:00:00 2001 From: Dan Notestein <dan@syncad.com> Date: Sat, 10 Feb 2024 00:30:13 +0000 Subject: [PATCH] Add in new jussi-stype config file parsing, and make drone decode method names and find the right backend the same way jussi did --- Cargo.lock | 1072 +++++++++++++++++++++++------------------ Cargo.toml | 6 +- src/config.rs | 160 ++++++ src/main.rs | 475 +++++++++++------- src/method_renamer.rs | 167 +++++++ 5 files changed, 1221 insertions(+), 659 deletions(-) create mode 100644 src/config.rs create mode 100644 src/method_renamer.rs diff --git a/Cargo.lock b/Cargo.lock index 908e5ba..081ec71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,26 +4,26 @@ version = 3 [[package]] name = "actix-codec" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "bytes", "futures-core", "futures-sink", - "log", "memchr", "pin-project-lite", "tokio", "tokio-util", + "tracing", ] [[package]] name = "actix-cors" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b340e9cfa5b08690aae90fb61beb44e9b06f44fe3d0f93781aaa58cfba86245e" +checksum = "0346d8c1f762b41b458ed3145eea914966bb9ad20b9be0d6d463b20d45586370" dependencies = [ "actix-utils", "actix-web", @@ -36,17 +36,17 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.3.1" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2079246596c18b4a33e274ae10c0e50613f4d32a4198e09c7b93771013fed74" +checksum = "d223b13fd481fc0d1f83bb12659ae774d9e3601814c68a0bc539731698cca743" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", - "ahash 0.8.3", - "base64 0.21.0", - "bitflags 1.3.2", + "ahash 0.8.8", + "base64 0.21.7", + "bitflags 2.4.2", "brotli", "bytes", "bytestring", @@ -75,19 +75,19 @@ dependencies = [ [[package]] name = "actix-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "actix-router" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511" dependencies = [ "bytestring", "http", @@ -98,9 +98,9 @@ dependencies = [ [[package]] name = "actix-rt" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" +checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" dependencies = [ "futures-core", "tokio", @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" +checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" dependencies = [ "actix-rt", "actix-service", @@ -118,7 +118,6 @@ dependencies = [ "futures-core", "futures-util", "mio", - "num_cpus", "socket2", "tokio", "tracing", @@ -147,9 +146,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.3.1" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96" +checksum = "43a6556ddebb638c2358714d853257ed226ece6023ef9364f23f0c70737ea984" dependencies = [ "actix-codec", "actix-http", @@ -160,7 +159,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.7.6", + "ahash 0.8.8", "bytes", "bytestring", "cfg-if", @@ -169,7 +168,6 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "http", "itoa", "language-tags", "log", @@ -188,14 +186,23 @@ dependencies = [ [[package]] name = "actix-web-codegen" -version = "4.2.0" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2262160a7ae29e3415554a3f1fc04c764b1540c116aa524683208078b7a75bc9" +checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", ] [[package]] @@ -206,9 +213,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -217,21 +224,22 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -251,6 +259,12 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -273,9 +287,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.67" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ea188f25f0255d8f92797797c97ebf5631fa88178beb1a46fdf5622c9a00e4" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", @@ -288,6 +302,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -296,9 +325,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.0" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bitflags" @@ -323,9 +352,9 @@ dependencies = [ [[package]] name = "brotli" -version = "3.3.4" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -334,9 +363,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.4" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -344,9 +373,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" [[package]] name = "bytecount" @@ -356,15 +385,15 @@ checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "bytestring" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" dependencies = [ "bytes", ] @@ -380,9 +409,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -402,11 +431,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -417,32 +447,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ + "android-tzdata", "iana-time-zone", - "num-integer", + "js-sys", "num-traits", "serde", - "winapi", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", + "wasm-bindgen", + "windows-targets 0.52.0", ] [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "json5", @@ -476,9 +498,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -486,24 +508,24 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -542,55 +564,11 @@ dependencies = [ "typenum", ] -[[package]] -name = "cxx" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c00419335c41018365ddf7e4d5f1c12ee3659ddcf3e01974650ba1de73d038" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8307ad413a98fff033c8545ecf133e3257747b3bae935e7602aab8aa92d4ca" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.48", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc52e2eb08915cb12596d29d55f0b5384f00d697a646dbd269b6ecb0fbd9d31" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "darling" -version = "0.14.4" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "c376d08ea6aa96aafe61237c7200d1241cb177b7d3a542d791f2d118e9cbb955" dependencies = [ "darling_core", "darling_macro", @@ -598,27 +576,37 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "33043dcd19068b8192064c704b3f83eb464f91f1ff527b44a4e2b08d9cdb8855" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.48", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", ] [[package]] @@ -636,9 +624,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", @@ -657,44 +645,42 @@ dependencies = [ "actix-cors", "actix-web", "async-recursion", + "chrono", "config", + "futures-util", "humantime", - "lru_time_cache", "moka", "reqwest", + "sequence_trie", "serde", "serde_json", "serde_with", + "serde_yaml", ] [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] [[package]] -name = "errno" -version = "0.2.8" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "errno" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -708,18 +694,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -748,54 +731,66 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "futures-channel" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-io" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] [[package]] name = "futures-sink" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-io", + "futures-macro", "futures-task", "memchr", "pin-project-lite", @@ -805,9 +800,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -815,15 +810,21 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", "wasi", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "glob" version = "0.3.1" @@ -832,9 +833,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.19" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -842,7 +843,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 2.2.3", "slab", "tokio", "tokio-util", @@ -855,23 +856,20 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] -name = "hermit-abi" -version = "0.2.6" +name = "hashbrown" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" [[package]] name = "hex" @@ -881,9 +879,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -892,9 +890,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -909,9 +907,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -921,9 +919,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.25" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -958,26 +956,25 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows-core", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -988,9 +985,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -998,61 +995,51 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", "serde", ] [[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.8" +name = "indexmap" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd6da19f25979c7270e70fa95ab371ec3b701cd0eefc47667a09785b3c59155" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.45.0", + "equivalent", + "hashbrown 0.14.3", ] [[package]] name = "ipnet" -version = "2.7.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -1082,18 +1069,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" - -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "linked-hash-map" @@ -1103,33 +1081,32 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "local-channel" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" dependencies = [ "futures-core", "futures-sink", - "futures-util", "local-waker", ] [[package]] name = "local-waker" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1137,30 +1114,21 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "lru_time_cache" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9106e1d747ffd48e6be5bb2d97fa706ed25b144fbee4d5c02eae110cd8d6badd" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minimal-lexical" @@ -1170,23 +1138,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1239,47 +1207,52 @@ dependencies = [ ] [[package]] -name = "num-integer" -version = "0.1.45" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.17.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.54" +version = "0.10.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -1290,13 +1263,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1307,9 +1280,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.88" +version = "0.9.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" dependencies = [ "cc", "libc", @@ -1324,7 +1297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" dependencies = [ "dlv-list", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -1339,22 +1312,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.45.0", + "windows-targets 0.48.5", ] [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pathdiff" @@ -1364,25 +1337,26 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.5.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cbd939b234e95d72bc393d51788aec68aeeb5d51e748ca08ff3aad58cb722f7" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.5.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a81186863f3d0a27340815be8f2078dd8050b14cd71913db9fbda795e5f707d7" +checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" dependencies = [ "pest", "pest_generator", @@ -1390,22 +1364,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a1ef20bf3193c15ac345acb32e26b3dc3223aff4d77ae4fc5359567683796b" +checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "pest_meta" -version = "2.5.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e3b284b1f13a20dc5ebc90aff59a51b8d7137c221131b52a7260c08cbc1cc80" +checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" dependencies = [ "once_cell", "pest", @@ -1414,9 +1388,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1426,9 +1400,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -1521,18 +1501,30 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.7.1" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -1541,17 +1533,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.14" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ - "base64 0.21.0", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -1569,9 +1561,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -1603,6 +1598,12 @@ dependencies = [ "ordered-multimap", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.4.0" @@ -1614,23 +1615,31 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.10" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe885c3a125aa45213b68cc1472a49880cb5923dc23f522ad2791b882228778" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.45.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", ] [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -1643,30 +1652,24 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.52.0", ] [[package]] name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scratch" -version = "1.0.5" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -1677,9 +1680,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -1687,13 +1690,19 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" dependencies = [ "serde", ] +[[package]] +name = "sequence_trie" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee22067b7ccd072eeb64454b9c6e1b33b61cd0d49e895fd48676a184580e0c3" + [[package]] name = "serde" version = "1.0.196" @@ -1716,9 +1725,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -1739,14 +1748,14 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85456ffac572dc8826334164f2fb6fb40a7c766aebe195a2a21ee69ee2885ecf" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" dependencies = [ "base64 0.13.1", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", "serde", "serde_json", "serde_with_macros", @@ -1755,21 +1764,33 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cbcd6104f8a4ab6af7f6be2a0da6be86b9de3c401f6e86bb856ab2af739232f" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", +] + +[[package]] +name = "serde_yaml" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +dependencies = [ + "indexmap 1.9.3", + "ryu", + "serde", + "yaml-rust", ] [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -1778,9 +1799,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -1813,27 +1834,27 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -1864,6 +1885,33 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tagptr" version = "0.2.0" @@ -1872,40 +1920,30 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.4.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", - "windows-sys 0.42.0", -] - -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", + "windows-sys 0.52.0", ] [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", @@ -1914,11 +1952,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ + "deranged", "itoa", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -1926,16 +1967,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -1956,21 +1998,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.26.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1985,9 +2026,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -2014,11 +2055,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-core", @@ -2026,9 +2066,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -2041,21 +2081,21 @@ checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicase" @@ -2068,15 +2108,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.12" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d502c968c6a838ead8e69b2ee18ec708802f99db92a0d156705ec9ef801993b" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -2087,17 +2127,11 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - [[package]] name = "url" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -2137,11 +2171,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -2153,9 +2186,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2163,24 +2196,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -2190,9 +2223,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2200,28 +2233,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", @@ -2245,9 +2278,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -2258,94 +2291,155 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-targets 0.48.5", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] @@ -2357,32 +2451,50 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "zstd" -version = "0.12.3+zstd.1.5.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" +checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "6.0.4+zstd.1.5.4" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543" +checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" dependencies = [ - "libc", "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.7+zstd.1.5.4" +version = "2.0.9+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index 7e2e21f..52a25c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,13 @@ actix-web = "4.3.1" reqwest = { version = "0.11.14", features = ["blocking", "json"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.94" +serde_with = "2.3.1" +serde_yaml = "0.8" humantime = "2.1.0" config = "0.13.3" -serde_with = "2.3.1" actix-cors = "0.6.4" async-recursion = "1.0.5" moka = { version = "0.12.5", features = ["sync"] } +sequence_trie = "0.3.6" +futures-util = "0.3.30" +chrono = "0.4.34" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..53a1b82 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,160 @@ +use std::collections::{HashMap, HashSet}; +use sequence_trie::SequenceTrie; +use serde::{Deserialize}; +use std::fs; + + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum TtlValue { + /// Never cache the response + NoCache, + /// Cache the response forever + NoExpire, + /// If irreversible, cache forever. Otherwise, cache for 9 seconds + ExpireIfReversible, + /// Expect the upstream server to tell us how long to cache via a `Cache-Control: max-age=` HTTP header + HonorUpstreamCacheControl, + /// Cache response for a fixed amount of time + DurationInSeconds(u32) +} + +#[derive(Clone, Deserialize, Debug)] +#[serde()] +pub struct DroneConfig { + /// the port to listen on + pub port: u16, + /// the endpoint (usually an IP like 0.0.0.0, but can be a hostname if you're weird) + pub hostname: String, + + //cache_initial_capacity: Option<u64>, // <- not sure we have any use for this + /// initial cache capacity, roughly the max size in bytes + pub cache_max_capacity: u64, + + /// String used to identify this software, returned in the response for / and /health endpoints + pub operator_message: String, + + /// number of threads used for connections between drone and the backends + pub middleware_connection_threads: usize, +} + + +/// AppConfig holds the parsed, ready-to-use configuration +#[derive(Debug, Clone)] +pub struct AppConfig { + pub drone: DroneConfig, + backends: HashMap<String, String>, + pub translate_to_appbase: HashSet<String>, + pub urls: SequenceTrie<String, String>, + pub ttls: SequenceTrie<String, TtlValue>, + pub timeouts: SequenceTrie<String, u32>, + pub equivalent_methods: HashMap<String, String>, +} + +impl AppConfig { + pub fn lookup_url(&self, method_name_parts: Vec<&String>) -> Option<&String> { + self.urls.get_ancestor(method_name_parts) + } + pub fn lookup_ttl(&self, method_name_parts: Vec<&String>) -> Option<&TtlValue> { + self.ttls.get_ancestor(method_name_parts) + } + pub fn lookup_timeout(&self, method_name_parts: Vec<&String>) -> Option<&u32> { + self.timeouts.get_ancestor(method_name_parts) + } + pub fn lookup_equivalent_method(&self, original_method_name: String) -> String { + match self.equivalent_methods.get(&original_method_name) { + Some(replacement_method_name) => { replacement_method_name.clone() } + None => { original_method_name } + } + } +} + +/// TtlValue enum split into two to make serde read it correctly +#[derive(Debug, Deserialize, Clone)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +enum YamlSpecialTtlValue { + NoCache, + NoExpire, + ExpireIfReversible, + HonorUpstreamCacheControl, +} + +#[derive(Debug, Deserialize, Clone)] +#[serde(untagged)] +enum YamlTtlValue { + SpecialValue(YamlSpecialTtlValue), + DurationInSeconds(u32) +} + +/// and a helper function to hide the ugliness +fn ttl_value_from_yaml(ttl: &YamlTtlValue) -> TtlValue { + match ttl { + YamlTtlValue::SpecialValue(YamlSpecialTtlValue::NoCache) => { TtlValue::NoCache } + YamlTtlValue::SpecialValue(YamlSpecialTtlValue::NoExpire) => { TtlValue::NoExpire } + YamlTtlValue::SpecialValue(YamlSpecialTtlValue::ExpireIfReversible) => { TtlValue::ExpireIfReversible } + YamlTtlValue::SpecialValue(YamlSpecialTtlValue::HonorUpstreamCacheControl) => { TtlValue::HonorUpstreamCacheControl } + YamlTtlValue::DurationInSeconds(n) => { TtlValue::DurationInSeconds(*n) } + } +} + +/// The config file format directly loaded from file +#[derive(Debug, Deserialize)] +struct YamlConfig { + drone: DroneConfig, + backends: HashMap<String, String>, + translate_to_appbase: Vec<String>, + urls: HashMap<String, String>, + ttls: HashMap<String, YamlTtlValue>, + timeouts: HashMap<String, u32>, + equivalent_methods: HashMap<String, Vec<String>>, +} + +pub fn parse_file(filename: &str) -> AppConfig { + // Parse the YAML into a temporary structure + let yaml_string = fs::read_to_string(filename) + .expect("Unable to read file"); + + let config: YamlConfig = serde_yaml::from_str(&yaml_string) + .expect("Unable to parse YAML"); + + // Then move the data into our AppConfig, into a format that's easier to use at runtime + let mut app_config = AppConfig { + drone: DroneConfig{port: 80, hostname: "0.0.0.0".to_string(), cache_max_capacity: 4 << 30, operator_message: "Drone by Deathwing".to_string(), middleware_connection_threads: 8}, + backends: HashMap::new(), + translate_to_appbase: HashSet::new(), + urls: SequenceTrie::new(), + ttls: SequenceTrie::new(), + timeouts: SequenceTrie::new(), + equivalent_methods: HashMap::new() + }; + + app_config.drone = config.drone; + // copy the backends in to our AppConfig. We don't have any immediate use for them now + for (backend, url) in config.backends { + app_config.backends.insert(backend, url); + } + for namespace in config.translate_to_appbase { + app_config.translate_to_appbase.insert(namespace); + } + + // move the urls, resolving the backend names into urls as we go + for (method, backend_name) in config.urls { + let parts: Vec<String> = method.split('.').map(|v| v.to_string()).collect(); + let url = app_config.backends.get(&backend_name).unwrap_or_else(|| panic!("Undefined backend \"{}\" for method \"{}\"", backend_name, method)); + app_config.urls.insert_owned(parts, url.clone()); + } + for (method, ttl) in config.ttls { + let parts: Vec<String> = method.split('.').map(|v| v.to_string()).collect(); + app_config.ttls.insert_owned(parts, ttl_value_from_yaml(&ttl)); + } + for (method, timeout) in config.timeouts { + let parts: Vec<String> = method.split('.').map(|v| v.to_string()).collect(); + app_config.timeouts.insert_owned(parts, timeout); + } + // flip the equivalent_methods around so we can do a direct source -> target lookup + for (target_method, source_methods) in config.equivalent_methods { + for source_method in source_methods { + app_config.equivalent_methods.insert(source_method, target_method.clone()); + } + } + app_config +} diff --git a/src/main.rs b/src/main.rs index b8d2d91..2c2ce88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,33 @@ use actix_cors::Cors; use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder}; -use async_recursion::async_recursion; -use config::Config; -use moka::sync::Cache; +use moka::{sync::Cache, Expiry}; use reqwest::{Client, ClientBuilder}; use serde::{Deserialize, Serialize, Serializer}; use serde_json::Value; -use serde_with::{serde_as, DurationSeconds}; -use std::{sync::Mutex, time::Duration, fmt::Display}; +use std::sync::{Mutex}; +use std::time::{Duration, Instant, SystemTime}; +use std::collections::{HashMap}; +use std::sync::atomic::{self, AtomicU32}; +use actix_web::rt::time::sleep; +use futures_util::future::{FutureExt, Future,Shared}; +use std::pin::Pin; +use std::sync::OnceLock; +use chrono::DateTime; + + + +pub mod config; +use config::{AppConfig, TtlValue}; + +pub mod method_renamer; +use method_renamer::MethodAndParams; const DRONE_VERSION: &str = env!("CARGO_PKG_VERSION"); -// Drone Cacheable Methods -const DRONE_CACHEABLE_METHODS: [&str; 7] = [ - "block_api.get_block", - "condenser_api.get_block", - "account_history_api.get_transaction", - "condenser_api.get_transaction", - "condenser_api.get_ops_in_block", - "condenser_api.get_block_range", - "block_api.get_block_range", -]; +// TODO: fix these, shouldn't be static globals +static last_irreversible_block_number: AtomicU32 = AtomicU32::new(0); +static current_head_block_number: AtomicU32 = AtomicU32::new(0); + #[derive(Serialize, Deserialize, Debug)] struct HealthCheck { @@ -35,7 +42,7 @@ async fn index(appdata: web::Data<AppData>) -> impl Responder { HttpResponse::Ok().json(HealthCheck { status: "OK".to_string(), drone_version: DRONE_VERSION.to_string(), - message: appdata.config.operator_message.to_string(), + message: appdata.config.drone.operator_message.to_string(), }) } @@ -58,7 +65,7 @@ enum ID { // Structure for API calls. #[derive(Serialize, Deserialize, Debug)] -struct APIRequest { +pub struct APIRequest { jsonrpc: String, id: ID, method: String, @@ -66,7 +73,7 @@ struct APIRequest { params: Option<Value>, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] enum ErrorField { Object(Value), // JSON from Hived Message(String), // Custom message @@ -85,7 +92,7 @@ impl Serialize for ErrorField { } // Structure for the error response. -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] struct ErrorStructure { jsonrpc: String, id: ID, @@ -94,154 +101,118 @@ struct ErrorStructure { error: ErrorField, } -// Enum for the endpoints. -enum Endpoints { - HAF, - HAFAH, - HIVEMIND, -} - +#[derive(Clone)] struct APICallResponse { + /// the original value of jsonrpc request made by the caller (usually "2.0") jsonrpc: String, result: Value, + /// the id the caller used in their request id: ID, + // data returned just for logging/debugging cached: bool, + mapped_method: MethodAndParams, // the method, parsed and transformed + backend_url: Option<String>, + upstream_method: Option<String> } -// Choose the endpoint depending on the method. -impl Endpoints { - fn choose_endpoint<'a>(&self, appdata: &'a web::Data<AppData>) -> &'a str { - match self { - Endpoints::HAF => appdata.config.haf_endpoint.as_str(), - Endpoints::HAFAH => appdata.config.hafah_endpoint.as_str(), - Endpoints::HIVEMIND => appdata.config.hivemind_endpoint.as_str(), - } +#[derive(Clone, Debug)] +struct CacheEntry { + result: Value, + size: u32, + ttl: TtlValue +} + +pub struct MyExpiry; + +impl Expiry<String, CacheEntry> for MyExpiry { + /// Returns the duration of the expiration of the value that was just + /// created. + fn expire_after_create(&self, key: &String, value: &CacheEntry, _current_time: Instant) -> Option<Duration> { + match value.ttl { + TtlValue::NoExpire => { None } + TtlValue::DurationInSeconds(s) => { + println!("MyExpiry: expire_after_create called with key {key}, returning duration {s}."); + Some(Duration::from_secs(s as u64)) + } + _ => { + println!("MyExpiry: expire_after_create called with key {key} that doesn't have a duration in seconds, this is unexpected."); + None + } + } } } -impl Display for Endpoints { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Endpoints::HAF => write!(f, " Endpoint: HAF"), - Endpoints::HAFAH => write!(f, " Endpoint: HAFAH"), - Endpoints::HIVEMIND => write!(f, " Endpoint: HIVEMIND"), - } +fn get_block_number_from_result(result: &Value) -> Option<u32> { + // appbase get_block + if let Some(block_num) = result.pointer("/block/block_id").and_then(|block_id| block_id.as_str()).and_then(|id_str| u32::from_str_radix(&id_str[..8], 16).ok()) { + return Some(block_num); + } + // appbase get_block_header + if let Some(prev_block_num) = result.pointer("/header/previous").and_then(|block_id| block_id.as_str()).and_then(|id_str| u32::from_str_radix(&id_str[..8], 16).ok()) { + return Some(prev_block_num + 1); } + // hived get_block + if let Some(block_num) = result.pointer("/block_id").and_then(|block_id| block_id.as_str()).and_then(|id_str| u32::from_str_radix(&id_str[..8], 16).ok()) { + return Some(block_num); + } + // hived get_block_header + if let Some(prev_block_num) = result.pointer("/previous").and_then(|block_id| block_id.as_str()).and_then(|id_str| u32::from_str_radix(&id_str[..8], 16).ok()) { + return Some(prev_block_num + 1); + } + + None } -#[async_recursion] -async fn handle_request( - request: &APIRequest, - data: &web::Data<AppData>, - client_ip: &String, -) -> Result<APICallResponse, ErrorStructure> { - // Convert the call to a struct. - let client = data.webclient.clone(); - let method = request.method.as_str(); - - if method == "call" { - if let Some(params) = request.params.as_ref().and_then(Value::as_array) { - if params.len() > 2 { - if let Some(method) = params[0].as_str() { - let format_new_method = format!("{}.{}", method, params[1].as_str().unwrap()); - let new_params = params[2].clone(); - let new_request = APIRequest { - jsonrpc: "2.0".to_string(), - id: request.id.clone(), - method: format_new_method, - params: Some(new_params), - }; - return handle_request(&new_request, data, client_ip).await; - } +// check a request to see if it's asking for a block that doesn't exist yet. We get a lot of API +// calls that do this, presumably clients that are just polling for the next block. +// This is a case we can optimize. Either by: +// - returning a stock error reply, without contacting the upstream, or +// - if the block is expected to arrive in a few seconds, just wait. once the bloc arrives, return it +// Waiting seems better +fn check_for_future_block_requests(mapped_method: &MethodAndParams) { + if mapped_method.method == "get_block" { + if let Some(block_num) = mapped_method.params.as_ref().and_then(|v| v["block_num"].as_u64()) { + if block_num as u32 > current_head_block_number.load(atomic::Ordering::Acquire) { + // we're only testing against the head block number we recorded the last + // time someone called get_dynamic_global_properties. + // we should also check that now() is < the predicted time the requested + // block will be produced + println!("future block requested: {block_num}, head is {}", current_head_block_number.load(atomic::Ordering::Acquire)); } } } +} - // Get humantime for logging. - let human_timestamp = humantime::format_rfc3339_seconds(std::time::SystemTime::now()); - let formatted_log = if let Some(params) = &request.params { - format!( - "Timestamp: {} || IP: {} || Request Method: {} || Request Params: {}", - human_timestamp, client_ip, request.method, params, - ) - } else { - format!( - "Timestamp: {} || IP: {} || Request Method: {}", - human_timestamp, client_ip, request.method, - ) - }; - println!("{}", formatted_log); - - - // Pick the endpoints depending on the method. - let endpoints = match method { - // HAF - "condenser_api.get_block" => Endpoints::HAF, - "block_api.get_block_range" => Endpoints::HAF, - "condenser_api.get_block_range" => Endpoints::HAF, - // HAFAH - _ if method.starts_with("account_history_api.") => Endpoints::HAFAH, - "condenser_api.get_ops_in_block" => Endpoints::HAFAH, - "condenser_api.get_transaction" => Endpoints::HAFAH, - "condenser_api.get_account_history" => Endpoints::HAFAH, - "database_api.get_account_history" => Endpoints::HAFAH, - // HIVEMIND - _hive_endpoint if method.starts_with("hive.") => Endpoints::HIVEMIND, - "condenser_api.get_content_replies" => Endpoints::HIVEMIND, - "condenser_api.get_account_votes" => Endpoints::HIVEMIND, - "condenser_api.get_followers" => Endpoints::HIVEMIND, - "condenser_api.get_following" => Endpoints::HIVEMIND, - "condenser_api.get_follow_count" => Endpoints::HIVEMIND, - "condenser_api.get_blog" => Endpoints::HIVEMIND, - "condenser_api.get_content" => Endpoints::HIVEMIND, - "condenser_api.get_blog_entries" => Endpoints::HIVEMIND, - "condenser_api.get_active_votes" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_trending" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_hot" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_promoted" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_created" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_blog" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_feed" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_comments" => Endpoints::HIVEMIND, - "condenser_api.get_discussions_by_author_before_date" => Endpoints::HIVEMIND, - "condenser_api.get_state" => Endpoints::HIVEMIND, - "condenser_api.get_trending_tags" => Endpoints::HIVEMIND, - "condenser_api.get_post_discussions_by_payout" => Endpoints::HIVEMIND, - "condenser_api.get_comment_discussions_by_payout" => Endpoints::HIVEMIND, - "condenser_api.get_replies_by_last_update" => Endpoints::HIVEMIND, - "condenser_api.get_reblogged_by" => Endpoints::HIVEMIND, - "database_api.find_comments" => Endpoints::HIVEMIND, - _bridge_endpoint if method.starts_with("bridge.") => Endpoints::HIVEMIND, - _follow_api_endpoint if method.starts_with("follow_api.") => Endpoints::HIVEMIND, // Remove when beem is updated. (Deprecated) - _tags_api_endpoint if method.starts_with("tags_api.") => Endpoints::HIVEMIND, // Remove when beem is updated. (Deprecated) - _anything_else => Endpoints::HAF, +async fn request_from_upstream(request: APIRequest, data: web::Data<AppData>, mapped_method: MethodAndParams, method_and_params_str: String) -> Result<APICallResponse, ErrorStructure> { + let endpoint = match data.config.lookup_url(mapped_method.get_method_name_parts()) { + Some(endpoint) => { endpoint } + None => { + return Err(ErrorStructure { + jsonrpc: request.jsonrpc.clone(), + id : request.id.clone(), + code: -32700, + message: format!("Unable to map request to endpoint."), + error: ErrorField::Message("Unable to map request to endpoint.".to_string()), + }); + } }; - // Check if the call is in the cache. If it is, return only the result while keeping the rest of the response the same. - let params_str = request.params.as_ref().map_or("[]".to_string(), |v: &Value| v.to_string()); - if let Some(cached_call) = data.cache.get(¶ms_str) { - // build result with data from cache and response - let result = cached_call.clone(); - return Ok(APICallResponse { - jsonrpc: request.jsonrpc.clone(), - result: result["result"].clone(), - id: request.id.clone(), - cached: true, - }); - } + let upstream_request = mapped_method.format_for_upstream(&data.config); + println!("Making upstream request using method {:?} and params {:?}", upstream_request.method, upstream_request.params); + let client = data.webclient.clone(); // Send the request to the endpoints. let res = match client - .post(endpoints.choose_endpoint(&data)) - .json(&request) + .post(endpoint) + .json(&upstream_request) .send() .await { Ok(response) => response, Err(err) => { let mut error_message = err.without_url().to_string(); - error_message.push_str(&endpoints.to_string()); + error_message.push_str(&endpoint.to_string()); return Err(ErrorStructure { jsonrpc: request.jsonrpc.clone(), id : request.id.clone(), @@ -251,6 +222,10 @@ async fn handle_request( }) } }; + + // to simulate slow calls, put a sleep here + // sleep(Duration::from_secs(10)).await; + let body = match res.text().await { Ok(text) => text, Err(err) => { @@ -284,27 +259,159 @@ async fn handle_request( error: ErrorField::Object(json_body["error"].clone()), }); } - let mut cacheable = true; + + // if the call was to get_dynamic_global_properties, save off the last irreversible block + println!("Mapped method is {}", mapped_method.method); + if mapped_method.method == "get_dynamic_global_properties" { + println!("This method was get_dynamic_global_properties"); + if let Some(new_lib) = json_body["result"]["last_irreversible_block_num"].as_u64() { + if new_lib as u32 > last_irreversible_block_number.load(atomic::Ordering::Acquire) { + println!("new LIB is {new_lib}"); + last_irreversible_block_number.store(new_lib as u32, atomic::Ordering::Release); + } + } + if let Some(new_head) = json_body["result"]["head_block_number"].as_u64() { + if new_head as u32 > current_head_block_number.load(atomic::Ordering::Acquire) { + println!("new head is {new_head}"); + current_head_block_number.store(new_head as u32, atomic::Ordering::Release); + if let Some(new_time) = json_body["result"]["time"].as_str() { + let current_head_block_time = DateTime::parse_from_rfc3339(&format!("{new_time}Z")).unwrap(); + let systemtime = SystemTime::from(current_head_block_time); + println!("Parsed datetime to {:?}, as systemtime: {:?}", current_head_block_time, systemtime); + } + } + } + } + + if json_body["result"].is_array() && json_body["result"].as_array().unwrap().is_empty() || json_body["result"].is_null() - || json_body["result"]["blocks"].is_array() - && json_body["result"]["blocks"].as_array().unwrap().is_empty() + || json_body["result"]["blocks"].is_array() && json_body["result"]["blocks"].as_array().unwrap().is_empty() { - cacheable = false; + // then this result shouldn't be cached + // TODO: why? } - - if DRONE_CACHEABLE_METHODS.contains(&request.method.as_str()) && cacheable { - let params_str = request.params.as_ref().map_or("[]".to_string(), |v| v.to_string()); - data.cache.insert(params_str, json_body.clone()); + else + { + let mut ttl = *data.config.lookup_ttl(mapped_method.get_method_name_parts()).unwrap_or(&TtlValue::NoCache); + println!("Method lookup_ttl returns {ttl:?}"); + + if ttl == TtlValue::ExpireIfReversible { + // we cache forever if the block is irreversible, or 9 seconds if it's reversible + if let Some(block_number) = get_block_number_from_result(&json_body["result"]) { + ttl = if block_number > last_irreversible_block_number.load(atomic::Ordering::Acquire) { TtlValue::DurationInSeconds(9) } else { TtlValue::NoExpire }; + println!("block number from result is {block_number}, lib is {}, setting ttl to {:?}", last_irreversible_block_number.load(atomic::Ordering::Acquire), ttl); + } + } + match ttl { + TtlValue::NoExpire | TtlValue::DurationInSeconds(_) => { + let entry = CacheEntry { + result: json_body["result"].clone(), + size: body.len() as u32, + ttl + }; + data.cache.insert(method_and_params_str, entry); + } + _ => {} + } } + Ok(APICallResponse { jsonrpc: request.jsonrpc.clone(), result: json_body["result"].clone(), id: request.id.clone(), cached: false, + mapped_method, + backend_url: Some(endpoint.clone()), + upstream_method: Some(upstream_request.method.clone()) }) } +async fn handle_request(request: APIRequest, data: &web::Data<AppData>, client_ip: &String) -> Result<APICallResponse, ErrorStructure> { + // perform any requested mappings, this may give us different method names & and params + let mapped_method = match method_renamer::map_method_name(&data.config, &request.method, &request.params) { + Ok(mapped_method) => { mapped_method } + Err(_) => { + return Err(ErrorStructure { + jsonrpc: request.jsonrpc.clone(), + id : request.id.clone(), + code: -32700, + message: format!("Unable to parse request method."), + error: ErrorField::Message("Unable to parse request method.".to_string()), + }); + } + }; + + check_for_future_block_requests(&mapped_method); + + // Get humantime for logging. + let human_timestamp = humantime::format_rfc3339_seconds(std::time::SystemTime::now()); + let formatted_log = if let Some(params) = &request.params { + format!( + "Timestamp: {} || IP: {} || Request Method: {} || Request Params: {}", + human_timestamp, client_ip, request.method, params, + ) + } else { + format!( + "Timestamp: {} || IP: {} || Request Method: {}", + human_timestamp, client_ip, request.method, + ) + }; + println!("{}", formatted_log); + + // Check if the call is in the cache. If it is, return it + let params_str = request.params.as_ref().map_or("[]".to_string(), |v: &Value| v.to_string()); + let method_and_params_str = format!("{}({params_str})", mapped_method.method); + println!("Using cache key {method_and_params_str}"); + if let Some(cached_call) = data.cache.get(&method_and_params_str) { + println!("Cache hit"); + return Ok(APICallResponse { + jsonrpc: request.jsonrpc.clone(), + result: cached_call.result.clone(), + id: request.id, + cached: true, + mapped_method, + backend_url: None, + upstream_method: None + }); + } + println!("Cache miss"); + + // Check and see if another thread is currently handling this call. If it is, join them + let in_progress_call: InProgressCall; + let first_caller: bool; + { + let mut in_progress = in_progress_call_registry().lock().unwrap(); + in_progress_call = if let Some(value) = in_progress.get_mut(&method_and_params_str) { + first_caller = false; + value.call_count += 1; + value.clone() + } else { + first_caller = true; + let upstream_request_record = InProgressCall { + future: request_from_upstream(request, data.clone(), mapped_method, method_and_params_str.clone()).boxed().shared(), + call_count: 1, + first_call_start_time: Instant::now() + }; + in_progress.insert(method_and_params_str.clone(), upstream_request_record.clone()); + upstream_request_record + } + } + if !first_caller { + println!("Multiple calls in progress: {method_and_params_str}: {}", in_progress_call.call_count); + } + + let upstream_response = in_progress_call.future.await; + + // one caller needs to remove the entry from the registry when the upstream call has completed. + // It doesn't matter who does it, so we arbitrarily decide to make it the first caller. + if first_caller { + in_progress_call_registry().lock().unwrap().remove(&method_and_params_str); + } + + upstream_response +} + async fn api_call( req: HttpRequest, call: web::Json<APICall>, @@ -331,11 +438,17 @@ async fn api_call( match call.0 { APICall::Single(request) => { - let result = handle_request(&request, &data, &user_ip).await; + let result = handle_request(request, &data, &user_ip).await; match result { Ok(response) => HttpResponse::Ok() .insert_header(("Drone-Version", DRONE_VERSION)) - .insert_header(("Cache-Status", response.cached.to_string())) + .insert_header(("X-Jussi-Cache-Hit", response.cached.to_string())) + .insert_header(("X-Jussi-Namespace", response.mapped_method.namespace)) + .insert_header(("X-Jussi-Api", response.mapped_method.api.unwrap_or("<Empty>".to_string()))) + .insert_header(("X-Jussi-Method", response.mapped_method.method)) + .insert_header(("X-Jussi-Params", response.mapped_method.params.map_or("[]".to_string(), |v| v.to_string()))) + .insert_header(("X-Jussi-Backend-Url", response.backend_url.unwrap_or("".to_string()))) + .insert_header(("X-Jussi-Upstream-Method", response.upstream_method.unwrap_or("".to_string()))) .json(serde_json::json!({ "jsonrpc": response.jsonrpc, "result": response.result, @@ -359,7 +472,7 @@ async fn api_call( } for request in requests { - let result = handle_request(&request, &data, &user_ip).await; + let result = handle_request(request, &data, &user_ip).await; match result { Ok(response) => responses.push(response), Err(err) => return HttpResponse::InternalServerError().json(err), @@ -368,7 +481,7 @@ async fn api_call( let mut cached = true; let mut result = Vec::new(); for response in responses { - if response.cached == false { + if !response.cached { cached = false; } result.push(serde_json::json!({ @@ -385,51 +498,57 @@ async fn api_call( } } +#[derive(Clone)] +struct InProgressCall { + future: Shared<Pin<Box<dyn Future<Output = Result<APICallResponse, ErrorStructure>> + Send>>>, + /// the rest of this data structure is just info we track for debugging/logging, + /// we could omit them and Drone would work the same + call_count: u32, + first_call_start_time: Instant, +} + struct AppData { - cache: Cache<String, Value>, + cache: Cache<String, CacheEntry>, webclient: Client, - config: DroneConfig, + config: AppConfig, } -#[serde_as] -#[derive(Clone, Deserialize, Debug)] -#[serde(rename_all = "UPPERCASE")] -struct DroneConfig { - port: u16, - hostname: String, - #[serde_as(as = "DurationSeconds<u64>")] - cache_ttl: Duration, - cache_count: u64, - operator_message: String, - haf_endpoint: String, - hafah_endpoint: String, - hivemind_endpoint: String, - middleware_connection_threads: usize, +/// Singleton registry that holds futures for all currently-in-progress calls to the upstream servers, +/// indexed by method name and parameters +fn in_progress_call_registry() -> &'static Mutex<HashMap<String, InProgressCall>> { + static INSTANCE: OnceLock<Mutex<HashMap<String, InProgressCall>>> = OnceLock::new(); + INSTANCE.get_or_init(|| Mutex::new(HashMap::new())) } #[actix_web::main] async fn main() -> std::io::Result<()> { // Load config. - let config = Config::builder() - .add_source(config::File::with_name("config.json")) - .build() - .expect("Could not load config.json") - .try_deserialize::<DroneConfig>() - .expect("config.json is not in a valid format."); + let app_config = config::parse_file("config.yaml"); + + // helpers for the cach + let expiry = MyExpiry; + let eviction_listener = |key, _value, cause| { + println!("Evicted key {key}. Cause: {cause:?}"); + }; + let weigher = |_key: &String, value: &CacheEntry| -> u32 { + value.size + }; // Create the cache. let _cache = web::Data::new(AppData { cache: Cache::builder() - .max_capacity(config.cache_count) - .time_to_live(config.cache_ttl) + .max_capacity(app_config.drone.cache_max_capacity) + .expire_after(expiry) + .eviction_listener(eviction_listener) + .weigher(weigher) .build(), webclient: ClientBuilder::new() - .pool_max_idle_per_host(config.middleware_connection_threads) + .pool_max_idle_per_host(app_config.drone.middleware_connection_threads) .build() .unwrap(), - config: config.clone(), + config: app_config.clone(), }); - println!("Drone is running on port {}.", config.port); + println!("Drone is running on port {}.", app_config.drone.port); HttpServer::new(move || { let cors = Cors::permissive(); App::new() @@ -445,7 +564,7 @@ async fn main() -> std::io::Result<()> { .route("/", web::post().to(api_call)) .route("/health", web::get().to(index)) }) - .bind((config.hostname, config.port))? + .bind((app_config.drone.hostname, app_config.drone.port))? .run() .await } diff --git a/src/method_renamer.rs b/src/method_renamer.rs new file mode 100644 index 0000000..ee0a996 --- /dev/null +++ b/src/method_renamer.rs @@ -0,0 +1,167 @@ +use serde_json::{Value}; +use serde_json::json; + + +use super::config::AppConfig; +use super::APIRequest; + +#[derive(Clone, Debug)] +pub struct MethodAndParams { + pub namespace: String, + pub api: Option<String>, + pub method: String, + pub params: Option<Value> +} + +impl MethodAndParams { + /// get [namespace, api, method], or just [namespace, method] if no API + // this is the format used to lookup methods in tries + pub fn get_method_name_parts(&self) -> Vec<&String> { + match &self.api { + Some(api) => { vec![&self.namespace, &api, &self.method] } + None => { vec![&self.namespace, &self.method] } + } + } + + /// same as get_method_name_parts, but as a dotted string + // this is the format our equivalent_method map uses + pub fn get_dotted_method_name(&self) -> String { + match &self.api { + Some(api) => { [self.namespace.as_str(), api.as_str(), self.method.as_str()].join(".") } + None => { [self.namespace.as_str(), self.method.as_str()].join(".") } + } + } + + /// gets the request to pass to the upstream + pub fn format_for_upstream(&self, _app_config: &AppConfig) -> APIRequest { + // app_config isn't currently used, but we could use it if we want to, say, + // send all translate_to_appbase calls using the "call" syntax + APIRequest { + id: 1, + jsonrpc: "2.0".to_string(), + method: self.api.as_ref().map_or("".to_string(), |api| api.clone() + ".") + &self.method, + params: self.params.clone() + } + } +} + +fn decode_api_if_numeric(api: &Value) -> Result<String, String> { + if let Some(number) = api.as_i64() { + match number { + 0 => { Ok("database_api".to_string()) } + 1 => { Ok("login_api".to_string()) } + _ => { Err("Invalid API number".to_string()) } + } + } else { + match api.as_str() { + Some(api_string) => { Ok(api_string.to_string()) } + None => { Err("Invalid API".to_string()) } + } + } +} + +fn parse_call(params: &Option<Value>) -> Result<MethodAndParams, String> { + match params.as_ref().and_then(Value::as_array).map(Vec::as_slice) { + Some([api, method]) => { + Ok(MethodAndParams { + namespace: "appbase".to_string(), + api: Some(decode_api_if_numeric(api)?), + method: method.as_str().ok_or("Invalid method name".to_string())?.to_string(), + params: None + }) + } + Some([api, method, actual_params]) => { + Ok(MethodAndParams { + namespace: if api == "condenser_api" || api == "jsonrpc" || actual_params.is_object() { "appbase".to_string() } else { "hived".to_string() }, + api: Some(decode_api_if_numeric(api)?), + method: method.as_str().ok_or("Invalid method name".to_string())?.to_string(), + params: Some(actual_params.clone()) + }) + } + _ => { + Err("error".to_string()) + } + } +} + +fn convert_method_name(method: &str, params: &Option<Value>) -> Result<MethodAndParams, String> { + let parts: Vec<&str> = method.split('.').collect(); + match &parts[..] { + ["call"] => { + parse_call(params) + } + [bare_method] => { + Ok(MethodAndParams { + namespace: "hived".to_string(), + api: Some("database_api".to_string()), + method: bare_method.to_string(), + params: params.clone() + }) + } + [appbase_api, method] if appbase_api.ends_with("_api") => { + // e.g., condenser_api.method + Ok(MethodAndParams { + namespace: "appbase".to_string(), + api: Some(appbase_api.to_string()), + method: method.to_string(), + params: params.clone() + }) + } + ["jsonrpc", method] => { + Ok(MethodAndParams { + namespace: "appbase".to_string(), + api: Some("jsonrpc".to_string()), + method: method.to_string(), + params: params.clone() + }) + } + [namespace, method] => { + // in practice, this is usually bridge.method + // {namespace, None, method} + Ok(MethodAndParams { + namespace: namespace.to_string(), + api: None, + method: method.to_string(), + params: params.clone() + }) + } + [namespace, api, method] => { + Ok(MethodAndParams { + namespace: namespace.to_string(), + api: Some(api.to_string()), + method: method.to_string(), + params: params.clone() + }) + } + _ => { + Err("Error parsing method".to_string()) + } + } +} + +fn translate_to_appbase(method_and_params: MethodAndParams) -> Result<MethodAndParams, String> { + parse_call(&Some(json!(["condenser_api", method_and_params.method, &method_and_params.params.or(Some(json!([])))]))) +} + +/// the main method in this module, this: +/// - parses the request, figuring out what "namespace", "api", and "method" the call represents +/// using the same rules jussi uses +/// - applies part of the "translate_to_appbase" functionality from jussi: if the call is marked +/// as one that should be translated, it converts it to the "appbase" namespace and +/// "condenser_api". However, unlike jussi, it does not cause the call to the upstream to be +/// made using the "call" syntax +/// - does any method renaming requested by the "equivalent_methods" config +pub fn map_method_name(app_config: &AppConfig, method: &str, params: &Option<Value>) -> Result<MethodAndParams, String> { + let mut mapped_method_and_params = convert_method_name(method, params)?; + + if app_config.translate_to_appbase.contains(&mapped_method_and_params.namespace) { + mapped_method_and_params = translate_to_appbase(mapped_method_and_params)?; + } + + match app_config.equivalent_methods.get(&mapped_method_and_params.get_dotted_method_name()) { + // note: the user can cause infinite recursion by setting up an equivalent_methods rule + // that renames to itself + Some(new_method_name) => { map_method_name(app_config, new_method_name, &mapped_method_and_params.params) } + None => { Ok(mapped_method_and_params) } + } +} -- GitLab