diff --git a/Cargo.lock b/Cargo.lock index 2f1fa4c..54bfce3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,15 +123,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-sys", "zeroize", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -151,19 +151,19 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.9" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ - "async-trait", "axum-core", "axum-macros", "bytes", + "form_urlencoded", "futures-util", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-util", "itoa", "matchit", @@ -172,8 +172,7 @@ dependencies = [ "multer", "percent-encoding", "pin-project-lite", - "rustversion", - "serde", + "serde_core", "serde_json", "serde_path_to_error", "serde_urlencoded", @@ -187,19 +186,17 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ - "async-trait", "bytes", - "futures-util", - "http 1.4.0", + "futures-core", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", - "rustversion", "sync_wrapper 1.0.2", "tower-layer", "tower-service", @@ -208,9 +205,9 @@ dependencies = [ [[package]] name = "axum-macros" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" +checksum = "7aa268c23bfbbd2c4363b9cd302a4f504fb2a9dfe7e3451d66f35dd392e20aca" dependencies = [ "proc-macro2", "quote", @@ -227,9 +224,9 @@ dependencies = [ "bytes", "either", "fs-err", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-util", "pin-project-lite", "rustls", @@ -443,9 +440,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" [[package]] name = "block-buffer" @@ -458,9 +455,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytes" @@ -470,9 +467,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.61" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", @@ -486,6 +483,23 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chksum-hash-core" version = "0.0.0" @@ -512,7 +526,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -570,6 +584,16 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -620,6 +644,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -640,9 +673,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -655,7 +688,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -708,11 +741,21 @@ dependencies = [ "subtle", ] +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.12.1", + "objc2", +] + [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -771,9 +814,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" @@ -1052,9 +1095,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1092,9 +1135,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1106,6 +1151,7 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "rand_core 0.10.1", "wasip2", "wasip3", ] @@ -1142,16 +1188,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.4.0", + "http 1.4.1", "indexmap", "slab", "tokio", @@ -1170,9 +1216,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "headers" @@ -1183,7 +1229,7 @@ dependencies = [ "base64 0.22.1", "bytes", "headers-core", - "http 1.4.0", + "http 1.4.1", "httpdate", "mime", "sha1", @@ -1195,7 +1241,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 1.4.0", + "http 1.4.1", ] [[package]] @@ -1241,9 +1287,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -1267,7 +1313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.4.0", + "http 1.4.1", ] [[package]] @@ -1278,7 +1324,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "pin-project-lite", ] @@ -1347,16 +1393,16 @@ dependencies = [ [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", - "h2 0.4.13", - "http 1.4.0", + "h2 0.4.14", + "http 1.4.1", "http-body 1.0.1", "httparse", "httpdate", @@ -1373,8 +1419,8 @@ version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "http 1.4.0", - "hyper 1.9.0", + "http 1.4.1", + "hyper 1.10.1", "hyper-util", "rustls", "tokio", @@ -1403,7 +1449,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-util", "native-tls", "tokio", @@ -1421,14 +1467,14 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", - "hyper 1.9.0", + "hyper 1.10.1", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.3", + "socket2 0.6.4", "system-configuration 0.7.0", "tokio", "tower-service", @@ -1448,7 +1494,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core", ] [[package]] @@ -1576,7 +1622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -1602,16 +1648,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1624,6 +1660,55 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -1636,9 +1721,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -1648,9 +1733,9 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "10.3.0" +version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" dependencies = [ "base64 0.22.1", "ed25519-dalek", @@ -1667,6 +1752,7 @@ dependencies = [ "sha2", "signature", "simple_asn1", + "zeroize", ] [[package]] @@ -1690,8 +1776,8 @@ dependencies = [ "hex", "http-body-util", "jsonwebtoken", - "rand 0.8.6", - "reqwest 0.12.28", + "rand 0.10.1", + "reqwest 0.13.4", "rustls", "serde", "sysinfo", @@ -1755,21 +1841,27 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "matchit" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "mime" @@ -1789,9 +1881,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", @@ -1807,7 +1899,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 1.4.0", + "http 1.4.1", "httparse", "memchr", "mime", @@ -1878,9 +1970,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -1912,13 +2004,40 @@ dependencies = [ "libm", ] +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.12.1", + "objc2", ] [[package]] @@ -1931,6 +2050,17 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "objc2-open-directory" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb82bed227edf5201dfedf072bba4015a33d3d4a98519837295a90f0a23f676d" +dependencies = [ + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -1945,15 +2075,14 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.78" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -1977,9 +2106,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.114" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -2037,7 +2166,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -2073,18 +2202,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -2186,6 +2315,62 @@ dependencies = [ "serde", ] +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.6.4", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.4", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.4", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.45" @@ -2231,6 +2416,27 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -2251,6 +2457,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -2269,6 +2485,21 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rand_hc" version = "0.2.0" @@ -2284,7 +2515,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", ] [[package]] @@ -2337,22 +2568,16 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", - "encoding_rs", - "futures-channel", "futures-core", "futures-util", - "h2 0.4.13", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", - "hyper 1.9.0", - "hyper-rustls", + "hyper 1.10.1", "hyper-tls 0.6.0", "hyper-util", "js-sys", "log", - "mime", - "mime_guess", "native-tls", "percent-encoding", "pin-project-lite", @@ -2374,6 +2599,47 @@ dependencies = [ "web-sys", ] +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.4.14", + "http 1.4.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.10.1", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -2418,6 +2684,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + [[package]] name = "rustc_version" version = "0.4.1" @@ -2433,7 +2705,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "errno", "libc", "linux-raw-sys", @@ -2442,9 +2714,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.39" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "log", @@ -2455,6 +2727,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -2470,9 +2754,37 @@ version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ + "web-time", "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.103.13" @@ -2497,6 +2809,15 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.29" @@ -2532,7 +2853,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -2587,9 +2908,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -2648,7 +2969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -2659,7 +2980,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -2674,9 +2995,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -2698,6 +3019,22 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "simple_asn1" version = "0.6.4" @@ -2734,9 +3071,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -2815,15 +3152,16 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.35.2" +version = "0.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e" +checksum = "21d0d938c10fcda3e897e28aaddf4ab462375d411f4378cd63b1c945f69aba96" dependencies = [ "libc", "memchr", "ntapi", "objc2-core-foundation", "objc2-io-kit", + "objc2-open-directory", "serde", "windows", ] @@ -2845,7 +3183,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "core-foundation 0.9.4", "system-configuration-sys 0.6.0", ] @@ -2974,11 +3312,26 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -2986,7 +3339,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.3", + "socket2 0.6.4", "tokio-macros", "windows-sys 0.61.2", ] @@ -3092,20 +3445,19 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytes", "futures-core", "futures-util", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "http-range-header", "httpdate", - "iri-string", "mime", "mime_guess", "percent-encoding", @@ -3116,6 +3468,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", + "url", ] [[package]] @@ -3196,9 +3549,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicase" @@ -3251,9 +3604,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -3285,6 +3638,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -3326,9 +3689,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -3339,9 +3702,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -3349,9 +3712,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3359,9 +3722,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -3372,9 +3735,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -3420,7 +3783,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "hashbrown 0.15.5", "indexmap", "semver", @@ -3428,14 +3791,33 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -3452,6 +3834,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -3460,37 +3851,23 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.61.3" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ "windows-collections", - "windows-core 0.61.2", + "windows-core", "windows-future", - "windows-link 0.1.3", "windows-numerics", ] [[package]] name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.61.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-core", ] [[package]] @@ -3501,19 +3878,19 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] name = "windows-future" -version = "0.2.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core", + "windows-link", "windows-threading", ] @@ -3539,12 +3916,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -3553,12 +3924,12 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-numerics" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core", + "windows-link", ] [[package]] @@ -3567,18 +3938,9 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] @@ -3587,16 +3949,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -3605,7 +3958,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -3626,13 +3979,22 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + [[package]] name = "windows-sys" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -3659,20 +4021,37 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + [[package]] name = "windows-threading" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -3687,6 +4066,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3699,6 +4084,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3711,12 +4102,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3729,6 +4132,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3741,6 +4150,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3753,6 +4168,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3765,11 +4186,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" [[package]] name = "winreg" @@ -3845,7 +4272,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.12.1", "indexmap", "log", "serde", @@ -3883,9 +4310,9 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -3906,18 +4333,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", @@ -3926,9 +4353,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] @@ -3950,6 +4377,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zerotrie" diff --git a/Cargo.toml b/Cargo.toml index dcdf7cb..2aeae2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,42 +1,42 @@ [package] name = "kernelci-storage" -version = "0.2.0" +version = "0.2.1" edition = "2021" [dependencies] async-trait = "0.1" -axum = { version = "0.7.9", features = ["tracing", "multipart", "macros"] } +axum = { version = "0.8.9", features = ["tracing", "multipart", "macros"] } axum-server = { version = "0.8.0", features = ["rustls", "tls-rustls"] } azure_blob_uploader = "0.1.4" azure_storage = "0.21.0" azure_storage_blobs = "0.21.0" -bytes = "1.9" +bytes = "1.11" chksum-hash-sha2-512 = "0.0.1" -chrono = "0.4.39" -clap = { version = "4.5.23", features = ["derive"] } +chrono = "0.4.44" +clap = { version = "4.6.1", features = ["derive"] } fs2 = "0.4.3" -futures = "0.3.31" -futures-util = "0.3.31" -headers = "0.4.0" +futures = "0.3.32" +futures-util = "0.3.32" +headers = "0.4.1" hex = "0.4.3" -http-body-util = "0.1.2" +http-body-util = "0.1.3" jsonwebtoken = { version = "10", features = ["rust_crypto"] } -rand = "0.8.5" -reqwest = { version = "0.12.9", features = ["blocking"] } -rustls = "0.23.20" -serde = { version = "1.0.216", features = ["derive"] } -sysinfo = { version = "0.35.2", features = ["serde"] } -tempfile = "3.14.0" -tokio = { version = "1.42.0", features = ["rt", "rt-multi-thread", "macros"] } -tokio-util = "0.7.13" +rand = "0.10.1" +reqwest = { version = "0.13.4", features = ["blocking"] } +rustls = "0.23.40" +serde = { version = "1.0.228", features = ["derive"] } +sysinfo = { version = "0.39.3", features = ["serde"] } +tempfile = "3.27.0" +tokio = { version = "1.52.3", features = ["rt", "rt-multi-thread", "macros"] } +tokio-util = "0.7.18" toml = "1.1.2" -tower = "0.5.2" -tower-http = { version = "0.6.2", features = ["trace", "fs", "limit"] } -tracing = "0.1.41" -tracing-subscriber = "0.3.19" +tower = "0.5.3" +tower-http = { version = "0.6.11", features = ["trace", "fs", "limit"] } +tracing = "0.1.44" +tracing-subscriber = "0.3.23" [dev-dependencies] -reqwest = { version = "0.12.9", features = ["blocking", "multipart"] } +reqwest = { version = "0.13.4", features = ["blocking", "multipart"] } jsonwebtoken = { version = "10", features = ["rust_crypto"] } -tokio = { version = "1.42.0", features = ["rt", "rt-multi-thread", "macros", "time", "process"] } -tempfile = "3.14.0" +tokio = { version = "1.52.3", features = ["rt", "rt-multi-thread", "macros", "time", "process"] } +tempfile = "3.27.0" diff --git a/src/azure.rs b/src/azure.rs index 21c8e7f..96d35e2 100644 --- a/src/azure.rs +++ b/src/azure.rs @@ -83,29 +83,6 @@ fn get_azure_credentials(name: &str) -> AzureConfig { } } -#[cfg(test)] -mod tests { - use super::normalize_sas_token; - - #[test] - fn sas_token_is_left_empty() { - assert_eq!(normalize_sas_token(""), ""); - assert_eq!(normalize_sas_token(" "), ""); - } - - #[test] - fn sas_token_is_left_intact_when_prefixed() { - assert_eq!(normalize_sas_token("?sv=1"), "?sv=1"); - assert_eq!(normalize_sas_token(" ?sv=1 "), "?sv=1"); - } - - #[test] - fn sas_token_is_prefixed_when_missing_question_mark() { - assert_eq!(normalize_sas_token("sv=1"), "?sv=1"); - assert_eq!(normalize_sas_token(" sv=1 "), "?sv=1"); - } -} - #[allow(dead_code)] fn calculate_checksum(filename: &String, data: &[u8]) { let hash = sha2_512::default().update(data).finalize(); @@ -618,7 +595,8 @@ impl super::Driver for AzureDriver { cont_type: String, owner_email: Option, ) -> (String, usize) { - let (_status, size) = write_file_to_blob_streaming(filename.clone(), data, cont_type, owner_email).await; + let (_status, size) = + write_file_to_blob_streaming(filename.clone(), data, cont_type, owner_email).await; (filename, size) } async fn tag_file( @@ -639,3 +617,26 @@ impl super::Driver for AzureDriver { Vec::new() } } + +#[cfg(test)] +mod tests { + use super::normalize_sas_token; + + #[test] + fn sas_token_is_left_empty() { + assert_eq!(normalize_sas_token(""), ""); + assert_eq!(normalize_sas_token(" "), ""); + } + + #[test] + fn sas_token_is_left_intact_when_prefixed() { + assert_eq!(normalize_sas_token("?sv=1"), "?sv=1"); + assert_eq!(normalize_sas_token(" ?sv=1 "), "?sv=1"); + } + + #[test] + fn sas_token_is_prefixed_when_missing_question_mark() { + assert_eq!(normalize_sas_token("sv=1"), "?sv=1"); + assert_eq!(normalize_sas_token(" sv=1 "), "?sv=1"); + } +} diff --git a/src/local.rs b/src/local.rs index 246ef49..49422d8 100644 --- a/src/local.rs +++ b/src/local.rs @@ -70,10 +70,14 @@ fn get_storage_file_path(filename: &str) -> PathBuf { let safe_name = filename.trim_start_matches('/'); let full = storage_path.join(safe_name); // Defense-in-depth: verify resolved path stays within storage root - let canonical_storage = storage_path.canonicalize().unwrap_or_else(|_| storage_path.to_path_buf()); + let canonical_storage = storage_path + .canonicalize() + .unwrap_or_else(|_| storage_path.to_path_buf()); // Use the parent directory for canonicalization since the file may not exist yet let parent = full.parent().unwrap_or(&full); - let canonical_parent = parent.canonicalize().unwrap_or_else(|_| parent.to_path_buf()); + let canonical_parent = parent + .canonicalize() + .unwrap_or_else(|_| parent.to_path_buf()); if !canonical_parent.starts_with(&canonical_storage) { // Fall back to storage root to prevent escape storage_path.join(Path::new(safe_name).file_name().unwrap_or_default()) @@ -265,26 +269,24 @@ fn list_files_in_local(directory: String) -> Vec { fn collect_files_recursive(path: &Path, base_path: &Path, files: &mut Vec) { if let Ok(entries) = fs::read_dir(path) { - for entry in entries { - if let Ok(entry) = entry { - let entry_path = entry.path(); - - // Skip metadata directory - if entry_path - .file_name() - .map_or(false, |name| name == ".metadata") - { - continue; - } + for entry in entries.flatten() { + let entry_path = entry.path(); + + // Skip metadata directory + if entry_path + .file_name() + .is_some_and(|name| name == ".metadata") + { + continue; + } - if entry_path.is_file() { - // Get relative path from storage root - if let Ok(relative_path) = entry_path.strip_prefix(base_path) { - files.push(relative_path.to_string_lossy().to_string()); - } - } else if entry_path.is_dir() { - collect_files_recursive(&entry_path, base_path, files); + if entry_path.is_file() { + // Get relative path from storage root + if let Ok(relative_path) = entry_path.strip_prefix(base_path) { + files.push(relative_path.to_string_lossy().to_string()); } + } else if entry_path.is_dir() { + collect_files_recursive(&entry_path, base_path, files); } } } @@ -352,7 +354,9 @@ impl super::Driver for LocalDriver { let fname = filename.clone(); match tokio::task::spawn_blocking(move || { write_file_to_local(fname, data, cont_type, owner_email) - }).await { + }) + .await + { Ok(Ok(_)) => filename, Ok(Err(e)) => { eprintln!("Local storage write error: {}", e); diff --git a/src/logging.rs b/src/logging.rs index d8a9765..534ac74 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -23,8 +23,8 @@ pub fn verbose_enabled() -> bool { } fn env_verbose_enabled() -> bool { - std::env::var(ENV_DEBUG).map_or(false, |v| !v.is_empty()) - || std::env::var(ENV_VERBOSE).map_or(false, |v| !v.is_empty()) + std::env::var(ENV_DEBUG).is_ok_and(|v| !v.is_empty()) + || std::env::var(ENV_VERBOSE).is_ok_and(|v| !v.is_empty()) } #[macro_export] diff --git a/src/main.rs b/src/main.rs index 56d328a..473ee92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ mod logging; mod storcaching; mod storjwt; +use async_trait::async_trait; use axum::{ body::Body, extract::{ConnectInfo, DefaultBodyLimit, Multipart, OriginalUri, Path, State}, @@ -25,9 +26,8 @@ use axum::{ routing::{get, post}, Router, }; -use bytes::Bytes; -use async_trait::async_trait; use axum_server::tls_rustls::RustlsConfig; +use bytes::Bytes; use clap::Parser; use headers::HeaderMap; use std::path; @@ -35,15 +35,15 @@ use std::sync::OnceLock; use std::{net::SocketAddr, path::PathBuf}; use tokio::io::{AsyncSeekExt, AsyncWriteExt}; -use std::{collections::HashMap, sync::Arc}; +use futures::Future; use std::pin::Pin; use std::task::{Context, Poll}; +use std::{collections::HashMap, sync::Arc}; use sysinfo::Disks; use tokio::sync::{RwLock, Semaphore}; use tokio_util::io::ReaderStream; use toml::Table; use tower::ServiceBuilder; -use futures::Future; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -80,7 +80,7 @@ struct Args { static ARGS: OnceLock = OnceLock::new(); fn get_args() -> &'static Args { - ARGS.get_or_init(|| Args::parse()) + ARGS.get_or_init(Args::parse) } // const names for last-modified and etag in lowercase @@ -182,9 +182,7 @@ impl<'a> tokio::io::AsyncRead for FieldStream<'a> { // EOF Poll::Ready(Ok(())) } - Poll::Ready(Err(e)) => { - Poll::Ready(Err(std::io::Error::new(std::io::ErrorKind::Other, e))) - } + Poll::Ready(Err(e)) => Poll::Ready(Err(std::io::Error::other(e))), Poll::Pending => Poll::Pending, } } @@ -420,7 +418,7 @@ async fn main() { .route("/v1/checkauth", get(ax_check_auth)) .route("/v1/file", post(ax_post_file)) .route("/upload", post(ax_post_file)) - .route("/*filepath", get(ax_get_file)) + .route("/{*filepath}", get(ax_get_file)) .route("/v1/list", get(ax_list_files)) .route("/metrics", get(ax_metrics)) .layer(ServiceBuilder::new().layer(DefaultBodyLimit::max(1024 * 1024 * 1024 * 4))) @@ -607,7 +605,10 @@ async fn ax_post_file( Ok(field) => field, Err(e) => { eprintln!("Error reading multipart field: {:?}", e); - return (StatusCode::BAD_REQUEST, b"Malformed multipart request".to_vec()); + return ( + StatusCode::BAD_REQUEST, + b"Malformed multipart request".to_vec(), + ); } } { let name = match field.name() { @@ -714,7 +715,8 @@ async fn ax_post_file( match verify_upload_permissions(&owner, &path) { Ok(_) => (), Err(e) => { - upload_result = Some((StatusCode::FORBIDDEN, e.to_string().into_bytes())); + upload_result = + Some((StatusCode::FORBIDDEN, e.to_string().into_bytes())); break; } } @@ -765,12 +767,14 @@ async fn ax_post_file( let driver_name = get_driver_type(); let driver = init_driver(&driver_name); - let (result, file_size) = driver.write_file_streaming( - full_path.clone(), - &mut field_stream, - content_type.to_string(), - Some(owner.clone()), - ).await; + let (result, file_size) = driver + .write_file_streaming( + full_path.clone(), + &mut field_stream, + content_type.to_string(), + Some(owner.clone()), + ) + .await; if result.is_empty() { upload_result = Some((StatusCode::CONFLICT, Vec::new())); @@ -925,7 +929,10 @@ async fn ax_post_file( // If we get here, something went wrong (no file0 field found) debug_log!("No file0 field found in multipart upload"); - (StatusCode::BAD_REQUEST, b"No file0 field in upload".to_vec()) + ( + StatusCode::BAD_REQUEST, + b"No file0 field in upload".to_vec(), + ) } fn filename_from_fullpath(filepath: &str) -> String { @@ -1077,7 +1084,8 @@ async fn ax_get_file( match range.to_str().ok().and_then(parse_range) { Some(parsed) => (start, end) = parsed, None => { - return (StatusCode::RANGE_NOT_SATISFIABLE, "Malformed Range header").into_response(); + return (StatusCode::RANGE_NOT_SATISFIABLE, "Malformed Range header") + .into_response(); } } } @@ -1120,18 +1128,19 @@ async fn ax_get_file( "{} 206 {} {} {} {} {}", client_ip, body_size, human_time, method, filepath, user_agent_str ); - return (StatusCode::PARTIAL_CONTENT, headers, axbody).into_response(); + (StatusCode::PARTIAL_CONTENT, headers, axbody).into_response() + } else { + println!( + "{} 200 {} {} {} {} {}", + client_ip, + metadata.len(), + human_time, + method, + filepath, + user_agent_str + ); + (StatusCode::OK, headers, axbody).into_response() } - println!( - "{} 200 {} {} {} {} {}", - client_ip, - metadata.len(), - human_time, - method, - filepath, - user_agent_str - ); - return (StatusCode::OK, headers, axbody).into_response(); } Err(_) => { eprintln!("Error opening file in ax_get_file"); @@ -1159,7 +1168,9 @@ async fn write_file_driver( ) -> String { let driver_name = get_driver_type(); let driver = init_driver(&driver_name); - driver.write_file(filename, data, cont_type, owner_email).await; + driver + .write_file(filename, data, cont_type, owner_email) + .await; "".to_string() } @@ -1223,7 +1234,10 @@ async fn ax_list_files() -> (StatusCode, String) { // Listing files is disabled for Azure backend because it is too slow // (flat blob namespace requires enumerating all blobs with prefix filtering). if driver_name == "azure" { - return (StatusCode::FORBIDDEN, "Listing files is disabled for Azure storage backend".to_string()); + return ( + StatusCode::FORBIDDEN, + "Listing files is disabled for Azure storage backend".to_string(), + ); } let driver = init_driver(&driver_name); let files = driver.list_files("/".to_string()).await; diff --git a/src/storjwt.rs b/src/storjwt.rs index 26bcb6c..4ed9af8 100644 --- a/src/storjwt.rs +++ b/src/storjwt.rs @@ -67,13 +67,9 @@ pub fn verify_jwt_token( pub fn generate_jwt_secret() { // generate a random 32 bytes alphanumeric string - use rand::{distributions::Alphanumeric, Rng}; + use rand::distr::{Alphanumeric, SampleString}; - let secret: String = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(32) - .map(char::from) - .collect(); + let secret = Alphanumeric.sample_string(&mut rand::rng(), 32); debug_log!("jwt_secret=\"{}\"", secret); } diff --git a/tests/e2e.rs b/tests/e2e.rs index df5e0cc..bfbab53 100644 --- a/tests/e2e.rs +++ b/tests/e2e.rs @@ -122,14 +122,21 @@ cleanup_chunk_size=100000 fn wait_until_ready(&self) { let client = reqwest::blocking::Client::new(); for _ in 0..50 { - if let Ok(resp) = client.get(&self.base_url).timeout(Duration::from_millis(200)).send() { + if let Ok(resp) = client + .get(&self.base_url) + .timeout(Duration::from_millis(200)) + .send() + { if resp.status().is_success() { return; } } std::thread::sleep(Duration::from_millis(100)); } - panic!("Server did not become ready within 5 seconds on port {}", self.port); + panic!( + "Server did not become ready within 5 seconds on port {}", + self.port + ); } fn url(&self, path: &str) -> String { @@ -157,7 +164,7 @@ impl Drop for TestServer { #[test] fn test_root_endpoint() { let server = TestServer::start(); - let resp = server.client().get(&server.url("/")).send().unwrap(); + let resp = server.client().get(server.url("/")).send().unwrap(); assert_eq!(resp.status(), 200); assert_eq!(resp.text().unwrap(), "KernelCI Storage Server"); } @@ -168,14 +175,22 @@ fn test_checkauth_valid_token() { let token = generate_token(TEST_EMAIL); let resp = server .client() - .get(&server.url("/v1/checkauth")) + .get(server.url("/v1/checkauth")) .header("Authorization", format!("Bearer {}", token)) .send() .unwrap(); assert_eq!(resp.status(), 200); let body = resp.text().unwrap(); - assert!(body.contains("Authorized"), "Expected 'Authorized' in body, got: {}", body); - assert!(body.contains(TEST_EMAIL), "Expected email in body, got: {}", body); + assert!( + body.contains("Authorized"), + "Expected 'Authorized' in body, got: {}", + body + ); + assert!( + body.contains(TEST_EMAIL), + "Expected email in body, got: {}", + body + ); } #[test] @@ -183,7 +198,7 @@ fn test_checkauth_no_token() { let server = TestServer::start(); let resp = server .client() - .get(&server.url("/v1/checkauth")) + .get(server.url("/v1/checkauth")) .send() .unwrap(); assert_eq!(resp.status(), 401); @@ -194,7 +209,7 @@ fn test_checkauth_invalid_token() { let server = TestServer::start(); let resp = server .client() - .get(&server.url("/v1/checkauth")) + .get(server.url("/v1/checkauth")) .header("Authorization", "Bearer invalid-token-value") .send() .unwrap(); @@ -210,18 +225,16 @@ fn test_upload_and_download() { let file_content = b"Hello, KernelCI storage e2e test!"; // Upload - let form = multipart::Form::new() - .text("path", "testdir") - .part( - "file0", - multipart::Part::bytes(file_content.to_vec()) - .file_name("hello.txt") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "testdir").part( + "file0", + multipart::Part::bytes(file_content.to_vec()) + .file_name("hello.txt") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -229,7 +242,7 @@ fn test_upload_and_download() { assert_eq!(resp.status(), 200, "Upload failed: {:?}", resp.text()); // Download - let resp = client.get(&server.url("/testdir/hello.txt")).send().unwrap(); + let resp = client.get(server.url("/testdir/hello.txt")).send().unwrap(); assert_eq!(resp.status(), 200); let body = resp.bytes().unwrap(); assert_eq!(body.as_ref(), file_content); @@ -242,18 +255,16 @@ fn test_upload_via_legacy_endpoint() { let client = server.client(); let file_content = b"legacy upload test"; - let form = multipart::Form::new() - .text("path", "legacy") - .part( - "file0", - multipart::Part::bytes(file_content.to_vec()) - .file_name("test.bin") - .mime_str("application/octet-stream") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "legacy").part( + "file0", + multipart::Part::bytes(file_content.to_vec()) + .file_name("test.bin") + .mime_str("application/octet-stream") + .unwrap(), + ); let resp = client - .post(&server.url("/upload")) + .post(server.url("/upload")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -261,7 +272,7 @@ fn test_upload_via_legacy_endpoint() { assert_eq!(resp.status(), 200); // Verify download works - let resp = client.get(&server.url("/legacy/test.bin")).send().unwrap(); + let resp = client.get(server.url("/legacy/test.bin")).send().unwrap(); assert_eq!(resp.status(), 200); assert_eq!(resp.bytes().unwrap().as_ref(), file_content); } @@ -271,18 +282,16 @@ fn test_upload_unauthorized() { let server = TestServer::start(); let client = server.client(); - let form = multipart::Form::new() - .text("path", "testdir") - .part( - "file0", - multipart::Part::bytes(b"should fail".to_vec()) - .file_name("fail.txt") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "testdir").part( + "file0", + multipart::Part::bytes(b"should fail".to_vec()) + .file_name("fail.txt") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .multipart(form) .send() .unwrap(); @@ -296,18 +305,16 @@ fn test_upload_permission_denied() { let client = server.client(); // restricted@kernelci.org can only upload to "restricted-area" prefix - let form = multipart::Form::new() - .text("path", "other-dir") - .part( - "file0", - multipart::Part::bytes(b"should be forbidden".to_vec()) - .file_name("forbidden.txt") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "other-dir").part( + "file0", + multipart::Part::bytes(b"should be forbidden".to_vec()) + .file_name("forbidden.txt") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -333,12 +340,17 @@ fn test_upload_permission_allowed_prefix() { ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() .unwrap(); - assert_eq!(resp.status(), 200, "Upload should be allowed: {:?}", resp.text()); + assert_eq!( + resp.status(), + 200, + "Upload should be allowed: {:?}", + resp.text() + ); } #[test] @@ -346,7 +358,7 @@ fn test_download_not_found() { let server = TestServer::start(); let resp = server .client() - .get(&server.url("/nonexistent/file.txt")) + .get(server.url("/nonexistent/file.txt")) .send() .unwrap(); assert_eq!(resp.status(), 404); @@ -364,18 +376,16 @@ fn test_list_files() { ("list-test", "file2.txt", "content2"), ("list-test/sub", "file3.txt", "content3"), ] { - let form = multipart::Form::new() - .text("path", path.to_string()) - .part( - "file0", - multipart::Part::bytes(content.as_bytes().to_vec()) - .file_name(name.to_string()) - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", path.to_string()).part( + "file0", + multipart::Part::bytes(content.as_bytes().to_vec()) + .file_name(name.to_string()) + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -384,12 +394,24 @@ fn test_list_files() { } // List files - let resp = client.get(&server.url("/v1/list")).send().unwrap(); + let resp = client.get(server.url("/v1/list")).send().unwrap(); assert_eq!(resp.status(), 200); let body = resp.text().unwrap(); - assert!(body.contains("list-test/file1.txt"), "Missing file1.txt in list: {}", body); - assert!(body.contains("list-test/file2.txt"), "Missing file2.txt in list: {}", body); - assert!(body.contains("list-test/sub/file3.txt"), "Missing file3.txt in list: {}", body); + assert!( + body.contains("list-test/file1.txt"), + "Missing file1.txt in list: {}", + body + ); + assert!( + body.contains("list-test/file2.txt"), + "Missing file2.txt in list: {}", + body + ); + assert!( + body.contains("list-test/sub/file3.txt"), + "Missing file3.txt in list: {}", + body + ); } #[test] @@ -401,17 +423,15 @@ fn test_range_request() { let file_content = b"0123456789ABCDEF"; // Upload - let form = multipart::Form::new() - .text("path", "range-test") - .part( - "file0", - multipart::Part::bytes(file_content.to_vec()) - .file_name("data.bin") - .mime_str("application/octet-stream") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "range-test").part( + "file0", + multipart::Part::bytes(file_content.to_vec()) + .file_name("data.bin") + .mime_str("application/octet-stream") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -420,11 +440,16 @@ fn test_range_request() { // Range request: bytes 5 onwards let resp = client - .get(&server.url("/range-test/data.bin")) + .get(server.url("/range-test/data.bin")) .header("Range", "bytes=5-") .send() .unwrap(); - assert_eq!(resp.status(), 206, "Expected 206 Partial Content, got {}", resp.status()); + assert_eq!( + resp.status(), + 206, + "Expected 206 Partial Content, got {}", + resp.status() + ); let body = resp.bytes().unwrap(); assert_eq!(body.as_ref(), &file_content[5..]); } @@ -438,17 +463,15 @@ fn test_head_request() { let file_content = b"head request test content"; // Upload - let form = multipart::Form::new() - .text("path", "head-test") - .part( - "file0", - multipart::Part::bytes(file_content.to_vec()) - .file_name("file.txt") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "head-test").part( + "file0", + multipart::Part::bytes(file_content.to_vec()) + .file_name("file.txt") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -457,7 +480,7 @@ fn test_head_request() { // HEAD request let resp = client - .head(&server.url("/head-test/file.txt")) + .head(server.url("/head-test/file.txt")) .send() .unwrap(); assert_eq!(resp.status(), 200); @@ -475,17 +498,15 @@ fn test_conditional_request_etag() { let file_content = b"etag test content"; // Upload - let form = multipart::Form::new() - .text("path", "etag-test") - .part( - "file0", - multipart::Part::bytes(file_content.to_vec()) - .file_name("file.txt") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "etag-test").part( + "file0", + multipart::Part::bytes(file_content.to_vec()) + .file_name("file.txt") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -494,20 +515,28 @@ fn test_conditional_request_etag() { // First GET to obtain ETag let resp = client - .get(&server.url("/etag-test/file.txt")) + .get(server.url("/etag-test/file.txt")) .send() .unwrap(); assert_eq!(resp.status(), 200); - let etag = resp.headers().get("etag").map(|v| v.to_str().unwrap().to_string()); + let etag = resp + .headers() + .get("etag") + .map(|v| v.to_str().unwrap().to_string()); if let Some(etag) = etag { // Conditional GET with If-None-Match let resp = client - .get(&server.url("/etag-test/file.txt")) + .get(server.url("/etag-test/file.txt")) .header("If-None-Match", &etag) .send() .unwrap(); - assert_eq!(resp.status(), 304, "Expected 304 Not Modified, got {}", resp.status()); + assert_eq!( + resp.status(), + 304, + "Expected 304 Not Modified, got {}", + resp.status() + ); } } @@ -517,18 +546,16 @@ fn test_path_traversal_rejected() { let token = generate_token(TEST_EMAIL); let client = server.client(); - let form = multipart::Form::new() - .text("path", "../etc") - .part( - "file0", - multipart::Part::bytes(b"evil".to_vec()) - .file_name("passwd") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "../etc").part( + "file0", + multipart::Part::bytes(b"evil".to_vec()) + .file_name("passwd") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -543,17 +570,15 @@ fn test_upload_overwrite() { let client = server.client(); // First upload - let form = multipart::Form::new() - .text("path", "dup-test") - .part( - "file0", - multipart::Part::bytes(b"first upload".to_vec()) - .file_name("same.txt") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "dup-test").part( + "file0", + multipart::Part::bytes(b"first upload".to_vec()) + .file_name("same.txt") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -561,17 +586,15 @@ fn test_upload_overwrite() { assert_eq!(resp.status(), 200); // Second upload to same path - overwrites the file - let form = multipart::Form::new() - .text("path", "dup-test") - .part( - "file0", - multipart::Part::bytes(b"second upload".to_vec()) - .file_name("same.txt") - .mime_str("text/plain") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "dup-test").part( + "file0", + multipart::Part::bytes(b"second upload".to_vec()) + .file_name("same.txt") + .mime_str("text/plain") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -579,7 +602,7 @@ fn test_upload_overwrite() { assert_eq!(resp.status(), 200, "Re-upload should succeed (overwrite)"); // Verify the new content - let resp = client.get(&server.url("/dup-test/same.txt")).send().unwrap(); + let resp = client.get(server.url("/dup-test/same.txt")).send().unwrap(); assert_eq!(resp.status(), 200); assert_eq!(resp.bytes().unwrap().as_ref(), b"second upload"); } @@ -587,11 +610,13 @@ fn test_upload_overwrite() { #[test] fn test_metrics_endpoint() { let server = TestServer::start(); - let resp = server.client().get(&server.url("/metrics")).send().unwrap(); + let resp = server.client().get(server.url("/metrics")).send().unwrap(); assert_eq!(resp.status(), 200); let body = resp.text().unwrap(); - assert!(body.contains("storage_free_space") || body.contains("storage_total_space"), - "Metrics should contain disk space info"); + assert!( + body.contains("storage_free_space") || body.contains("storage_total_space"), + "Metrics should contain disk space info" + ); } #[test] @@ -601,17 +626,15 @@ fn test_content_type_preserved() { let client = server.client(); // Upload a .json file - let form = multipart::Form::new() - .text("path", "ctype-test") - .part( - "file0", - multipart::Part::bytes(b"{\"key\": \"value\"}".to_vec()) - .file_name("data.json") - .mime_str("application/json") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "ctype-test").part( + "file0", + multipart::Part::bytes(b"{\"key\": \"value\"}".to_vec()) + .file_name("data.json") + .mime_str("application/json") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -619,7 +642,10 @@ fn test_content_type_preserved() { assert_eq!(resp.status(), 200); // Download and check content-type - let resp = client.get(&server.url("/ctype-test/data.json")).send().unwrap(); + let resp = client + .get(server.url("/ctype-test/data.json")) + .send() + .unwrap(); assert_eq!(resp.status(), 200); let content_type = resp .headers() @@ -644,17 +670,15 @@ fn test_large_file_upload() { let file_content: Vec = (0..1024 * 1024).map(|i| (i % 256) as u8).collect(); let expected_len = file_content.len(); - let form = multipart::Form::new() - .text("path", "large-test") - .part( - "file0", - multipart::Part::bytes(file_content) - .file_name("large.bin") - .mime_str("application/octet-stream") - .unwrap(), - ); + let form = multipart::Form::new().text("path", "large-test").part( + "file0", + multipart::Part::bytes(file_content) + .file_name("large.bin") + .mime_str("application/octet-stream") + .unwrap(), + ); let resp = client - .post(&server.url("/v1/file")) + .post(server.url("/v1/file")) .header("Authorization", format!("Bearer {}", token)) .multipart(form) .send() @@ -662,7 +686,10 @@ fn test_large_file_upload() { assert_eq!(resp.status(), 200); // Download and verify size - let resp = client.get(&server.url("/large-test/large.bin")).send().unwrap(); + let resp = client + .get(server.url("/large-test/large.bin")) + .send() + .unwrap(); assert_eq!(resp.status(), 200); let body = resp.bytes().unwrap(); assert_eq!(body.len(), expected_len, "Downloaded file size mismatch");