From d5aed85a1e6b082f96c915f01ce9ab23978ebcb0 Mon Sep 17 00:00:00 2001 From: Bo Date: Sat, 16 Dec 2023 00:16:22 +0800 Subject: [PATCH 1/6] feat: Add genfile and baseline. --- ruan_lao_shi_xiao_fen_dui/baseline/.gitignore | 1 + ruan_lao_shi_xiao_fen_dui/baseline/Cargo.lock | 1580 +++++++++++++++++ ruan_lao_shi_xiao_fen_dui/baseline/Cargo.toml | 11 + ruan_lao_shi_xiao_fen_dui/baseline/README.md | 22 + .../baseline/single.dump | 235 +++ .../baseline/src/main.rs | 101 ++ ruan_lao_shi_xiao_fen_dui/genfile/.gitignore | 1 + ruan_lao_shi_xiao_fen_dui/genfile/Cargo.lock | 7 + ruan_lao_shi_xiao_fen_dui/genfile/Cargo.toml | 8 + ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs | 34 + 10 files changed, 2000 insertions(+) create mode 100644 ruan_lao_shi_xiao_fen_dui/baseline/.gitignore create mode 100644 ruan_lao_shi_xiao_fen_dui/baseline/Cargo.lock create mode 100644 ruan_lao_shi_xiao_fen_dui/baseline/Cargo.toml create mode 100644 ruan_lao_shi_xiao_fen_dui/baseline/README.md create mode 100644 ruan_lao_shi_xiao_fen_dui/baseline/single.dump create mode 100644 ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/genfile/.gitignore create mode 100644 ruan_lao_shi_xiao_fen_dui/genfile/Cargo.lock create mode 100644 ruan_lao_shi_xiao_fen_dui/genfile/Cargo.toml create mode 100644 ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/.gitignore b/ruan_lao_shi_xiao_fen_dui/baseline/.gitignore new file mode 100644 index 0000000..c41cc9e --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/baseline/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/Cargo.lock b/ruan_lao_shi_xiao_fen_dui/baseline/Cargo.lock new file mode 100644 index 0000000..b8e345c --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/baseline/Cargo.lock @@ -0,0 +1,1580 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", +] + +[[package]] +name = "attohttpc" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f77d243921b0979fbbd728dd2d5162e68ac8252976797c24eb5b3a6af9090dc" +dependencies = [ + "http", + "log", + "native-tls", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "aws-creds" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390ad3b77f3e21e01a4a0355865853b681daf1988510b0b15e31c0c4ae7eb0f6" +dependencies = [ + "attohttpc", + "home", + "log", + "quick-xml", + "rust-ini", + "serde", + "thiserror", + "time", + "url", +] + +[[package]] +name = "aws-region" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42fed2b9fca70f2908268d057a607f2a906f47edbf856ea8587de9038d264e22" +dependencies = [ + "thiserror", +] + +[[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.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "baseline" +version = "0.1.0" +dependencies = [ + "chrono", + "rust-s3", + "tokio", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.5", +] + +[[package]] +name = "const-random" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaf16c9c2c612020bcfd042e170f6e32de9b9d75adb5277cdbbd2e2c8c8299a" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deranged" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +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 = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "maybe-async" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "minidom" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f45614075738ce1b77a1768912a60c0227525971b03e09122a05b8a34a2a6278" +dependencies = [ + "rxml", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-multimap" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" +dependencies = [ + "dlv-list", + "hashbrown", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "rust-ini" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rust-s3" +version = "0.34.0-rc4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0533896b025761b23147ca1a168c436e1b87d14e460b1f19a6442882d2a3e07f" +dependencies = [ + "async-trait", + "aws-creds", + "aws-region", + "base64", + "bytes", + "cfg-if", + "futures", + "hex", + "hmac", + "http", + "hyper", + "hyper-tls", + "log", + "maybe-async", + "md5", + "minidom", + "native-tls", + "percent-encoding", + "quick-xml", + "serde", + "serde_derive", + "serde_json", + "sha2", + "thiserror", + "time", + "tokio", + "tokio-native-tls", + "tokio-stream", + "url", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rxml" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98f186c7a2f3abbffb802984b7f1dfd65dac8be1aafdaabbca4137f53f0dff7" +dependencies = [ + "bytes", + "rxml_validation", + "smartstring", +] + +[[package]] +name = "rxml_validation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.40", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +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 = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +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 = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/Cargo.toml b/ruan_lao_shi_xiao_fen_dui/baseline/Cargo.toml new file mode 100644 index 0000000..009f612 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/baseline/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "baseline" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rust-s3 = {version = "0.34.0-rc4"} +tokio = { version = "1.19.2", features = ["full"] } +chrono = { version = "0.4.19", features = ["serde"] } \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/README.md b/ruan_lao_shi_xiao_fen_dui/baseline/README.md new file mode 100644 index 0000000..9235aef --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/baseline/README.md @@ -0,0 +1,22 @@ +# Baseline + +多台设备直接读取同一个文件,测试读取速度。测试机器4核8G,测试文件大小为10MB。 + +### 测试结果 + +> (10MB下载),测试S3服务器使用Minio S3, 带宽约为1MB/s,可以使用tc工具进行限速 +> 配置文件可修改,默认分片大小为128KB + +1. 目前是使用多线程的方式并行进行下载,下载时间为: +(10个线程同时读取这个10MB的文件): +```bash +Average multi download test duration: 117.793s +``` + +2. 尝试使用p2p方式进行下载,下载时间为: +(10个node节点同时读取这个10MB的文件): +```bash +cpu 37.540 total +``` + +因此,在10个节点的情况下,读取该文件的时间提升大。 \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/single.dump b/ruan_lao_shi_xiao_fen_dui/baseline/single.dump new file mode 100644 index 0000000..0a91359 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/baseline/single.dump @@ -0,0 +1,235 @@ +asklv@192 baseline % cargo run + Compiling baseline v0.1.0 (/Users/asklv/Projects/Hackathon/baseline) + Finished dev [unoptimized + debuginfo] target(s) in 1.43s + Running `target/debug/baseline` +Start multi download test... start_time: Instant { tv_sec: 1048133, tv_nsec: 211625750 } +Start download test 0 +Start download test 1 +Start download test 3 +Start download test 5 +Start download test 4 +Start download test 6 +Start download test 7 +Start download test 8 +Start download test 9 +Start download test 2 +End download test 0 +End download test 8 +End download test 9 +End download test 5 +End download test 7 +End download test 3 +End download test 4 +End download test 6 +End download test 2 +End download test 1 +End multi download test... end_time: Instant { tv_sec: 1048246, tv_nsec: 701054250 } +Task-0 multi download test duration: 113.4894285s +Start multi download test... start_time: Instant { tv_sec: 1048246, tv_nsec: 701085208 } +Start download test 0 +Start download test 1 +Start download test 2 +Start download test 3 +Start download test 4 +Start download test 5 +Start download test 6 +Start download test 7 +Start download test 8 +Start download test 9 +End download test 8 +End download test 5 +End download test 1 +End download test 6 +End download test 7 +End download test 0 +End download test 9 +End download test 4 +End download test 3 +End download test 2 +End multi download test... end_time: Instant { tv_sec: 1048357, tv_nsec: 382688125 } +Task-1 multi download test duration: 110.681602917s +Start multi download test... start_time: Instant { tv_sec: 1048357, tv_nsec: 382721875 } +Start download test 0 +Start download test 1 +Start download test 3 +Start download test 4 +Start download test 5 +Start download test 6 +Start download test 7 +Start download test 8 +Start download test 9 +Start download test 2 +End download test 3 +End download test 6 +End download test 7 +End download test 8 +End download test 5 +End download test 4 +End download test 2 +End download test 9 +End download test 1 +End download test 0 +End multi download test... end_time: Instant { tv_sec: 1048497, tv_nsec: 724967208 } +Task-2 multi download test duration: 140.342245333s +Start multi download test... start_time: Instant { tv_sec: 1048497, tv_nsec: 724983458 } +Start download test 0 +Start download test 1 +Start download test 3 +Start download test 4 +Start download test 5 +Start download test 6 +Start download test 7 +Start download test 8 +Start download test 9 +Start download test 2 +End download test 5 +End download test 1 +End download test 8 +End download test 0 +End download test 6 +End download test 9 +End download test 7 +End download test 2 +End download test 3 +End download test 4 +End multi download test... end_time: Instant { tv_sec: 1048621, tv_nsec: 978657083 } +Task-3 multi download test duration: 124.253673625s +Start multi download test... start_time: Instant { tv_sec: 1048621, tv_nsec: 978682625 } +Start download test 0 +Start download test 2 +Start download test 4 +Start download test 5 +Start download test 3 +Start download test 1 +Start download test 6 +Start download test 7 +Start download test 8 +Start download test 9 +End download test 5 +End download test 8 +End download test 2 +End download test 4 +End download test 9 +End download test 7 +End download test 6 +End download test 3 +End download test 1 +End download test 0 +End multi download test... end_time: Instant { tv_sec: 1048738, tv_nsec: 916607166 } +Task-4 multi download test duration: 116.937924541s +Start multi download test... start_time: Instant { tv_sec: 1048738, tv_nsec: 916632416 } +Start download test 0 +Start download test 1 +Start download test 3 +Start download test 4 +Start download test 5 +Start download test 2 +Start download test 6 +Start download test 7 +Start download test 8 +Start download test 9 +End download test 3 +End download test 9 +End download test 2 +End download test 4 +End download test 0 +End download test 1 +End download test 7 +End download test 8 +End download test 6 +End download test 5 +End multi download test... end_time: Instant { tv_sec: 1048859, tv_nsec: 151565083 } +Task-5 multi download test duration: 120.234932667s +Start multi download test... start_time: Instant { tv_sec: 1048859, tv_nsec: 151584583 } +Start download test 0 +Start download test 1 +Start download test 2 +Start download test 4 +Start download test 5 +Start download test 6 +Start download test 7 +Start download test 3 +Start download test 8 +Start download test 9 +End download test 9 +End download test 0 +End download test 3 +End download test 5 +End download test 6 +End download test 1 +End download test 8 +End download test 2 +End download test 7 +End download test 4 +End multi download test... end_time: Instant { tv_sec: 1048968, tv_nsec: 65341333 } +Task-6 multi download test duration: 108.91375675s +Start multi download test... start_time: Instant { tv_sec: 1048968, tv_nsec: 65367166 } +Start download test 0 +Start download test 2 +Start download test 5 +Start download test 6 +Start download test 7 +Start download test 1 +Start download test 8 +Start download test 9 +Start download test 3 +Start download test 4 +End download test 3 +End download test 5 +End download test 8 +End download test 6 +End download test 9 +End download test 0 +End download test 4 +End download test 2 +End download test 1 +End download test 7 +End multi download test... end_time: Instant { tv_sec: 1049081, tv_nsec: 595953500 } +Task-7 multi download test duration: 113.530586334s +Start multi download test... start_time: Instant { tv_sec: 1049081, tv_nsec: 595999666 } +Start download test 0 +Start download test 1 +Start download test 2 +Start download test 3 +Start download test 4 +Start download test 5 +Start download test 6 +Start download test 7 +Start download test 8 +Start download test 9 +End download test 1 +End download test 9 +End download test 5 +End download test 6 +End download test 7 +End download test 2 +End download test 0 +End download test 8 +End download test 4 +End download test 3 +End multi download test... end_time: Instant { tv_sec: 1049195, tv_nsec: 332050375 } +Task-8 multi download test duration: 113.736050709s +Start multi download test... start_time: Instant { tv_sec: 1049195, tv_nsec: 332062375 } +Start download test 0 +Start download test 2 +Start download test 5 +Start download test 4 +Start download test 6 +Start download test 1 +Start download test 7 +Start download test 8 +Start download test 9 +Start download test 3 +End download test 1 +End download test 2 +End download test 3 +End download test 5 +End download test 0 +End download test 7 +End download test 6 +End download test 8 +End download test 9 +End download test 4 +End multi download test... end_time: Instant { tv_sec: 1049311, tv_nsec: 147842875 } +Task-9 multi download test duration: 115.8157805s +Average multi download test duration: 117793 \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs b/ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs new file mode 100644 index 0000000..a4f4b00 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs @@ -0,0 +1,101 @@ +#![allow(unused)] + +use s3::creds::Credentials; +use s3::region::Region; +use s3::error::S3Error; +use s3::{bucket::Bucket, BucketConfiguration}; +use chrono::Utc; +use std::time::Instant; + +async fn test_download(id:usize) -> Result<(), S3Error> { + println!("Start download test {:?}", id); + + let bucket_name = "hackathon"; + let region = Region::Custom { + region: "".to_owned(), + endpoint: "http://127.0.0.1:39000".to_owned(), + }; + let credentials = Credentials::new( + Some("hackathon".to_owned().as_str()), + Some("hackathon".to_owned().as_str()), + None, + None, + None, + )?; + + let mut bucket = + Bucket::new(bucket_name, region.clone(), credentials.clone())?.with_path_style(); + + if !bucket.exists().await? { + bucket = Bucket::create_with_path_style( + bucket_name, + region, + credentials, + BucketConfiguration::default(), + ) + .await? + .bucket; + } + + let filename = "output_10MB.txt"; + // let start_time = Instant::now(); + // Get meta data + let (meta, code) = bucket.head_object(filename).await?; + println!("meta: {:?}", meta); + + // let res = bucket.get_object(filename).await?; + // println!("get object: {:?}", res); + + // Get object range + let file_size = meta.content_length.unwrap(); + let step = 128 * 1024; // 128KB + let mut start = 0; + let mut end = step; + // let buf = Vec::new(); + while start < file_size { + if end > file_size { + end = file_size; + } + let res = bucket.get_object_range(filename, start.try_into().unwrap(), Some(end.try_into().unwrap())).await.unwrap(); + println!("get object range: {:?}", res); + // buf.extend_from_slice(&res); + start += step; + end += step; + } + + // 校验下载的文件大小 + // let end_time = Instant::now(); + // let duration = end_time - start_time; + println!("End download test {:?}", id); + + Ok(()) +} + +#[tokio::main] +async fn main() -> Result<(), S3Error>{ + let mut count = 0; + + for j in 0..1 { + let start_time = Instant::now(); + + println!("Start multi download test... start_time: {:?}", start_time); + let mut tasks = Vec::new(); + for i in 0..1 { + tasks.push(tokio::spawn(test_download(i))); + } + for task in tasks { + task.await; + } + + let end_time = Instant::now(); + let duration = end_time - start_time; + println!("End multi download test... end_time: {:?}", end_time); + println!("Task-{:?} multi download test duration: {:?}", j, duration); + + count += duration.as_millis(); + } + + println!("Average multi download test duration: {:?}", count/10); + + Ok(()) +} diff --git a/ruan_lao_shi_xiao_fen_dui/genfile/.gitignore b/ruan_lao_shi_xiao_fen_dui/genfile/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/genfile/.gitignore @@ -0,0 +1 @@ +/target diff --git a/ruan_lao_shi_xiao_fen_dui/genfile/Cargo.lock b/ruan_lao_shi_xiao_fen_dui/genfile/Cargo.lock new file mode 100644 index 0000000..9ecb589 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/genfile/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "genfile" +version = "0.1.0" diff --git a/ruan_lao_shi_xiao_fen_dui/genfile/Cargo.toml b/ruan_lao_shi_xiao_fen_dui/genfile/Cargo.toml new file mode 100644 index 0000000..bdc15b0 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/genfile/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "genfile" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs b/ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs new file mode 100644 index 0000000..1ab1e2f --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs @@ -0,0 +1,34 @@ +use std::fs::File; +use std::io::prelude::*; +use std::io::BufWriter; + +fn main() { + let file_size = 10 * 1024 * 1024; // 200MB + let file_path = "output_10MB.txt"; + + // 创建文件并打开写入模式 + let file = File::create(file_path).expect("无法创建文件"); + let mut writer = BufWriter::new(file); + + let mut bytes_written = 0; + let buffer_size = 1024; // 每次写入的缓冲区大小 + + // 持续写入数据,直到达到目标文件大小 + while bytes_written < file_size { + let remaining_bytes = file_size - bytes_written; + let bytes_to_write = std::cmp::min(buffer_size, remaining_bytes); + + // 创建一个缓冲区并填充为 ASCII 字符 'A' + let buffer: Vec = vec![b'A'; bytes_to_write]; + + // 将缓冲区写入文件 + writer.write_all(&buffer).expect("写入文件时发生错误"); + + bytes_written += bytes_to_write; + } + + // 刷新缓冲区并写入文件 + writer.flush().expect("刷新缓冲区时发生错误"); + + println!("生成的文件大小为 {}MB", file_size / (1024 * 1024)); +} \ No newline at end of file From e2f5c1147ff09e4bf5891a8b354251f0bd241258 Mon Sep 17 00:00:00 2001 From: Bo Date: Sat, 16 Dec 2023 00:24:43 +0800 Subject: [PATCH 2/6] feat: Add p2p implement. --- .../p2p-with-tracker/.gitignore | 1 + .../p2p-with-tracker/.vscode/settings.json | 5 + .../p2p-with-tracker/Cargo.lock | 2544 +++++++++++++++++ .../p2p-with-tracker/Cargo.toml | 50 + .../p2p-with-tracker/config.toml | 18 + .../p2p-with-tracker/rustfmt.toml | 11 + .../p2p-with-tracker/src/config.rs | 60 + .../p2p-with-tracker/src/constant.rs | 10 + .../p2p-with-tracker/src/lib.rs | 4 + .../p2p-with-tracker/src/logger.rs | 77 + .../p2p-with-tracker/src/main.rs | 62 + .../p2p-with-tracker/src/server/error.rs | 44 + .../p2p-with-tracker/src/server/logic/file.rs | 332 +++ .../p2p-with-tracker/src/server/logic/mod.rs | 4 + .../p2p-with-tracker/src/server/logic/node.rs | 61 + .../src/server/logic/session.rs | 1 + .../src/server/logic/tracker.rs | 15 + .../p2p-with-tracker/src/server/mod.rs | 122 + .../src/server/node/api/file.rs | 49 + .../src/server/node/api/info.rs | 37 + .../src/server/node/api/mod.rs | 17 + .../src/server/node/api/node.rs | 80 + .../src/server/node/client/file.rs | 125 + .../src/server/node/client/mod.rs | 4 + .../src/server/node/client/node.rs | 65 + .../src/server/node/client/piece.rs | 71 + .../src/server/node/client/session.rs | 67 + .../p2p-with-tracker/src/server/node/mod.rs | 3 + .../src/server/node/task/check.rs | 72 + .../src/server/node/task/mod.rs | 1 + .../src/server/store/helper.rs | 99 + .../p2p-with-tracker/src/server/store/mod.rs | 28 + .../p2p-with-tracker/src/server/store/node.rs | 98 + .../src/server/store/piece.rs | 431 +++ .../src/server/store/session.rs | 102 + .../src/server/tracker/api/cluster.rs | 44 + .../src/server/tracker/api/file.rs | 97 + .../src/server/tracker/api/info.rs | 43 + .../src/server/tracker/api/mod.rs | 20 + .../src/server/tracker/api/node.rs | 42 + .../src/server/tracker/mod.rs | 2 + .../src/server/tracker/task/check.rs | 50 + .../src/server/tracker/task/mod.rs | 1 + .../p2p-with-tracker/src/server/utils/mod.rs | 2 + .../src/server/utils/s3_helper.rs | 165 ++ .../src/server/utils/time_helper.rs | 11 + .../p2p-with-tracker/test.sh | 6 + 47 files changed, 5253 insertions(+) create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.gitignore create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.vscode/settings.json create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.lock create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.toml create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/rustfmt.toml create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/config.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/constant.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/lib.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/logger.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/main.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/error.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/file.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/node.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/session.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/tracker.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/file.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/info.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/node.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/file.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/node.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/piece.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/session.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/check.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/helper.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/node.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/piece.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/session.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/cluster.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/file.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/info.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/node.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/check.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/mod.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/s3_helper.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/time_helper.rs create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/test.sh diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.gitignore b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.gitignore @@ -0,0 +1 @@ +/target diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.vscode/settings.json b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.vscode/settings.json new file mode 100644 index 0000000..352a626 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.linkedProjects": [ + "./Cargo.toml" + ] +} \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.lock b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.lock new file mode 100644 index 0000000..4a20474 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.lock @@ -0,0 +1,2544 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "async-compression" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "attohttpc" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f77d243921b0979fbbd728dd2d5162e68ac8252976797c24eb5b3a6af9090dc" +dependencies = [ + "http", + "log", + "native-tls", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "aws-creds" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390ad3b77f3e21e01a4a0355865853b681daf1988510b0b15e31c0c4ae7eb0f6" +dependencies = [ + "attohttpc", + "home", + "log", + "quick-xml", + "rust-ini", + "serde", + "thiserror", + "time", + "url", +] + +[[package]] +name = "aws-region" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42fed2b9fca70f2908268d057a607f2a906f47edbf856ea8587de9038d264e22" +dependencies = [ + "thiserror", +] + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "multer", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-server" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bace45b270e36e3c27a190c65883de6dfc9f1d18c829907c127464815dc67b24" +dependencies = [ + "arc-swap", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-unit" +version = "4.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" +dependencies = [ + "serde", + "utf8-width", +] + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.5", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_derive", + "clap_lex", + "indexmap 1.9.3", + "once_cell", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "const-random" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaf16c9c2c612020bcfd042e170f6e32de9b9d75adb5277cdbbd2e2c8c8299a" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deranged" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +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 = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "iri-string" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78" +dependencies = [ + "nom", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "maybe-async" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minidom" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f45614075738ce1b77a1768912a60c0227525971b03e09122a05b8a34a2a6278" +dependencies = [ + "rxml", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "memchr", + "mime", + "spin 0.9.8", + "version_check", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.3", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-multimap" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" +dependencies = [ + "dlv-list", + "hashbrown 0.13.2", +] + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p2p-with-tracker" +version = "0.1.0" +dependencies = [ + "anyhow", + "axum", + "axum-server", + "backtrace", + "byte-unit", + "chrono", + "clap", + "hyper", + "lazy_static", + "parking_lot 0.11.2", + "rand", + "reqwest", + "rust-s3", + "serde", + "serde_json", + "thiserror", + "tokio", + "toml", + "tower-http", + "tracing", + "tracing-subscriber", + "uuid", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "rust-ini" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rust-s3" +version = "0.34.0-rc4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0533896b025761b23147ca1a168c436e1b87d14e460b1f19a6442882d2a3e07f" +dependencies = [ + "async-trait", + "aws-creds", + "aws-region", + "base64 0.21.5", + "bytes", + "cfg-if", + "futures", + "hex", + "hmac", + "http", + "hyper", + "hyper-tls", + "log", + "maybe-async", + "md5", + "minidom", + "native-tls", + "percent-encoding", + "quick-xml", + "serde", + "serde_derive", + "serde_json", + "sha2", + "thiserror", + "time", + "tokio", + "tokio-native-tls", + "tokio-stream", + "url", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rxml" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98f186c7a2f3abbffb802984b7f1dfd65dac8be1aafdaabbca4137f53f0dff7" +dependencies = [ + "bytes", + "rxml_validation", + "smartstring", +] + +[[package]] +name = "rxml_validation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +dependencies = [ + "proc-macro2", + "quote", + "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 = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "termcolor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "async-compression", + "base64 0.13.1", + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "uuid", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "getrandom", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.41", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[package]] +name = "web-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +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 = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +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 = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.toml b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.toml new file mode 100644 index 0000000..552bd80 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "p2p-with-tracker" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# Http server +# axum = { version = "0.7" } +axum = { version = "0.6.0-rc.2", features = ["http2", "multipart"] } +axum-server = { version = "0.4", features = ["tls-rustls"] } +# axum-extra = { version = "0.9", features = ["typed-header"] } +tower-http = { version = "0.3", features = ["full"] } +hyper = { version = "0.14", features = ["full"] } +byte-unit = "4.0" +reqwest = { version="0.11", features=["json", "multipart"]} + +# Errors +anyhow = "1.0" +thiserror = "1.0" + +# Serialization +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + +# Object storage +rust-s3 = {version = "0.34.0-rc4"} +tokio = { version = "1.19.2", features = ["full"] } +chrono = { version = "0.4.19", features = ["serde"] } + +# Logger +tracing = { version = "0.1", features = ["max_level_debug", "release_max_level_info", "log"] } +tracing-subscriber = "0.3" +# Backtrace in panic hook +backtrace = "0.3" + +# Generate uuid +uuid = { version = "1.2", features = ["v4"] } +rand = "0.8.4" + +# Config +toml = "0.5" + +# Command +clap = { version = "3.2", features = ["derive"] } + +# lazy_static +lazy_static = "1.4" +parking_lot = "0.11" \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml new file mode 100644 index 0000000..628a78d --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml @@ -0,0 +1,18 @@ +[http] +host = "127.0.0.1" +trackerPort = 38080 +rangePortStart = 48000 # for node server port +rangePortEnd = 49000 +cors = [ "localhost:38080" ] # CORS domains + +[p2p] +pieceSize = 131072 # 128KB +sessionExpireTime = 10 # seconds +sessionCheckTime = 3 # seconds + +[s3] +endpoint = "http://81.69.26.72:39000" +bucket = "hackathon" +region = "" +accessKey = "hackathon" +secretKey = "hackathon" \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/rustfmt.toml b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/rustfmt.toml new file mode 100644 index 0000000..03f625c --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/rustfmt.toml @@ -0,0 +1,11 @@ +# https://rust-lang.github.io/rustfmt + +# stable +edition = "2021" +newline_style = "Unix" +match_block_trailing_comma = true + +# nightly +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +format_code_in_doc_comments = true diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/config.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/config.rs new file mode 100644 index 0000000..f54300d --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/config.rs @@ -0,0 +1,60 @@ +use std::fs; + +use serde::Deserialize; + +#[derive(Debug, Clone, Deserialize)] +pub struct Config { + pub http: ConfigHttp, + pub p2p: ConfigP2p, + pub s3: ConfigS3, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ConfigHttp { + pub host: String, + pub tracker_port: u16, + pub range_port_start: u16, + pub range_port_end: u16, + pub cors: Vec, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ConfigP2p { + pub piece_size: u64, + pub session_expire_time: u64, + pub session_check_time: u64, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ConfigS3 { + pub endpoint: String, + pub bucket: String, + pub region: String, + pub access_key: String, + pub secret_key: String, +} + +impl Config { + /// Parse configuration file. + pub fn parse(path: &str) -> anyhow::Result { + let config_str = fs::read_to_string(path)?; + + let config = toml::from_str(&config_str)?; + + Ok(config) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + /// Test default configuration file. + #[test] + fn test_config() { + Config::parse("./config.toml").expect("Failed to parse configuration file"); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/constant.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/constant.rs new file mode 100644 index 0000000..1693f39 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/constant.rs @@ -0,0 +1,10 @@ +/// Default configuration file. +pub const DEFAULT_CONFIG_FILE: &str = "config.toml"; +/// Default configuration file content. +pub static DEFAULT_CONFIG_CONTENT: &[u8] = include_bytes!("../config.toml"); +/// Default mode +pub const DEFAULT_SERVER_MODE: &str = "tracker"; // "tracker" or "node" +pub const SERVER_MODE_TRACKER: &str = "tracker"; // Tracker mode +pub const SERVER_MODE_NODE: &str = "node"; // Node mode +/// Default filename +pub const DEFAULT_FILENAME: &str = "output_10MB.txt"; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/lib.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/lib.rs new file mode 100644 index 0000000..46e13da --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/lib.rs @@ -0,0 +1,4 @@ +pub mod config; +pub mod constant; +pub mod logger; +pub mod server; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/logger.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/logger.rs new file mode 100644 index 0000000..084affe --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/logger.rs @@ -0,0 +1,77 @@ +//! Initialize logger. + +use std::{panic, thread}; + +use tracing::{error, level_filters::LevelFilter}; + +#[cfg(debug_assertions)] +const MAX_LEVEL: LevelFilter = LevelFilter::DEBUG; + +#[cfg(not(debug_assertions))] +const MAX_LEVEL: LevelFilter = LevelFilter::INFO; + +/// Initialize logger (tracing and panic hook). +pub fn init() { + tracing_subscriber::fmt().with_max_level(MAX_LEVEL).init(); + + // catch panic and log them using tracing instead of default output to StdErr + panic::set_hook(Box::new(|info| { + let thread = thread::current(); + let thread = thread.name().unwrap_or("unknown"); + + let msg = match info.payload().downcast_ref::<&'static str>() { + Some(s) => *s, + None => match info.payload().downcast_ref::() { + Some(s) => &**s, + None => "Box", + }, + }; + + let backtrace = backtrace::Backtrace::new(); + + match info.location() { + Some(location) => { + // without backtrace + if msg.starts_with("notrace - ") { + error!( + target: "panic", "thread '{}' panicked at '{}': {}:{}", + thread, + msg.replace("notrace - ", ""), + location.file(), + location.line() + ); + } + // with backtrace + else { + error!( + target: "panic", "thread '{}' panicked at '{}': {}:{}\n{:?}", + thread, + msg, + location.file(), + location.line(), + backtrace + ); + } + }, + None => { + // without backtrace + if msg.starts_with("notrace - ") { + error!( + target: "panic", "thread '{}' panicked at '{}'", + thread, + msg.replace("notrace - ", ""), + ); + } + // with backtrace + else { + error!( + target: "panic", "thread '{}' panicked at '{}'\n{:?}", + thread, + msg, + backtrace + ); + } + }, + } + })); +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/main.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/main.rs new file mode 100644 index 0000000..8fef6aa --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/main.rs @@ -0,0 +1,62 @@ +//! Datenlord p2p server +//! + +use std::{fs::File, io::Write, path::Path}; + +use clap::Parser; + +use tracing::{info, warn}; + +use p2p_with_tracker::config::Config; +use p2p_with_tracker::constant::*; +use p2p_with_tracker::logger; +use p2p_with_tracker::server; + +#[derive(Debug, Parser)] +#[clap( + name = env!("CARGO_PKG_NAME"), + about = env!("CARGO_PKG_DESCRIPTION"), + version = env!("CARGO_PKG_VERSION"), +)] +struct Cli { + #[clap(short = 'c', long = "config", help = "Configuration file path", default_value = DEFAULT_CONFIG_FILE, display_order = 1)] + config: String, + #[clap(short = 'm', long = "mode", help = "Server running mode", default_value = DEFAULT_SERVER_MODE, display_order = 2)] + mode: String, + #[clap(short = 'f', long = "filename", help = "Download s3 filename", default_value = DEFAULT_FILENAME, display_order = 3)] + filename: String, +} + +#[tokio::main] +async fn main() { + logger::init(); + + let args = Cli::parse(); + + let config_path = args.config; + + // if configuration file doesn't exist, create it + if !Path::new(&config_path).exists() { + warn!("Configuration file doesn't exists."); + + let mut file = + File::create(config_path).expect("notrace - Failed to create configuration file"); + + file.write_all(DEFAULT_CONFIG_CONTENT) + .expect("notrace - Failed to write default configuration to config file"); + + info!("Created configuration file. Exiting..."); + + std::process::exit(0); + } + + let mut config = + Config::parse(&config_path).expect("notrace - Failed to parse configuration file"); + + // Print configuration + info!("Configuration: {:?}", config); + + server::start_server(&mut config, args.mode, args.filename) + .await + .expect("notrace - HTTP Server error"); +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/error.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/error.rs new file mode 100644 index 0000000..8348252 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/error.rs @@ -0,0 +1,44 @@ +use serde::Serialize; +use thiserror::Error; +use tracing::error; + +#[derive(Debug, Error)] +pub enum Error { + // `/tracker` error + #[error("Parameter is missing.")] + ParamMissing, + #[error("Fetch metadata failed.")] + FetchMetadataFailed, + + // `/node` error + #[error("Fetch seed info failed.")] + FetchSeedInfoFailed, + #[error("Download file failed.")] + DownloadFailed, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "kebab-case")] +enum ResponseError { + Error(String), +} + +impl axum::response::IntoResponse for Error { + fn into_response(self) -> axum::response::Response { + use axum::http::StatusCode; + + #[cfg(debug_assertions)] + error!("Error: {:?}", self); + + let status = match self { + _ => StatusCode::BAD_REQUEST, + }; + + let mut response = axum::Json(ResponseError::Error(self.to_string())).into_response(); + *response.status_mut() = status; + + response + } +} + +pub type Result = std::result::Result; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/file.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/file.rs new file mode 100644 index 0000000..9f1d8c8 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/file.rs @@ -0,0 +1,332 @@ +use core::fmt; + +use chrono::format; +use rand::seq::SliceRandom; +use serde::{Serialize, Deserialize}; +use tracing::{debug, info}; + +use crate::server::error::*; +use crate::server::node::client::file::{FileClient, self}; +use crate::server::node::client::node::NodeClient; +use crate::server::node::client::piece::PieceClient; +use crate::server::store::piece::PieceInfo; +use crate::server::store::{ + FINISHED_NODE_CACHE, GLOBAL_TIMESTAMP_CACHE, NODE_INFO_CACHE, PIECE_INFO_CACHE, + PIECE_NODE_INFO_CACHE, SEED_INFO_CACHE, NODE_ID, PIECE_CACHE, +}; +use crate::server::utils::s3_helper::S3Client; +use crate::server::utils::time_helper::get_current_timestamp; +use crate::{config::Config, server::store::piece::SeedInfo}; + +pub async fn fetch_seed(config: Config, filename: &str) -> Result { + // Get seed from cache + match SEED_INFO_CACHE.get(&filename.to_string()) { + Some(seed_info) => { + debug!("Fetch seed info from cache: {:?}", seed_info); + return Ok(seed_info); + }, + None => { + debug!("Fetch seed info from s3"); + }, + } + + let endpoint = config.s3.endpoint; + let bucket = config.s3.bucket; + let region = config.s3.region; + let access_key = config.s3.access_key; + let secret_key = config.s3.secret_key; + + let client = S3Client::new(endpoint, bucket, region, access_key, secret_key); + let metadata = match client.get_object_metadata(filename.to_string()).await { + Ok(metadata) => metadata, + Err(e) => { + return Err(Error::FetchMetadataFailed); + }, + }; + let mut pieces: Vec = vec![]; + let mut piece_size = config.p2p.piece_size; + + let file_size = metadata.content_length.unwrap() as u64; + let mut start = 0; + let mut end = piece_size; + while start < file_size { + if end > file_size { + end = file_size; + piece_size = end - start; + } + let checksum = uuid::Uuid::new_v4(); + let piece: PieceInfo = PieceInfo::new( + filename.to_string(), + start as u32, + piece_size as u32, + checksum.to_string(), + ); + pieces.push(piece.clone()); + + // Update to piece info cache + PIECE_INFO_CACHE.set(checksum.to_string(), piece.clone()); + + // Iterate to next piece + start += piece_size; + end += piece_size; + } + + let seed_info: SeedInfo = SeedInfo::new( + filename.to_string(), + metadata.content_length.unwrap_or_default() as u32, + pieces, + ); + SEED_INFO_CACHE.set(filename.to_string(), seed_info.clone()); + + Ok(seed_info) +} + +pub async fn progress_report( + node_id: &str, + piece_id: &str, + progress: f64, + filename: &str, +) -> Result<()> { + PIECE_NODE_INFO_CACHE.set(piece_id.to_string(), node_id.to_string()); + + // Calc finish time + #[cfg(debug_assertions)] + { + calc_download_time(node_id, progress).await; + } + + Ok(()) +} + +pub async fn calc_download_time(node_id: &str, progress: f64) { + if progress >= 1.0 { + FINISHED_NODE_CACHE.insert(node_id.to_string()); + } + + // check if all online nodes finished + let nodes = NODE_INFO_CACHE.get_all_node_id(); + for node in nodes { + if !FINISHED_NODE_CACHE.contains(&node) { + return; + } + } + + match GLOBAL_TIMESTAMP_CACHE.get_last_timestamp() { + Some(timestamp) => { + let current_timestamp = get_current_timestamp(); + let download_time = current_timestamp - timestamp; + debug!("All nodes finished at timestamp: {} ms", download_time) + }, + None => { + debug!("No timestamp found"); + }, + } + + // Update global timestamp + let timestamp = get_current_timestamp(); + // Update current finished time + GLOBAL_TIMESTAMP_CACHE.insert(timestamp); +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct DownloadResult { + pub data: Vec, + pub success_count: f64, + pub failed_count: f64, + pub total_count: f64, +} + +impl DownloadResult { + pub fn new(data: Vec, success_count: f64, failed_count:f64, total_count: f64) -> Self { + DownloadResult { + data: data, + success_count: success_count, + failed_count: failed_count, + total_count: total_count, + } + } + + pub fn get_data(&self) -> Vec { + self.data.clone() + } + + pub fn get_success_count(&self) -> f64 { + self.success_count + } + + pub fn get_failed_count(&self) -> f64 { + self.failed_count + } + + pub fn get_total_count(&self) -> f64 { + self.total_count + } + + pub fn get_progress(&self) -> f64 { + self.success_count / self.total_count + } + + pub fn is_finished(&self) -> bool { + self.get_progress() >= 1.0 + } + + pub fn set_data(&mut self, data: Vec) { + self.data = data; + } + + pub fn set_success_count(&mut self, success_count: f64) { + self.success_count = success_count; + } + + pub fn set_failed_count(&mut self, failed_count: f64) { + self.failed_count = failed_count; + } + + pub fn set_total_count(&mut self, total_count: f64) { + self.total_count = total_count; + } + + pub fn set_progress(&mut self, progress: f64) { + self.success_count = progress * self.total_count; + } +} + +pub async fn download(config: Config, filename: &str) -> Result { + // Fetch seed info + let file_client = FileClient::new( + &config.http.host, + config.http.tracker_port, + ); + let node_client = NodeClient::new( + &config.http.host, + config.http.tracker_port, + ); + let s3_client = S3Client::new( + config.s3.endpoint.to_string(), + config.s3.bucket.to_string(), + config.s3.region.to_string(), + config.s3.access_key.to_string(), + config.s3.secret_key.to_string(), + ); + match file_client.fetch_seed(filename).await { + Ok(seed_info) => { + let seed_info = seed_info.seed_info; + // Save to local memory + SEED_INFO_CACHE.set(filename.to_string(), seed_info.to_owned()); + + let mut pieces = seed_info.get_piece_list(); + let mut shuffled_pieces = seed_info.get_piece_list(); + // shuffle piece list + shuffled_pieces.shuffle(&mut rand::thread_rng()); + debug!("Fetch seed info: {:?}", seed_info); + + let mut success_count: f64 = 0.0; + let mut failed_count: f64 = 0.0; + let total_count: f64 = pieces.len() as f64; + + // Download pieces + for piece in shuffled_pieces { + let piece_id = piece.get_checksum().clone(); + let mut piece_node_list: Vec = Vec::new(); + // Fetch piece node info cache + match node_client.node_list(piece_id.as_str()).await { + Ok(node_list) => { + debug!("Fetch node list: {:?}", node_list); + piece_node_list = node_list.node_list; + }, + Err(e) => { + debug!("Fetch node list failed: {:?}", e); + continue; + }, + } + + // 1. Check if the piece is downloaded or not + if PIECE_INFO_CACHE.contains(&piece_id) { + debug!("Piece: {:?} is already downloaded", piece); + success_count+=1.0; + continue; + } + + // Fetch piece from S3 or node + if piece_node_list.len() == 0 { + debug!("No node found for piece: {:?} from tracker", piece_id); + + // Download from s3 + let start = piece.get_index() as u64; + let end = start + piece.get_size() as u64; + match s3_client.get_object_range_data(filename.to_string(), start, end).await { + Ok(data) => { + debug!("Download piece: {:?} from s3 success", piece); + success_count+=1.0; + + // Update piece info cache + PIECE_INFO_CACHE.set(piece_id.clone(), piece.clone()); + PIECE_CACHE.set(piece_id.clone(), data.clone()); + let _ = file_client.report(&NODE_ID, piece_id.as_str(), success_count/total_count, filename).await; + }, + Err(e) => { + debug!("Download piece: {:?} from s3 failed", piece); + continue; + }, + } + } else { + // Download from node + // Iterate node list to fetch data + for node_addr in piece_node_list { + // TODO: Skip current node + // if node_addr.eq(format!("{}:{}", config.http.host, config.http.port).as_str()) { + // continue; + // } + + // Fetch piece data from node + let piece_client = PieceClient::new(node_addr.as_str()); + + match piece_client.fetch_piece(&piece_id).await { + Ok(response) => { + if response.data.is_empty() { + continue; + } + + debug!("Download piece: {:?} from node addr: {:?} success", piece, node_addr); + success_count+=1.0; + + // Update piece info cache + PIECE_INFO_CACHE.set(piece_id.clone(), piece.clone()); + PIECE_CACHE.set(piece_id.clone(), response.data.clone()); + let _ = file_client.report(&NODE_ID, piece_id.as_str(), success_count/total_count, filename).await; + break; + }, + Err(e) => { + debug!("Download piece: {:?} from node addr: {:?} failed", piece, node_addr); + failed_count+=1.0; + continue; + }, + } + } + } + } + + // Assemble pieces + let mut file = vec![]; + for piece in pieces { + let piece_id: String = piece.get_checksum().clone(); + match PIECE_CACHE.get(&piece_id.clone()) { + Some(piece) => { + file.extend(piece); + }, + None => { + debug!("Piece: {:?} not found", piece); + continue; + }, + } + } + + // return download result + let download_result = DownloadResult::new(file, success_count, failed_count, total_count); + return Ok(download_result); + }, + Err(e) => { + return Err(Error::FetchSeedInfoFailed); + }, + } +} \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/mod.rs new file mode 100644 index 0000000..fa208a3 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/mod.rs @@ -0,0 +1,4 @@ +pub mod file; +pub mod node; +pub mod session; +pub mod tracker; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/node.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/node.rs new file mode 100644 index 0000000..5bc69d2 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/node.rs @@ -0,0 +1,61 @@ +use tracing::debug; + +use crate::server::error::*; +use crate::server::store::{ + piece, GLOBAL_TIMESTAMP_CACHE, NODE_INFO_CACHE, PIECE_NODE_INFO_CACHE, SESSION_INFO_CACHE, +}; +use crate::server::utils::time_helper::get_current_timestamp; + +pub async fn update_session(node_id: &str) -> Result<()> { + let timestamp = get_current_timestamp(); + + // Check if node is the first to connect + #[cfg(debug_assertions)] + { + let is_empty = NODE_INFO_CACHE.is_empty(); + if is_empty { + debug!( + "Node {} is first time to connect - timestamp:{}", + node_id, timestamp + ); + + // Update global time + GLOBAL_TIMESTAMP_CACHE.insert(timestamp); + } + } + + SESSION_INFO_CACHE.set(node_id.to_string(), timestamp); + + Ok(()) +} + +pub async fn add_node(node_id: &str, addr: &str) -> Result<()> { + NODE_INFO_CACHE.set(node_id.to_string(), addr.to_string()); + + Ok(()) +} + +pub async fn get_piece_node_list(piece_id: &str) -> Result> { + let node_list = match PIECE_NODE_INFO_CACHE.get_node_list(&piece_id.to_string()) { + Some(node_list) => { + // Convert to addr list + let mut addr_list = vec![]; + for node_id in node_list.iter() { + match NODE_INFO_CACHE.get_addr(node_id) { + Some(addr) => { + addr_list.push(addr); + } + None => { + debug!("Node {} is not online", node_id); + } + } + } + return Ok(addr_list); + }, + None => { + vec![] + }, + }; + + Ok(node_list) +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/session.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/session.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/session.rs @@ -0,0 +1 @@ + diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/tracker.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/tracker.rs new file mode 100644 index 0000000..fc141b1 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/logic/tracker.rs @@ -0,0 +1,15 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + +use crate::server::error::*; +use crate::server::store::{ + NODE_INFO_CACHE, PIECE_INFO_CACHE, PIECE_NODE_INFO_CACHE, SESSION_INFO_CACHE, +}; + +pub async fn get_tracker_info() -> Result<()> { + let session_info = SESSION_INFO_CACHE.get_all(); + let node_info = NODE_INFO_CACHE.get_all(); + let piece_node_info = PIECE_NODE_INFO_CACHE.get_piece_info(); + let piece_info = PIECE_INFO_CACHE.get_all(); + + Ok(()) +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/mod.rs new file mode 100644 index 0000000..900bf1b --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/mod.rs @@ -0,0 +1,122 @@ +pub mod error; +pub mod logic; +pub mod node; +pub mod store; +pub mod tracker; +pub mod utils; + +use std::{ + path::{Path, PathBuf}, + process::exit, +}; + +use anyhow::anyhow; +use axum::{ + extract::Host, + handler::HandlerWithoutStateExt, + http::{HeaderValue, StatusCode, Uri}, + response::Redirect, + routing::get, + Extension, Router, +}; +use axum_server::tls_rustls::RustlsConfig; +use hyper::header::SERVER; +use rand::Rng; +use tower_http::{ + cors::{AllowOrigin, CorsLayer}, + BoxError, +}; +use tracing::{debug, error, info}; + +use crate::constant::*; +use crate::server::store::NODE_ID; +use crate::{ + config::Config, + server::{node::task::check::HeartBeatTask, tracker::task::check::CheckTask}, +}; + +pub async fn start_server( + config: &mut Config, + mode: String, + filename: String, +) -> anyhow::Result<()> { + let mut port = config.http.tracker_port; + let mut app = Router::new(); + + // Get router and port + match mode.as_str() { + SERVER_MODE_TRACKER => { + app = create_tracker_router(config.to_owned()).await; + CheckTask::new( + &NODE_ID, + config.p2p.session_check_time, + config.p2p.session_expire_time, + ) + .start(); + }, + SERVER_MODE_NODE => { + app = create_node_router(config.to_owned()).await; + // Get random port + port = rand::thread_rng().gen_range( + config.http.range_port_start.clone()..config.http.range_port_end.clone(), + ); + HeartBeatTask::new( + config.to_owned(), + &NODE_ID, + format!("{}:{}", config.http.host, port).as_str(), + config.p2p.session_check_time, + ) + .start(); + }, + _ => { + error!("Invalid server mode"); + exit(1); + }, + } + + let host = format!("{}:{}", config.http.host, port); + + info!( + "🚀🚀🚀 Server [{}:{}] has launched on http://{}", + mode, + NODE_ID.as_str(), + host + ); + + // change the type from Vec to Vec so that the http server can correctly detect CORS hosts + let origins = config + .http + .cors + .iter() + .map(|e| e.parse().expect("Failed to parse CORS hosts")) + .collect::>(); + app = app.layer(CorsLayer::new().allow_origin(AllowOrigin::list(origins))); + + // start http server + axum::Server::bind(&host.parse().unwrap()) + .serve(app.into_make_service()) + .await + .unwrap(); + + Err(anyhow!("Server unexpected stopped!")) +} + +pub async fn create_tracker_router(config: Config) -> Router<()> { + let app = Router::new() + .nest("/api/v1", tracker::api::app()) + .route("/", get(tracker::api::health)) + // .layer(CorsLayer::new().allow_origin(AllowOrigin::list(origins))) + .layer(Extension(config.clone())); + + app +} + +pub async fn create_node_router(config: Config) -> Router<()> { + let app = Router::new() + .nest("/api/v1", node::api::app()) + .route("/", get(node::api::health)) + // .layer(CorsLayer::new().allow_origin(AllowOrigin::list(origins))) + .layer(Extension(config.clone())); + + app +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/file.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/file.rs new file mode 100644 index 0000000..1a9140e --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/file.rs @@ -0,0 +1,49 @@ +use axum::{Extension, Json}; +use hyper::StatusCode; +use serde::{Deserialize, Serialize}; +use tracing::{debug, info, log::LevelFilter}; + +use crate::config::Config; +use crate::server::error::*; +use crate::server::store::PIECE_CACHE; + +pub async fn fetch_piece( + Extension(config): Extension, + Json(request): Json, +) -> Result> { + debug!( + "Receive fetch piece pieceId: {piece_id}", + piece_id = request.piece_id, + ); + + match PIECE_CACHE.get(&request.piece_id) { + Some(piece) => { + let response = FetchPieceResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + data: piece, + }; + return Ok(Json(response)) + } + None => { + let response = FetchPieceResponse { + code: StatusCode::OK.to_string(), + msg: "Not find".to_string(), + data: vec![], + }; + return Ok(Json(response)) + } + } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FetchPieceRequest { + pub piece_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FetchPieceResponse { + pub code: String, + pub msg: String, + pub data: Vec, +} \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/info.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/info.rs new file mode 100644 index 0000000..d75acd0 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/info.rs @@ -0,0 +1,37 @@ +use std::collections::HashSet; + +use axum::{Extension, Json}; +use hyper::StatusCode; +use serde::{Deserialize, Serialize}; +use tracing::{debug, info, log::LevelFilter}; + +use crate::config::Config; +use crate::server::error::*; +use crate::server::store::piece::{PieceInfo, PieceId}; +use crate::server::store::{ + NODE_INFO_CACHE, PIECE_INFO_CACHE, PIECE_NODE_INFO_CACHE, SESSION_INFO_CACHE, PIECE_CACHE, SEED_INFO_CACHE, +}; + +pub async fn info(Extension(config): Extension) -> Result> { + debug!("Get node info"); + + let piece_info_cache: Vec<(PieceId, PieceInfo)> = PIECE_INFO_CACHE.get_all(); + let piece_cache: Vec<(String, Vec)> = PIECE_CACHE.get_all(); + + let response = InfoResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + piece_info_cache, + piece_cache, + }; + + Ok(Json(response)) +} + +#[derive(Serialize, Deserialize)] +pub struct InfoResponse { + pub code: String, + pub msg: String, + pub piece_info_cache: Vec<(PieceId, PieceInfo)>, + pub piece_cache: Vec<(String, Vec)>, +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/mod.rs new file mode 100644 index 0000000..c46abcf --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/mod.rs @@ -0,0 +1,17 @@ +pub mod info; +pub mod file; +pub mod node; + +use axum::routing::*; + +pub async fn health() -> &'static str { + "Node is running!" +} + +pub fn app() -> Router { + Router::new() + .route("/start_download", post(node::start_download)) + .route("/fetch_piece", post(file::fetch_piece)) + .route("/info", get(info::info)) + .route("/health", get(health)) +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/node.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/node.rs new file mode 100644 index 0000000..8663052 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/api/node.rs @@ -0,0 +1,80 @@ +use std::fs; + +use axum::{Extension, Json}; +use hyper::StatusCode; +use serde::{Deserialize, Serialize}; +use tracing::{debug, info, log::LevelFilter}; + +use crate::config::Config; +use crate::server::error::*; +use crate::server::logic::file; + +// Start download +pub async fn start_download( + Extension(config): Extension, + Json(request): Json, +) -> Result> { + info!( + "Receive start download request with filename: {filename}", + filename = request.filename, + ); + + #[cfg(debug_assertions)] + { + // Sync in debug mode + match file::download(config, &request.filename.as_str()).await { + Ok(file) => { + info!("Download success!"); + + let response = StartDownloadResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + success_count: file.success_count as f64, + failed_count: file.failed_count as f64, + total_count: file.total_count as f64, + }; + + fs::write(request.filename.as_str(), file.data).unwrap(); + + return Ok(Json(response)) + }, + Err(e) => { + info!("Download failed!"); + }, + } + + // Check if the file is downloaded or not + } + + #[cfg(not(debug_assertions))] + { + // Async in release mode + tokio::spawn(async move { + file::download(&request.filename.as_str()).await.unwrap(); + }); + } + + let response = StartDownloadResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + success_count: 0.0, + failed_count: 0.0, + total_count: 0.0, + }; + + Ok(Json(response)) +} + +#[derive(Debug, Deserialize)] +pub struct StartDownloadRequest { + pub filename: String, +} + +#[derive(Serialize, Deserialize)] +pub struct StartDownloadResponse { + pub code: String, + pub msg: String, + pub success_count: f64, + pub failed_count: f64, + pub total_count: f64, +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/file.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/file.rs new file mode 100644 index 0000000..58b823d --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/file.rs @@ -0,0 +1,125 @@ +use reqwest::Client; +use serde::{Deserialize, Serialize}; + +use reqwest::Error; + +use crate::server::store::piece::SeedInfo; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FileClient { + host: String, + port: u16, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ReportRequest { + pub node_id: String, + pub piece_id: String, + pub progress: f64, + pub filename: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ReportResponse { + pub code: String, + pub msg: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FetchSeedRequest { + pub filename: String, +} + +#[derive(Serialize, Deserialize)] +pub struct FetchSeedResponse { + pub code: String, + pub msg: String, + pub seed_info: SeedInfo, +} + +impl FileClient { + pub fn new(host: &str, port: u16) -> Self { + FileClient { + host: host.to_string(), + port: port, + } + } + + pub async fn report( + &self, + node_id: &str, + piece_id: &str, + progress: f64, + filename: &str, + ) -> Result { + let url = format!("http://{}:{}/api/v1/report", self.host, self.port); + let client = Client::new(); + let payload = ReportRequest { + node_id: node_id.to_string(), + piece_id: piece_id.to_string(), + progress: progress, + filename: filename.to_string(), + }; + + let response = client + .post(url) + .header("Content-Type", "application/json") + .json(&payload) + .send() + .await?; + + let response_body: ReportResponse = response.json().await?; + + Ok(response_body) + } + + pub async fn fetch_seed(&self, filename: &str) -> Result { + let url = format!("http://{}:{}/api/v1/fetch_seed", self.host, self.port); + let client = Client::new(); + let payload = FetchSeedRequest { + filename: filename.to_string(), + }; + + let response = client + .post(url) + .header("Content-Type", "application/json") + .json(&payload) + .send() + .await?; + + let response_body: FetchSeedResponse = response.json().await?; + + Ok(response_body) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_report() { + let client = FileClient::new("127.0.0.1", 38080); + + let node_id = "D526D2F5-920F-42A7-B5B9-BC643AC6B71B"; + let piece_id = "D526D2F5-920F-42A7-B5B9-BC643AC6B71B"; + let progress = 0.5; + let filename = "test.txt"; + + let response = client + .report(node_id, piece_id, progress, filename) + .await + .unwrap(); + println!("{:?}", response); + } + + #[tokio::test] + async fn test_fetch_seed() { + let client = FileClient::new("127.0.0.1", 38080); + + let filename = "output_10MB.txt"; + + let response = client.fetch_seed(filename).await.unwrap(); + println!("{:#?}", response.seed_info); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/mod.rs new file mode 100644 index 0000000..47b69ff --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/mod.rs @@ -0,0 +1,4 @@ +pub mod file; +pub mod node; +pub mod session; +pub mod piece; \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/node.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/node.rs new file mode 100644 index 0000000..a939167 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/node.rs @@ -0,0 +1,65 @@ +use reqwest::Client; +use serde::{Deserialize, Serialize}; + +use reqwest::Error; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct NodeClient { + host: String, + port: u16, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct NodeListRequest { + pub piece_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct NodeListResponse { + pub code: String, + pub msg: String, + pub node_list: Vec, +} + +impl NodeClient { + pub fn new(host: &str, port: u16) -> Self { + NodeClient { + host: host.to_string(), + port: port, + } + } + + pub async fn node_list(&self, piece_id: &str) -> Result { + let url = format!("http://{}:{}/api/v1/node_list", self.host, self.port); + let client = Client::new(); + let payload = NodeListRequest { + piece_id: piece_id.to_string(), + }; + + let response = client + .post(url) + .header("Content-Type", "application/json") + .json(&payload) + .send() + .await?; + + let response_body: NodeListResponse = response.json().await?; + + Ok(response_body) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_node_list() { + let client = NodeClient::new("127.0.0.1", 38080); + + let piece_id = "D526D2F5-920F-42A7-B5B9-BC643AC6B71B"; + + let response = client.node_list(piece_id).await.unwrap(); + println!("{:?}", response); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/piece.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/piece.rs new file mode 100644 index 0000000..370ef8a --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/piece.rs @@ -0,0 +1,71 @@ +use reqwest::Client; +use serde::{Deserialize, Serialize}; + +use reqwest::Error; + +use crate::server::store::piece::SeedInfo; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct PieceClient { + endpoint: String, // host:port +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FetchPieceRequest { + pub piece_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FetchPieceResponse { + pub code: String, + pub msg: String, + pub data: Vec, +} + +impl PieceClient { + pub fn new(endpoint: &str) -> Self { + PieceClient { + endpoint: endpoint.to_string(), + } + } + + pub async fn fetch_piece( + &self, + piece_id: &str, + ) -> Result { + let url = format!("http://{}/api/v1/fetch_piece", self.endpoint); + let client = Client::new(); + let payload = FetchPieceRequest { + piece_id: piece_id.to_string(), + }; + + let response = client + .post(url) + .header("Content-Type", "application/json") + .json(&payload) + .send() + .await?; + + let response_body: FetchPieceResponse = response.json().await?; + + Ok(response_body) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_report() { + let client = PieceClient::new("127.0.0.1:48349"); + + let piece_id = "88120779-00bc-4912-a2a5-c53f52297a03"; + + let response = client + .fetch_piece(piece_id) + .await + .unwrap(); + println!("{:?}", response); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/session.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/session.rs new file mode 100644 index 0000000..570b375 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/client/session.rs @@ -0,0 +1,67 @@ +use reqwest::Client; +use serde::{Deserialize, Serialize}; + +use reqwest::Error; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct SessionClient { + host: String, + port: u16, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct HeartBeatRequest { + pub node_id: String, + pub addr: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct HeartBeatResponse { + pub code: String, + pub msg: String, +} + +impl SessionClient { + pub fn new(host: &str, port: u16) -> Self { + SessionClient { + host: host.to_string(), + port: port, + } + } + + pub async fn heart_beat(&self, addr: &str, node_id: &str) -> Result { + let url = format!("http://{}:{}/api/v1/heart_beat", self.host, self.port); + let client = Client::new(); + let payload = HeartBeatRequest { + addr: addr.to_string(), + node_id: node_id.to_string(), + }; + + let response = client + .post(url) + .header("Content-Type", "application/json") + .json(&payload) + .send() + .await?; + + let response_body: HeartBeatResponse = response.json().await?; + + Ok(response_body) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_heart_beat() { + let client = SessionClient::new("127.0.0.1", 38080); + + let addr = "192.168.1.100:3933"; + let node_id = "D526D2F5-920F-42A7-B5B9-BC643AC6B71B"; + + let response = client.heart_beat(addr, node_id).await.unwrap(); + println!("{:?}", response); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/mod.rs new file mode 100644 index 0000000..5901fcd --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/mod.rs @@ -0,0 +1,3 @@ +pub mod api; +pub mod client; +pub mod task; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/check.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/check.rs new file mode 100644 index 0000000..6c39a75 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/check.rs @@ -0,0 +1,72 @@ +use std::thread; +use std::time::Duration; + +use tracing::{debug, info}; + +use crate::config::Config; +use crate::server::node::client::session::SessionClient; +use std::sync::Arc; + +pub struct HeartBeatTask { + config: Config, + node_uuid: String, + node_addr: String, + session_check_time: u64, +} + +impl HeartBeatTask { + pub fn new(config: Config, uuid: &str, addr: &str, session_check_time: u64) -> Self { + Self { + config, + node_uuid: uuid.to_string(), + node_addr: addr.to_string(), + session_check_time, + } + } + + pub fn start(&self) { + let session_check_time = self.session_check_time; + let node_uuid = self.node_uuid.clone(); + let node_addr = self.node_addr.clone(); + let config = Arc::new(self.config.clone()); + + tokio::spawn(async move { + let interval = Duration::from_secs(session_check_time); + + let tracker_host = config.http.host.clone(); + let tracker_port = config.http.tracker_port; + let session_client = SessionClient::new(tracker_host.as_str(), tracker_port); + let session_client = Arc::new(session_client); + + loop { + let node_addr = node_addr.clone(); + let node_uuid = node_uuid.clone(); + let session_client = Arc::clone(&session_client); + + let heartbeat_task = async move { + match session_client + .heart_beat(node_addr.as_str(), node_uuid.as_str()) + .await + { + Ok(_) => { + debug!( + "[HeartBeatTask-Node:{node_uuid}] Send heart beat to tracker", + node_uuid = node_uuid + ); + }, + Err(e) => { + debug!("[HeartBeatTask-Node:{node_uuid}] Send heart beat to tracker failed, error: {error}", node_uuid = node_uuid, error = e); + }, + } + // debug!("[HeartBeatTask-Node:{node_uuid}] Send heart beat to tracker"); + }; + + tokio::pin!(heartbeat_task); + + heartbeat_task.await; + + tokio::time::sleep(interval).await; + } + }); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/mod.rs new file mode 100644 index 0000000..3e8ff0f --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/node/task/mod.rs @@ -0,0 +1 @@ +pub mod check; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/helper.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/helper.rs new file mode 100644 index 0000000..e4c88cf --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/helper.rs @@ -0,0 +1,99 @@ +use std::{collections::HashSet, sync::Arc}; + +use parking_lot::Mutex; + +pub struct FinishedNodeCache { + inner: Arc>>, +} + +impl FinishedNodeCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(HashSet::new())), + } + } + + pub fn insert(&self, node_id: String) { + let mut inner = self.inner.lock(); + inner.insert(node_id); + } + + pub fn remove(&self, node_id: &str) { + let mut inner = self.inner.lock(); + inner.remove(node_id); + } + + pub fn contains(&self, node_id: &str) -> bool { + let inner = self.inner.lock(); + inner.contains(node_id) + } + + pub fn clear(&self) { + let mut inner = self.inner.lock(); + inner.clear(); + } +} + +pub struct GlobalTimestampCache { + inner: Arc>>, +} + +impl GlobalTimestampCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(vec![])), + } + } + + pub fn insert(&self, timestamp: u128) { + let mut inner = self.inner.lock(); + inner.push(timestamp); + } + + pub fn get(&self) -> Vec { + let inner = self.inner.lock(); + inner.clone() + } + + pub fn clear(&self) { + let mut inner = self.inner.lock(); + inner.clear(); + } + + pub fn get_last_timestamp(&self) -> Option { + let inner = self.inner.lock(); + inner.last().cloned() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_finished_node_cache() { + let cache = FinishedNodeCache::new(); + cache.insert("1".to_string()); + cache.insert("2".to_string()); + cache.insert("3".to_string()); + assert!(cache.contains("1")); + assert!(cache.contains("2")); + assert!(cache.contains("3")); + cache.remove("1"); + assert!(!cache.contains("1")); + cache.clear(); + assert!(!cache.contains("2")); + assert!(!cache.contains("3")); + } + + #[test] + fn test_global_timestamp_cache() { + let cache = GlobalTimestampCache::new(); + cache.insert(1); + cache.insert(2); + cache.insert(3); + assert_eq!(cache.get(), vec![1, 2, 3]); + cache.clear(); + assert_eq!(cache.get(), vec![]); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/mod.rs new file mode 100644 index 0000000..f18b933 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/mod.rs @@ -0,0 +1,28 @@ +pub mod helper; +pub mod node; +pub mod piece; +pub mod session; + +use lazy_static::lazy_static; +use tracing::{debug, error, info}; + +lazy_static! { + // Tracker cache + pub static ref NODE_INFO_CACHE: node::NodeInfoCache = node::NodeInfoCache::new(); + pub static ref PIECE_NODE_INFO_CACHE: piece::PieceNodeInfoCache = piece::PieceNodeInfoCache::new(); + pub static ref SESSION_INFO_CACHE: session::SessionInfoCache = session::SessionInfoCache::new(); + + // Node cache + pub static ref PIECE_INFO_CACHE: piece::PieceInfoCache = piece::PieceInfoCache::new(); + pub static ref PIECE_CACHE: piece::PieceCache = piece::PieceCache::new(); + + // Seed cache + pub static ref SEED_INFO_CACHE: piece::SeedInfoCache = piece::SeedInfoCache::new(); + + // NodeId + pub static ref NODE_ID: node::NodeId = uuid::Uuid::new_v4().to_string(); + + /// For Test: Store finished node + pub static ref FINISHED_NODE_CACHE: helper::FinishedNodeCache = helper::FinishedNodeCache::new(); + pub static ref GLOBAL_TIMESTAMP_CACHE: helper::GlobalTimestampCache = helper::GlobalTimestampCache::new(); +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/node.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/node.rs new file mode 100644 index 0000000..2914a7c --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/node.rs @@ -0,0 +1,98 @@ +use std::{collections::HashMap, sync::Arc}; + +use parking_lot::Mutex; +use serde::{Deserialize, Serialize}; + +pub type NodeId = String; +pub type Addr = String; +// pub type NodeInfoCache = Arc>>; + +pub struct NodeInfoCache { + inner: Arc>>, +} + +impl NodeInfoCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub fn get(&self, node_id: &NodeId) -> Option { + let inner = self.inner.lock(); + inner.get(node_id).cloned() + } + + pub fn get_addr(&self, node_id: &NodeId) -> Option { + let inner = self.inner.lock(); + inner.get(node_id).cloned() + } + + pub fn set(&self, node_id: NodeId, addr: Addr) { + let mut inner = self.inner.lock(); + inner.insert(node_id, addr); + } + + pub fn remove(&self, node_id: &NodeId) { + let mut inner = self.inner.lock(); + inner.remove(node_id); + } + + pub fn get_all(&self) -> Vec<(NodeId, Addr)> { + let inner = self.inner.lock(); + inner.iter().map(|(k, v)| (k.clone(), v.clone())).collect() + } + + pub fn get_all_node_id(&self) -> Vec { + let inner = self.inner.lock(); + inner.keys().cloned().collect() + } + + pub fn get_all_addr(&self) -> Vec { + let inner = self.inner.lock(); + inner.values().cloned().collect() + } + + pub fn get_all_map(&self) -> HashMap { + let inner = self.inner.lock(); + inner.clone() + } + + pub fn is_empty(&self) -> bool { + let inner = self.inner.lock(); + inner.is_empty() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_node_info_cache() { + let node_info_cache = NodeInfoCache::new(); + let node_id = "node_id".to_string(); + let addr = "addr".to_string(); + + node_info_cache.set(node_id.clone(), addr.clone()); + assert_eq!(node_info_cache.get(&node_id), Some(addr.clone())); + + println!("{:?}", node_info_cache.get_all()); + + node_info_cache.remove(&node_id); + assert_eq!(node_info_cache.get(&node_id), None); + + node_info_cache.set(node_id.clone(), addr.clone()); + assert_eq!( + node_info_cache.get_all(), + vec![(node_id.clone(), addr.clone())] + ); + + assert_eq!(node_info_cache.get_all_node_id(), vec![node_id.clone()]); + assert_eq!(node_info_cache.get_all_addr(), vec![addr.clone()]); + + let mut map = HashMap::new(); + map.insert(node_id.clone(), addr.clone()); + assert_eq!(node_info_cache.get_all_map(), map); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/piece.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/piece.rs new file mode 100644 index 0000000..a75fe28 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/piece.rs @@ -0,0 +1,431 @@ +use std::{collections::HashMap, collections::HashSet, sync::Arc}; + +use parking_lot::Mutex; +use serde::{Deserialize, Serialize}; + +pub type NodeId = String; +pub type PieceId = String; +pub type PieceToNode = HashMap>; +pub type NodeToPiece = HashMap>; + +#[derive(Debug, Serialize, Deserialize)] +pub struct PieceNodeInfo { + piece_to_node: PieceToNode, + node_to_piece: NodeToPiece, +} + +pub struct PieceNodeInfoCache { + inner: Arc>, +} + +impl PieceNodeInfoCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(PieceNodeInfo { + piece_to_node: HashMap::new(), + node_to_piece: HashMap::new(), + })), + } + } + + pub fn get(&self, piece_id: &PieceId) -> Option> { + let inner = self.inner.lock(); + inner.piece_to_node.get(piece_id).cloned() + } + + pub fn set(&self, piece_id: PieceId, node_id: NodeId) { + let mut inner = self.inner.lock(); + let node_set = inner + .piece_to_node + .entry(piece_id.clone()) + .or_insert(HashSet::new()); + node_set.insert(node_id.clone()); + + let piece_set = inner.node_to_piece.entry(node_id).or_insert(HashSet::new()); + piece_set.insert(piece_id.clone()); + } + + pub fn remove(&self, piece_id: &PieceId, node_id: &NodeId) { + let mut inner = self.inner.lock(); + if let Some(node_set) = inner.piece_to_node.get_mut(piece_id) { + node_set.remove(node_id); + } + + if let Some(piece_set) = inner.node_to_piece.get_mut(node_id) { + piece_set.remove(piece_id); + } + } + + pub fn get_all(&self) -> Vec<(PieceId, HashSet)> { + let inner = self.inner.lock(); + inner + .piece_to_node + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect() + } + + pub fn get_all_piece_id(&self) -> Vec { + let inner = self.inner.lock(); + inner.piece_to_node.keys().cloned().collect() + } + + pub fn get_all_node_id(&self) -> Vec { + let inner = self.inner.lock(); + inner.node_to_piece.keys().cloned().collect() + } + + pub fn get_all_map(&self) -> PieceToNode { + let inner = self.inner.lock(); + inner.piece_to_node.clone() + } + + pub fn get_piece_info(&self) -> PieceNodeInfo { + let inner = self.inner.lock(); + PieceNodeInfo { + piece_to_node: inner.piece_to_node.clone(), + node_to_piece: inner.node_to_piece.clone(), + } + } + + pub fn get_node_list(&self, piece_id: &PieceId) -> Option> { + let inner = self.inner.lock(); + inner + .piece_to_node + .get(piece_id) + .map(|e| e.iter().cloned().collect()) + } + + pub fn get_piece_list(&self, node_id: &NodeId) -> Option> { + let inner = self.inner.lock(); + inner + .node_to_piece + .get(node_id) + .map(|e| e.iter().cloned().collect()) + } + + pub fn purge_node(&self, node_id: &NodeId) { + let mut inner = self.inner.lock(); + if let Some(piece_set) = inner.node_to_piece.get_mut(node_id) { + // TODO: Update borrow checker + let mut inner_mut = self.inner.lock(); + for piece_id in piece_set.iter() { + if let Some(node_set) = inner_mut.piece_to_node.get_mut(piece_id) { + node_set.remove(node_id); + } + } + } + inner.node_to_piece.remove(node_id); + } +} + +#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, PartialOrd)] +pub struct PieceInfo { + filename: String, + index: u32, + size: u32, + checksum: String, // Same as PieceId +} + +impl PieceInfo { + pub fn new(filename: String, index: u32, size: u32, checksum: String) -> Self { + Self { + filename, + index, + size, + checksum, + } + } + + pub fn get_filename(&self) -> String { + self.filename.clone() + } + + pub fn get_index(&self) -> u32 { + self.index + } + + pub fn get_size(&self) -> u32 { + self.size + } + + pub fn get_checksum(&self) -> String { + self.checksum.clone() + } +} + +pub struct PieceInfoCache { + inner: Arc>>, +} + +impl PieceInfoCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub fn get(&self, piece_id: &PieceId) -> Option { + let inner = self.inner.lock(); + inner.get(piece_id).cloned() + } + + pub fn set(&self, piece_id: PieceId, piece_info: PieceInfo) { + let mut inner = self.inner.lock(); + inner.insert(piece_id, piece_info); + } + + pub fn contains(&self, piece_id: &PieceId) -> bool { + let inner = self.inner.lock(); + inner.contains_key(piece_id) + } + + pub fn remove(&self, piece_id: &PieceId) { + let mut inner = self.inner.lock(); + inner.remove(piece_id); + } + + pub fn get_all(&self) -> Vec<(PieceId, PieceInfo)> { + let inner = self.inner.lock(); + inner.iter().map(|(k, v)| (k.clone(), v.clone())).collect() + } + + pub fn get_all_piece_id(&self) -> Vec { + let inner = self.inner.lock(); + inner.keys().cloned().collect() + } + + pub fn get_all_map(&self) -> HashMap { + let inner = self.inner.lock(); + inner.clone() + } +} + +#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, PartialOrd)] +pub struct SeedInfo { + filename: String, + content_length: u32, // file content size + piece_list: Vec, // piece list(order by index) +} + +impl SeedInfo { + pub fn new(filename: String, content_length: u32, piece_list: Vec) -> Self { + Self { + filename, + content_length, + piece_list, + } + } + + pub fn get_filename(&self) -> String { + self.filename.clone() + } + + pub fn get_content_length(&self) -> u32 { + self.content_length + } + + pub fn get_piece_list(&self) -> Vec { + self.piece_list.clone() + } + + pub fn add_piece(&mut self, piece_info: PieceInfo) { + self.piece_list.push(piece_info); + } +} + +type Filename = String; + +pub struct SeedInfoCache { + inner: Arc>>, +} + +impl SeedInfoCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub fn get(&self, filename: &Filename) -> Option { + let inner = self.inner.lock(); + inner.get(filename).cloned() + } + + pub fn set(&self, filename: Filename, seed_info: SeedInfo) { + let mut inner = self.inner.lock(); + inner.insert(filename, seed_info); + } + + pub fn remove(&self, filename: &Filename) { + let mut inner = self.inner.lock(); + inner.remove(filename); + } + + pub fn get_all(&self) -> Vec<(Filename, SeedInfo)> { + let inner = self.inner.lock(); + inner.iter().map(|(k, v)| (k.clone(), v.clone())).collect() + } + + pub fn get_all_filename(&self) -> Vec { + let inner = self.inner.lock(); + inner.keys().cloned().collect() + } + + pub fn get_all_map(&self) -> HashMap { + let inner = self.inner.lock(); + inner.clone() + } +} + +pub struct PieceCache { + inner: Arc>>>, +} + +impl PieceCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub fn get(&self, piece_id: &PieceId) -> Option> { + let inner = self.inner.lock(); + inner.get(piece_id).cloned() + } + + pub fn set(&self, piece_id: PieceId, piece: Vec) { + let mut inner = self.inner.lock(); + inner.insert(piece_id, piece); + } + + pub fn remove(&self, piece_id: &PieceId) { + let mut inner = self.inner.lock(); + inner.remove(piece_id); + } + + pub fn get_all(&self) -> Vec<(PieceId, Vec)> { + let inner = self.inner.lock(); + inner.iter().map(|(k, v)| (k.clone(), v.clone())).collect() + } + + pub fn get_all_piece_id(&self) -> Vec { + let inner = self.inner.lock(); + inner.keys().cloned().collect() + } + + pub fn get_all_map(&self) -> HashMap> { + let inner = self.inner.lock(); + inner.clone() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_piece_node_info_cache() { + let piece_info_cache = PieceNodeInfoCache::new(); + let piece_id = "piece_id".to_string(); + let node_id = "node_id".to_string(); + let piece_id1 = "piece_id1".to_string(); + let node_id1 = "node_id1".to_string(); + let piece_id2 = "piece_id1".to_string(); + let node_id2 = "node_id".to_string(); + + piece_info_cache.set(piece_id.clone(), node_id.clone()); + piece_info_cache.set(piece_id1.clone(), node_id1.clone()); + piece_info_cache.set(piece_id2.clone(), node_id2.clone()); + assert_eq!( + piece_info_cache.get(&piece_id), + Some(vec![node_id.clone()].into_iter().collect()) + ); + + // PieceNodeInfo { piece_to_node: {"piece_id": {"node_id"}, "piece_id1": {"node_id1", "node_id"}}, node_to_piece: {"node_id": {"piece_id1", "piece_id"}, "node_id1": {"piece_id1"}} } + println!("{:?}", piece_info_cache.get_piece_info()); + + piece_info_cache.remove(&piece_id, &node_id); + assert_eq!( + piece_info_cache.get(&piece_id), + Some(vec![].into_iter().collect()) + ); + + piece_info_cache.set(piece_id.clone(), node_id.clone()); + } + + #[test] + fn test_piece_info_cache() { + let piece_info_cache = PieceInfoCache::new(); + let piece_id = "piece_id".to_string(); + let piece_info = PieceInfo { + filename: "filename".to_string(), + index: 0, + size: 0, + checksum: "checksum".to_string(), + }; + + piece_info_cache.set(piece_id.clone(), piece_info.clone()); + assert_eq!(piece_info_cache.get(&piece_id).unwrap(), piece_info.clone()); + + // [("piece_id", PieceInfo { filename: "filename", index: 0, size: 0 })] + println!("{:?}", piece_info_cache.get_all()); + + piece_info_cache.remove(&piece_id); + assert_eq!(piece_info_cache.get(&piece_id), None); + + piece_info_cache.set(piece_id.clone(), piece_info.clone()); + assert_eq!( + piece_info_cache.get_all(), + vec![(piece_id.clone(), piece_info.clone())] + ); + } + + #[test] + fn test_seed_info_cache() { + let seed_info_cache = SeedInfoCache::new(); + let filename = "filename".to_string(); + let seed_info = SeedInfo { + filename: "filename".to_string(), + content_length: 0, + piece_list: vec![], + }; + + seed_info_cache.set(filename.clone(), seed_info.clone()); + assert_eq!(seed_info_cache.get(&filename).unwrap(), seed_info.clone()); + + // [("filename", SeedInfo { filename: "filename", content_length: 0, piece_list: [] })] + println!("{:?}", seed_info_cache.get_all()); + + seed_info_cache.remove(&filename); + assert_eq!(seed_info_cache.get(&filename), None); + + seed_info_cache.set(filename.clone(), seed_info.clone()); + assert_eq!( + seed_info_cache.get_all(), + vec![(filename.clone(), seed_info.clone())] + ); + } + + #[test] + fn test_piece_cache() { + let piece_cache = PieceCache::new(); + let piece_id = "piece_id".to_string(); + let piece = vec![0, 1, 2, 3]; + + piece_cache.set(piece_id.clone(), piece.clone()); + assert_eq!(piece_cache.get(&piece_id).unwrap(), piece.clone()); + + // [("piece_id", [0, 1, 2, 3])] + println!("{:?}", piece_cache.get_all()); + + piece_cache.remove(&piece_id); + assert_eq!(piece_cache.get(&piece_id), None); + + piece_cache.set(piece_id.clone(), piece.clone()); + assert_eq!( + piece_cache.get_all(), + vec![(piece_id.clone(), piece.clone())] + ); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/session.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/session.rs new file mode 100644 index 0000000..2c8b0c6 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/store/session.rs @@ -0,0 +1,102 @@ +use std::{collections::HashMap, sync::Arc}; + +use parking_lot::Mutex; +use serde::{Deserialize, Serialize}; + +pub type NodeId = String; +pub type Timestamp = u128; +// pub type NodeInfoCache = Arc>>; + +pub struct SessionInfoCache { + inner: Arc>>, +} + +impl SessionInfoCache { + pub fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub fn get(&self, node_id: &NodeId) -> Option { + let inner = self.inner.lock(); + inner.get(node_id).cloned() + } + + pub fn set(&self, node_id: NodeId, timestamp: Timestamp) { + let mut inner = self.inner.lock(); + inner.insert(node_id, timestamp); + } + + pub fn remove(&self, node_id: &NodeId) { + let mut inner = self.inner.lock(); + inner.remove(node_id); + } + + pub fn get_all(&self) -> Vec<(NodeId, Timestamp)> { + let inner = self.inner.lock(); + inner.iter().map(|(k, v)| (k.clone(), v.clone())).collect() + } + + pub fn get_all_node_id(&self) -> Vec { + let inner = self.inner.lock(); + inner.keys().cloned().collect() + } + + pub fn get_all_timestamp(&self) -> Vec { + let inner = self.inner.lock(); + inner.values().cloned().collect() + } + + pub fn get_all_map(&self) -> HashMap { + let inner = self.inner.lock(); + inner.clone() + } + + pub fn clear(&self) { + let mut inner = self.inner.lock(); + inner.clear(); + } + + pub fn find_expired(&self, current_timestamp: Timestamp, timeout: Timestamp) -> Vec { + let inner = self.inner.lock(); + inner + .iter() + .filter(|(_, timestamp)| current_timestamp - **timestamp > timeout) + .map(|(node_id, _)| node_id.clone()) + .collect() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::time::{SystemTime, UNIX_EPOCH}; + + #[test] + fn test_session_info_cache() { + let cache = SessionInfoCache::new(); + let node_id = "node_id".to_string(); + + let current_time = SystemTime::now(); + + let duration = current_time + .duration_since(UNIX_EPOCH) + .expect("Failed to get current time"); + let milliseconds = duration.as_millis(); + let timestamp = milliseconds; + + cache.set(node_id.clone(), timestamp); + + println!("{:?}", cache.get_all()); + + assert_eq!(cache.get(&node_id), Some(timestamp)); + assert_eq!(cache.get_all_node_id(), vec![node_id.clone()]); + assert_eq!(cache.get_all_timestamp(), vec![timestamp]); + assert_eq!( + cache.get_all_map(), + vec![(node_id.clone(), timestamp)].into_iter().collect() + ); + cache.remove(&node_id); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/cluster.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/cluster.rs new file mode 100644 index 0000000..d556171 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/cluster.rs @@ -0,0 +1,44 @@ +use axum::{Extension, Json}; +use hyper::StatusCode; +use serde::{Deserialize, Serialize}; +use tracing::{debug, info, log::LevelFilter}; + +use crate::config::Config; +use crate::server::logic::node::{add_node, update_session}; +use crate::server::{error::*, logic}; + +pub async fn heart_beat( + Extension(config): Extension, + Json(request): Json, +) -> Result> { + info!( + "Receive heart beat from node: {node_id}, addr: {addr}", + node_id = request.node_id, + addr = request.addr + ); + + // Update session + update_session(request.node_id.as_str()).await?; + + // Store node info + add_node(request.node_id.as_str(), &request.addr.as_str()).await?; + + let response = HeartBeatResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + }; + + Ok(Json(response)) +} + +#[derive(Debug, Deserialize)] +pub struct HeartBeatRequest { + pub node_id: String, + pub addr: String, +} + +#[derive(Serialize, Deserialize)] +pub struct HeartBeatResponse { + pub code: String, + pub msg: String, +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/file.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/file.rs new file mode 100644 index 0000000..3f32939 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/file.rs @@ -0,0 +1,97 @@ +use axum::{Extension, Json}; +use hyper::StatusCode; +use serde::{Deserialize, Serialize}; +use tracing::{debug, info, log::LevelFilter}; + +use crate::config::Config; +use crate::server::logic::file::progress_report; +use crate::server::store::piece::SeedInfo; +use crate::server::{error::*, logic}; + +pub async fn report( + Extension(config): Extension, + Json(request): Json, +) -> Result> { + debug!( + "Receive piece report from node: {piece_id}, pieceId: {node_id} progress: {progress} filename: {filename}", + piece_id = request.piece_id, + node_id = request.node_id, + progress = request.progress, + filename = request.filename, + ); + + if request.node_id == "" || request.piece_id == "" { + return Err(Error::ParamMissing); + } + + // Update to progress info + progress_report( + request.node_id.as_str(), + request.piece_id.as_str(), + request.progress, + request.filename.as_str(), + ) + .await?; + + let response = ReportResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + }; + + Ok(Json(response)) +} + +pub async fn fetch_seed( + Extension(config): Extension, + Json(request): Json, +) -> Result> { + debug!( + "Receive fetch seed filename: {filename}", + filename = request.filename, + ); + + if request.filename == "" { + return Err(Error::ParamMissing); + } + + let response = match logic::file::fetch_seed(config, request.filename.as_str()).await { + Ok(seed_info) => FetchSeedResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + seed_info: seed_info, + }, + Err(e) => FetchSeedResponse { + code: StatusCode::INTERNAL_SERVER_ERROR.to_string(), + msg: e.to_string(), + seed_info: SeedInfo::new("".to_string(), 0, vec![]), + }, + }; + + Ok(Json(response)) +} + +#[derive(Debug, Deserialize)] +pub struct ReportRequest { + pub node_id: String, + pub piece_id: String, + pub progress: f64, + pub filename: String, +} + +#[derive(Serialize, Deserialize)] +pub struct ReportResponse { + pub code: String, + pub msg: String, +} + +#[derive(Debug, Deserialize)] +pub struct FetchSeedRequest { + pub filename: String, +} + +#[derive(Serialize, Deserialize)] +pub struct FetchSeedResponse { + pub code: String, + pub msg: String, + pub seed_info: SeedInfo, +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/info.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/info.rs new file mode 100644 index 0000000..db156fe --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/info.rs @@ -0,0 +1,43 @@ +use std::collections::HashSet; + +use axum::{Extension, Json}; +use hyper::StatusCode; +use serde::{Deserialize, Serialize}; +use tracing::{debug, info, log::LevelFilter}; + +use crate::config::Config; +use crate::server::error::*; +use crate::server::store::piece::PieceInfo; +use crate::server::store::{ + NODE_INFO_CACHE, PIECE_INFO_CACHE, PIECE_NODE_INFO_CACHE, SESSION_INFO_CACHE, +}; + +pub async fn info(Extension(config): Extension) -> Result> { + debug!("Get tracker info"); + + let session_info: Vec<(String, u128)> = SESSION_INFO_CACHE.get_all(); + let node_info: Vec<(String, String)> = NODE_INFO_CACHE.get_all(); + let piece_node_info: Vec<(String, HashSet)> = PIECE_NODE_INFO_CACHE.get_all(); + let piece_info: Vec<(String, PieceInfo)> = PIECE_INFO_CACHE.get_all(); + + let response = InfoResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + session_info, + node_info, + piece_node_info, + piece_info, + }; + + Ok(Json(response)) +} + +#[derive(Serialize, Deserialize)] +pub struct InfoResponse { + pub code: String, + pub msg: String, + pub session_info: Vec<(String, u128)>, + pub node_info: Vec<(String, String)>, + pub piece_node_info: Vec<(String, HashSet)>, + pub piece_info: Vec<(String, PieceInfo)>, +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/mod.rs new file mode 100644 index 0000000..28ff150 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/mod.rs @@ -0,0 +1,20 @@ +mod cluster; +mod file; +mod info; +mod node; + +use axum::routing::*; + +pub async fn health() -> &'static str { + "Tracker is running!" +} + +pub fn app() -> Router { + Router::new() + .route("/heart_beat", post(cluster::heart_beat)) + .route("/node_list", post(node::node_list)) + .route("/fetch_seed", post(file::fetch_seed)) + .route("/report", post(file::report)) + .route("/info", get(info::info)) + .route("/health", get(health)) +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/node.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/node.rs new file mode 100644 index 0000000..da471b7 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/api/node.rs @@ -0,0 +1,42 @@ +use axum::{Extension, Json}; +use hyper::StatusCode; +use serde::{Deserialize, Serialize}; +use tracing::{debug, info, log::LevelFilter}; + +use crate::config::Config; +use crate::server::error::*; +use crate::server::logic::node::get_piece_node_list; + +/// Get online node list by piece Id +pub async fn node_list( + Extension(config): Extension, + Json(request): Json, +) -> Result> { + debug!( + "Receive query pieceId with pieceId: {piece_id}", + piece_id = request.piece_id, + ); + + // Change to addr list + let node_list = get_piece_node_list(request.piece_id.as_str()).await?; + + let response = NodeListResponse { + code: StatusCode::OK.to_string(), + msg: "ok".to_string(), + node_list: node_list, + }; + + Ok(Json(response)) +} + +#[derive(Debug, Deserialize)] +pub struct NodeListRequest { + pub piece_id: String, +} + +#[derive(Serialize, Deserialize)] +pub struct NodeListResponse { + pub code: String, + pub msg: String, + pub node_list: Vec, +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/mod.rs new file mode 100644 index 0000000..9ee3e67 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/mod.rs @@ -0,0 +1,2 @@ +pub mod api; +pub mod task; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/check.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/check.rs new file mode 100644 index 0000000..9e67334 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/check.rs @@ -0,0 +1,50 @@ +use std::thread; +use std::time::Duration; + +use tracing::{debug, info}; + +use crate::server::store::{SESSION_INFO_CACHE, NODE_INFO_CACHE}; +use crate::server::utils::time_helper::get_current_timestamp; +pub struct CheckTask { + tracker_uuid: String, + session_check_time: u64, + session_expire_time: u64, +} + +impl CheckTask { + pub fn new(uuid: &str, session_check_time: u64, session_expire_time: u64) -> Self { + Self { + tracker_uuid: uuid.to_string(), + session_check_time, + session_expire_time, + } + } + + pub fn start(&self) { + let session_check_time = self.session_check_time; + let session_expire_time = self.session_expire_time; + let tracker_uuid = self.tracker_uuid.clone(); + + thread::spawn(move || loop { + let interval = Duration::from_secs(session_check_time); + let expire_time = Duration::from_secs(session_expire_time); + let timestamp = get_current_timestamp(); + let expired_node_list = + SESSION_INFO_CACHE.find_expired(timestamp, expire_time.as_millis()); + if expired_node_list.is_empty() { + debug!("[CheckTask-Tracker:{tracker_uuid}] No expired node"); + } else { + for node_id in expired_node_list.iter() { + SESSION_INFO_CACHE.remove(node_id); + NODE_INFO_CACHE.remove(node_id); + } + info!( + "[CheckTask-Tracker:{tracker_uuid}] Remove expired node list: {:?}", + expired_node_list + ); + } + + thread::sleep(interval); + }); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/mod.rs new file mode 100644 index 0000000..3e8ff0f --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/tracker/task/mod.rs @@ -0,0 +1 @@ +pub mod check; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/mod.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/mod.rs new file mode 100644 index 0000000..43fc9ec --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/mod.rs @@ -0,0 +1,2 @@ +pub mod s3_helper; +pub mod time_helper; diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/s3_helper.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/s3_helper.rs new file mode 100644 index 0000000..c10d276 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/s3_helper.rs @@ -0,0 +1,165 @@ +use s3::{creds::Credentials, error::S3Error, serde_types::HeadObjectResult, Bucket, Region}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct S3Client { + pub endpoint: String, + pub bucket: String, + pub region: String, + pub access_key: String, + pub secret_key: String, +} + +impl S3Client { + pub fn new( + endpoint: String, + bucket: String, + region: String, + access_key: String, + secret_key: String, + ) -> Self { + Self { + endpoint, + bucket, + region, + access_key, + secret_key, + } + } + + pub fn get_endpoint(&self) -> String { + self.endpoint.clone() + } + + pub fn get_bucket(&self) -> String { + self.bucket.clone() + } + + pub fn get_region(&self) -> String { + self.region.clone() + } + + pub fn get_access_key(&self) -> String { + self.access_key.clone() + } + + pub fn get_secret_key(&self) -> String { + self.secret_key.clone() + } + + pub async fn get_object_metadata(&self, key: String) -> Result { + let endpoint = self.get_endpoint(); + let bucket = self.get_bucket(); + let region = self.get_region(); + let access_key = self.get_access_key(); + let secret_key = self.get_secret_key(); + + let region = Region::Custom { + region: region.to_owned(), + endpoint: endpoint.to_owned(), + }; + let credentials = Credentials::new( + Some(access_key.to_owned().as_str()), + Some(secret_key.to_owned().as_str()), + None, + None, + None, + ) + .expect("Failed to create credentials"); + + let bucket_object = + Bucket::new(bucket.as_str(), region.clone(), credentials.clone())?.with_path_style(); + + // Get meta data + let (data, _code) = bucket_object.head_object(key.as_str()).await?; + + Ok(data) + } + + pub async fn get_object_range_data( + &self, + key: String, + start: u64, + end: u64, + ) -> Result, S3Error> { + let endpoint = self.get_endpoint(); + let bucket = self.get_bucket(); + let region = self.get_region(); + let access_key = self.get_access_key(); + let secret_key = self.get_secret_key(); + + let region = Region::Custom { + region: region.to_owned(), + endpoint: endpoint.to_owned(), + }; + let credentials = Credentials::new( + Some(access_key.to_owned().as_str()), + Some(secret_key.to_owned().as_str()), + None, + None, + None, + ) + .expect("Failed to create credentials"); + + let bucket_object = + Bucket::new(bucket.as_str(), region.clone(), credentials.clone())?.with_path_style(); + + // Get range data + let response_data = bucket_object + .get_object_range(key.as_str(), start, Some(end)) + .await?; + let data = response_data.to_vec(); + + Ok(data) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_get_object_metadata() { + let endpoint = "http://127.0.0.1:39000"; + let bucket = "hackathon"; + let region = ""; + let access_key = "hackathon"; + let secret_key = "hackathon"; + + let s3 = S3Client::new( + endpoint.to_string(), + bucket.to_string(), + region.to_string(), + access_key.to_string(), + secret_key.to_string(), + ); + let res = s3 + .get_object_metadata("output_10MB.txt".to_string()) + .await + .unwrap(); + println!("{:?}", res); + } + + #[tokio::test] + async fn test_get_object_range_data() { + let endpoint = "http://127.0.0.1:39000"; + let bucket = "hackathon"; + let region = ""; + let access_key = "hackathon"; + let secret_key = "hackathon"; + + let s3 = S3Client::new( + endpoint.to_string(), + bucket.to_string(), + region.to_string(), + access_key.to_string(), + secret_key.to_string(), + ); + let res = s3 + .get_object_range_data("output_10MB.txt".to_string(), 0, 1024) + .await + .unwrap(); + + println!("{:?}", res); + } +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/time_helper.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/time_helper.rs new file mode 100644 index 0000000..b833fda --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/src/server/utils/time_helper.rs @@ -0,0 +1,11 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + +pub fn get_current_timestamp() -> u128 { + let current_time = SystemTime::now(); + let duration = current_time + .duration_since(UNIX_EPOCH) + .expect("Failed to get current time"); + let milliseconds = duration.as_millis(); + + return milliseconds; +} diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/test.sh b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/test.sh new file mode 100644 index 0000000..e23b868 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/test.sh @@ -0,0 +1,6 @@ +time curl --location --request POST 'http://127.0.0.1:48452/api/v1/start_download' \ +--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "filename": "output_10MB.txt" +}' \ No newline at end of file From 50f7f6a65b4c9ad2dc1c6e1fae6b81bc69a59e64 Mon Sep 17 00:00:00 2001 From: Bo Date: Sat, 16 Dec 2023 00:37:03 +0800 Subject: [PATCH 3/6] misc: Update api docs and docker-compose. --- ruan_lao_shi_xiao_fen_dui/README.md | 0 .../deploy/docker-compose.yaml | 18 + .../docs/p2p-with-tracker.md | 370 ++++++++++++++++++ 3 files changed, 388 insertions(+) create mode 100644 ruan_lao_shi_xiao_fen_dui/README.md create mode 100644 ruan_lao_shi_xiao_fen_dui/deploy/docker-compose.yaml create mode 100644 ruan_lao_shi_xiao_fen_dui/docs/p2p-with-tracker.md diff --git a/ruan_lao_shi_xiao_fen_dui/README.md b/ruan_lao_shi_xiao_fen_dui/README.md new file mode 100644 index 0000000..e69de29 diff --git a/ruan_lao_shi_xiao_fen_dui/deploy/docker-compose.yaml b/ruan_lao_shi_xiao_fen_dui/deploy/docker-compose.yaml new file mode 100644 index 0000000..00d511f --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/deploy/docker-compose.yaml @@ -0,0 +1,18 @@ +version: "3" + +services: + minio: + image: minio/minio + container_name: hackathon-minio + ports: + - "39000:9000" + - "39090:9090" + volumes: + - ./data:/data + - ./config:/root/.minio + environment: + - MINIO_ROOT_USER=hackathon + - MINIO_ROOT_PASSWORD=hackathon + - MINIO_BUCKET=hackathon + - MINIO_SERVER_URL=http://127.0.0.1:9000 + command: minio server /data --console-address ':9090' \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/docs/p2p-with-tracker.md b/ruan_lao_shi_xiao_fen_dui/docs/p2p-with-tracker.md new file mode 100644 index 0000000..8440fbf --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/docs/p2p-with-tracker.md @@ -0,0 +1,370 @@ +--- +title: p2p-with-tracker v1.0.0 +language_tabs: + - shell: Shell + - http: HTTP + - javascript: JavaScript + - ruby: Ruby + - python: Python + - php: PHP + - java: Java + - go: Go +toc_footers: [] +includes: [] +search: true +code_clipboard: true +highlight_theme: darkula +headingLevel: 2 +generator: "@tarslib/widdershins v4.0.17" + +--- + +# p2p-with-tracker + +> v1.0.0 + +Base URLs: + +* 开发环境: http://127.0.0.1:48349/api/v1(随机生成) + +* 测试环境: http://127.0.0.1:38080/api/v1 + +# Authentication + +# Default + +## POST tracker心跳 + +POST /heart_beat + +> Body 请求参数 + +```json +{ + "node_id": "string", + "addr": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|说明| +|---|---|---|---|---| +|body|body|object| 否 |none| +|» node_id|body|string| 是 |none| +|» addr|body|string| 是 |none| + +> 返回示例 + +> 200 Response + +```json +{ + "code": "string", + "msg": "string" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline| + +### 返回数据结构 + +状态码 **200** + +|名称|类型|必选|约束|中文名|说明| +|---|---|---|---|---|---| +|» code|string|true|none||none| +|» msg|string|true|none||none| + +## POST 启动node下载 + +POST /start_download + +> Body 请求参数 + +```json +{ + "filename": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|说明| +|---|---|---|---|---| +|body|body|object| 否 |none| +|» filename|body|string| 是 |none| + +> 返回示例 + +> 200 Response + +```json +{ + "code": "string", + "msg": "string" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline| + +### 返回数据结构 + +状态码 **200** + +|名称|类型|必选|约束|中文名|说明| +|---|---|---|---|---|---| +|» code|string|true|none||none| +|» msg|string|true|none||none| + +## POST 获取node中的分片 + +POST /fetch_piece + +> Body 请求参数 + +```json +{ + "piece_id": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|说明| +|---|---|---|---|---| +|body|body|object| 否 |none| +|» piece_id|body|string| 是 |none| + +> 返回示例 + +> 200 Response + +```json +{ + "code": "string", + "msg": "string", + "data": "string" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline| + +### 返回数据结构 + +状态码 **200** + +|名称|类型|必选|约束|中文名|说明| +|---|---|---|---|---|---| +|» code|string|true|none||none| +|» msg|string|true|none||none| +|» data|string|true|none||none| + +## GET 获取tracker信息 + +GET /info + +> Body 请求参数 + +```json +{} +``` + +### 请求参数 + +|名称|位置|类型|必选|说明| +|---|---|---|---|---| +|body|body|object| 否 |none| + +> 返回示例 + +> 200 Response + +```json +{ + "code": "string", + "msg": "string", + "session_info": "string", + "node_info": "string", + "piece_info": "string", + "piece_node_info": "string" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline| + +### 返回数据结构 + +状态码 **200** + +|名称|类型|必选|约束|中文名|说明| +|---|---|---|---|---|---| +|» code|string|true|none||none| +|» msg|string|true|none||none| +|» session_info|string|true|none||none| +|» node_info|string|true|none||none| +|» piece_info|string|true|none||none| +|» piece_node_info|string|true|none||none| + +## POST 获取分片的node列表 + +POST /node_list + +> Body 请求参数 + +```json +{ + "piece_id": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|说明| +|---|---|---|---|---| +|body|body|object| 否 |none| +|» piece_id|body|string| 是 |none| + +> 返回示例 + +> 200 Response + +```json +{ + "code": "string", + "msg": "string", + "node_list": [ + "string" + ] +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline| + +### 返回数据结构 + +状态码 **200** + +|名称|类型|必选|约束|中文名|说明| +|---|---|---|---|---|---| +|» code|string|true|none||none| +|» msg|string|true|none||none| +|» node_list|[string]|true|none||none| + +## POST 更新分片信息 + +POST /report + +> Body 请求参数 + +```json +{ + "piece_id": "string", + "node_id": "string", + "progress": "string", + "filename": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|说明| +|---|---|---|---|---| +|body|body|object| 否 |none| +|» piece_id|body|string| 是 |none| +|» node_id|body|string| 是 |none| +|» progress|body|string| 是 |none| +|» filename|body|string| 是 |none| + +> 返回示例 + +> 200 Response + +```json +{ + "code": "string", + "msg": "string" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline| + +### 返回数据结构 + +状态码 **200** + +|名称|类型|必选|约束|中文名|说明| +|---|---|---|---|---|---| +|» code|string|true|none||none| +|» msg|string|true|none||none| + +## POST 获取seed信息 + +POST /fetch_seed + +> Body 请求参数 + +```json +{ + "filename": "string" +} +``` + +### 请求参数 + +|名称|位置|类型|必选|说明| +|---|---|---|---|---| +|body|body|object| 否 |none| +|» filename|body|string| 是 |none| + +> 返回示例 + +> 200 Response + +```json +{ + "code": "string", + "msg": "string", + "seed_info": "string" +} +``` + +### 返回结果 + +|状态码|状态码含义|说明|数据模型| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|成功|Inline| + +### 返回数据结构 + +状态码 **200** + +|名称|类型|必选|约束|中文名|说明| +|---|---|---|---|---|---| +|» code|string|true|none||none| +|» msg|string|true|none||none| +|» seed_info|string|true|none||none| From 0d29ea2a2e4ab5d98f4fba9469aa28cf4d3f5e43 Mon Sep 17 00:00:00 2001 From: Bo Date: Sat, 16 Dec 2023 00:39:37 +0800 Subject: [PATCH 4/6] fix: Update config. --- ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml index 628a78d..5712a0d 100644 --- a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker/config.toml @@ -11,7 +11,7 @@ sessionExpireTime = 10 # seconds sessionCheckTime = 3 # seconds [s3] -endpoint = "http://81.69.26.72:39000" +endpoint = "http://127.0.0.1:39000" bucket = "hackathon" region = "" accessKey = "hackathon" From c0906d37cc2107cab09c75fb6b59c6242808d199 Mon Sep 17 00:00:00 2001 From: Bo Date: Sat, 16 Dec 2023 23:44:13 +0800 Subject: [PATCH 5/6] misc: Update test client. --- ruan_lao_shi_xiao_fen_dui/baseline/README.md | 65 +- .../baseline/src/main.rs | 10 +- ruan_lao_shi_xiao_fen_dui/genfile/README.md | 16 + .../genfile/README_zh.md | 15 + ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs | 2 +- .../p2p-with-tracker-client/.gitignore | 1 + .../p2p-with-tracker-client/Cargo.lock | 1178 +++++++++++++++++ .../p2p-with-tracker-client/Cargo.toml | 13 + .../p2p-with-tracker-client/README.md | 0 .../p2p-with-tracker-client/src/main.rs | 83 ++ 10 files changed, 1371 insertions(+), 12 deletions(-) create mode 100644 ruan_lao_shi_xiao_fen_dui/genfile/README.md create mode 100644 ruan_lao_shi_xiao_fen_dui/genfile/README_zh.md create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/.gitignore create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.lock create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.toml create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/README.md create mode 100644 ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/src/main.rs diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/README.md b/ruan_lao_shi_xiao_fen_dui/baseline/README.md index 9235aef..4e1ca53 100644 --- a/ruan_lao_shi_xiao_fen_dui/baseline/README.md +++ b/ruan_lao_shi_xiao_fen_dui/baseline/README.md @@ -4,19 +4,70 @@ ### 测试结果 -> (10MB下载),测试S3服务器使用Minio S3, 带宽约为1MB/s,可以使用tc工具进行限速 -> 配置文件可修改,默认分片大小为128KB +**测试环境使用tc工具进行限速,单个节点10MB大约需要10S下载完成** +**通过给网络带宽限速访问小文件的形式测试来模拟高带宽,海量存储的情况** + +##### **Baseline测试**(baseline) + +1. 单个文件使用分片形式直接下载到内存中,耗时为:9.730874292s + +```bash +Start multi download test... start_time: Instant { tv_sec: 1195191, tv_nsec: 100834166 } +Start download test 0 +meta: HeadObjectResult { accept_ranges: Some("bytes"), cache_control: None, content_disposition: None, content_encoding: None, content_language: None, content_length: Some(10485760), content_type: Some("text/plain"), delete_marker: None, e_tag: Some("\"8b8378787c0925f42ccb829f6cc2fb97\""), expiration: None, expires: None, last_modified: Some("Tue, 12 Dec 2023 08:05:17 GMT"), metadata: Some({}), missing_meta: None, object_lock_legal_hold_status: None, object_lock_mode: None, object_lock_retain_until_date: None, parts_count: None, replication_status: None, request_charged: None, restore: None, sse_customer_algorithm: None, sse_customer_key_md5: None, ssekms_key_id: None, server_side_encryption: None, storage_class: None, version_id: None, website_redirect_location: None } +End download test 0 +End multi download test... end_time: Instant { tv_sec: 1195200, tv_nsec: 831708458 } +Task-0 multi download test duration: 9.730874292s +Average multi download test duration: 973 +``` -1. 目前是使用多线程的方式并行进行下载,下载时间为: -(10个线程同时读取这个10MB的文件): +2. 目前是使用多线程的方式并行进行下载,下载时间为: +(10个线程同时读取这个10MB的文件,测试10次取平均值): ```bash +... Average multi download test duration: 117.793s ``` -2. 尝试使用p2p方式进行下载,下载时间为: -(10个node节点同时读取这个10MB的文件): +#### **P2P测试**(p2p-with-tracker) + +>(10MB下载),测试S3服务器使用Minio S3, 带宽约为1MB/s,可以使用tc工具进行限速 +> +> 配置文件可修改,默认分片大小为128KB + +修改config.toml,启动tracker服务,默认端口38080: +```bash +cargo run +``` + +修改config.toml,指定启动模式为node,启动node服务,默认端口是在48000-49000中的随机端口,可以在启动日志中查看: +```bash +cargo run -- -m node + +# INFO p2p_with_tracker::server: 🚀🚀🚀 Server [node:ff0e66a6-6153-4926-842a-3a5f5d360d66] has launched on http://127.0.0.1:48133 +``` + +修改test.sh文件,指定node服务的端口,以及下载的文件名,启动下载测试: +```bash +time curl --location --request POST 'http://127.0.0.1:48412/api/v1/start_download' \ +--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "filename": "output_10MB.txt" +}' +``` +> time命令可以测试命令的执行时间。 + + +1. 使用p2p的方式进行下载,1个node节点同时读取这个10MB的文件,下载时间为,比直接下载略长(**主要是额外的通信的耗时**): +```bash +cpu 12.450 total +``` + +2. 尝试使用p2p方式进行下载,10个node节点同时读取这个10MB的文件,下载时间为(**后续节点能够选择从高速的相邻节点进行下载**): ```bash cpu 37.540 total ``` -因此,在10个节点的情况下,读取该文件的时间提升大。 \ No newline at end of file +因此,在10个节点的情况下,读取该文件的时间提升效果非常明显。 + +3. \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs b/ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs index a4f4b00..303d096 100644 --- a/ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs +++ b/ruan_lao_shi_xiao_fen_dui/baseline/src/main.rs @@ -13,7 +13,7 @@ async fn test_download(id:usize) -> Result<(), S3Error> { let bucket_name = "hackathon"; let region = Region::Custom { region: "".to_owned(), - endpoint: "http://127.0.0.1:39000".to_owned(), + endpoint: "http://81.69.26.72:39000".to_owned(), }; let credentials = Credentials::new( Some("hackathon".to_owned().as_str()), @@ -57,7 +57,7 @@ async fn test_download(id:usize) -> Result<(), S3Error> { end = file_size; } let res = bucket.get_object_range(filename, start.try_into().unwrap(), Some(end.try_into().unwrap())).await.unwrap(); - println!("get object range: {:?}", res); + // println!("get object range: {:?}", res); // buf.extend_from_slice(&res); start += step; end += step; @@ -75,12 +75,14 @@ async fn test_download(id:usize) -> Result<(), S3Error> { async fn main() -> Result<(), S3Error>{ let mut count = 0; - for j in 0..1 { + // Test 10 times + for j in 0..10 { let start_time = Instant::now(); println!("Start multi download test... start_time: {:?}", start_time); let mut tasks = Vec::new(); - for i in 0..1 { + // 10 tasks + for i in 0..10 { tasks.push(tokio::spawn(test_download(i))); } for task in tasks { diff --git a/ruan_lao_shi_xiao_fen_dui/genfile/README.md b/ruan_lao_shi_xiao_fen_dui/genfile/README.md new file mode 100644 index 0000000..d97e6cb --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/genfile/README.md @@ -0,0 +1,16 @@ +# Generate Test File + +### Generate Test File + +By default, a 10MB text file is generated with the content of the character `A`. + +```rs +let file_size = 10 * 1024 * 1024; // 10MB +let file_path = "output_10MB.txt"; +``` + +Run the service in the test environment, and the generated file will be in the current directory. + +```bash +cargo run +``` \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/genfile/README_zh.md b/ruan_lao_shi_xiao_fen_dui/genfile/README_zh.md new file mode 100644 index 0000000..8046fca --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/genfile/README_zh.md @@ -0,0 +1,15 @@ +# 测试文件生成 + +### 生成测试文件 + +默认生成10MB的文本文件,文件中文本内容为字符`A`。 +```rs +let file_size = 10 * 1024 * 1024; // 10MB +let file_path = "output_10MB.txt"; +``` + +在测试环境中运行服务,生成的文件在当前目录下。 + +```bash +cargo run +``` \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs b/ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs index 1ab1e2f..ce3dfba 100644 --- a/ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs +++ b/ruan_lao_shi_xiao_fen_dui/genfile/src/main.rs @@ -3,7 +3,7 @@ use std::io::prelude::*; use std::io::BufWriter; fn main() { - let file_size = 10 * 1024 * 1024; // 200MB + let file_size = 10 * 1024 * 1024; // 10MB let file_path = "output_10MB.txt"; // 创建文件并打开写入模式 diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/.gitignore b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/.gitignore @@ -0,0 +1 @@ +/target diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.lock b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.lock new file mode 100644 index 0000000..a93d3b4 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.lock @@ -0,0 +1,1178 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "autocfg" +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.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "p2p-with-tracker-client" +version = "0.1.0" +dependencies = [ + "reqwest", + "serde", + "serde_json", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "syn" +version = "2.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[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 = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.5", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[package]] +name = "web-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[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.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +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 = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +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 = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.toml b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.toml new file mode 100644 index 0000000..f31e160 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "p2p-with-tracker-client" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +reqwest = { version="0.11", features=["json", "multipart", "blocking"]} + +# Serialization +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" \ No newline at end of file diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/README.md b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/README.md new file mode 100644 index 0000000..e69de29 diff --git a/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/src/main.rs b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/src/main.rs new file mode 100644 index 0000000..b39ef07 --- /dev/null +++ b/ruan_lao_shi_xiao_fen_dui/p2p-with-tracker-client/src/main.rs @@ -0,0 +1,83 @@ +use reqwest::blocking::Client; +use serde_json::json; +use std::thread; +use std::time::{Instant, Duration}; + +fn main() { + // Request online nodes from tracker + let tracker_url = "http://127.0.0.1:38080/api/v1/info"; + // Default timeout is 30s + let client = Client::new(); + + let response = client + .get(tracker_url) + .timeout(Duration::from_secs(1000)) + .header("User-Agent", "Apifox/1.0.0 (https://apifox.com)") + .header("Content-Type", "application/json") + .json(&json!({})) + .send(); + + let online_nodes: Vec = match response { + Ok(res) => { + let data: serde_json::Value = res.json().unwrap(); + let node_info = data["node_info"].as_array().unwrap(); + node_info + .iter() + .map(|node| node[1].as_str().unwrap().to_string()) + .collect() + } + Err(err) => { + println!("Request failed: {:?}", err); + Vec::new() + } + }; + + let online_node_list = online_nodes; + // ["127.0.0.1:48133", "127.0.0.1:48354"] + + let urls: Vec = online_node_list.iter().map(|node| format!("http://{}/api/v1/start_download", node)).collect(); + println!("Online node list: {:?}", urls); + + let filename = "output_10MB.txt"; + let client = Client::new(); + let start_time = Instant::now(); // Start timer + + println!("Start request download..."); + let threads: Vec<_> = urls + .into_iter() + .map(|url| { + let client = client.clone(); + let filename = filename.to_string(); + + thread::spawn(move || { + let payload = json!({ + "filename": filename + }); + + let response = client + .post(&url) + .timeout(Duration::from_secs(1000)) + .header("User-Agent", "Apifox/1.0.0 (https://apifox.com)") + .header("Content-Type", "application/json") + .json(&payload) + .send(); + + match response { + Ok(res) => { + println!("Request successful: {:?}", res.text().unwrap()); + } + Err(err) => { + println!("Request failed: {:?}", err); + } + } + }) + }) + .collect(); + + for thread in threads { + thread.join().unwrap(); + } + + let elapsed_time = start_time.elapsed(); // Calculate elapsed time + println!("Finish request download...Total time taken: {:?}", elapsed_time); +} From d05762cb05a652ec29c1afc222b957c75dab0144 Mon Sep 17 00:00:00 2001 From: Bo Date: Sat, 16 Dec 2023 23:59:50 +0800 Subject: [PATCH 6/6] misc: Update docs. --- ruan_lao_shi_xiao_fen_dui/README.md | 58 +++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/ruan_lao_shi_xiao_fen_dui/README.md b/ruan_lao_shi_xiao_fen_dui/README.md index e69de29..b9b0e92 100644 --- a/ruan_lao_shi_xiao_fen_dui/README.md +++ b/ruan_lao_shi_xiao_fen_dui/README.md @@ -0,0 +1,58 @@ +# 基于异步HTTP实现p2p分布式协议加速S3 Object存取实现 + +### 其他文档 + +```bash +. +├── README.md +├── baseline # 基准测试,直接读取 +├── deploy # 部署Minio S3存储 +├── docs # API文档 +├── genfile # 生成测试服务 +├── p2p-with-tracker # 基于tracker的p2p实现 +└── p2p-with-tracker-client # 基于tracker的p2p实现的测试客户端 +``` + +### **其他文档在各自目录下** + +##### 大致框架,使用Tracker存储部分节点信息和seed信息,Node主要负责下载和上传 + +![](https://github.com/datenlord/Hackathon-2023/assets/47499836/07cd5d99-f1a3-49cf-b4bf-e4caf6e225cc) + +![](https://github.com/datenlord/Hackathon-2023/assets/47499836/0686f79e-9bb1-4f0a-a2d3-8b588ac79fba) + +##### 流程拆分 + +1. 初始化构建阶段 + +初步思路: + +N0将文件S(大小为S)切分n片,然后传输到N1-Nn中,W为带宽,耗费时间: +```math +T = \frac{S}{n * W} +``` +第一步传输完成之后,P2P成员之间会继续交换,接下来的T时间,N1将Fs1传递给其他N-1个节点,以此类推,等于是再次花费一遍传输的时间,整个文件就同步了,就是上面的2T。(所有节点都在相互传输) + +```math +T_{total}=2*\frac{S}{n*W} +``` +这里就节省很多时间了!!! + +==这里也可以进行优化,就是在传输的过程中,第一步N0上获取数据,其他p2p都在等待这个结果,然后第二步才开始进行p2p传输,这两个步骤也可以进行并行化处理== + +> Tips: 减小分片长度进行初始化 + +就是尽量减小分片的长度,然后下载一点点之后就可以开始p2p传输了,粒度更小的话约等于同时开始发送,这样子启动速度就会变快。 + +就是针对上面的分片,再次切分成为m段,然后变成: +T0: m+1 2m+1 ... +T1: m+2 2m+2 ... + +交换上一个由Tx周由N0发送的文件片段。 +```math +t(m) \rarr \frac{1}{n}*\frac{S}{W}(m \rarr +\infty) +``` +我们将总文件分割的片断越小,下载加速比就越大,理论极限为N倍速下载,N为P2P网络成员数量减1。 + +所有的N+1个节点都有了完整的文件F,现在假设新加入一个节点,它也需要这个文件,就不用重复刚才的过程了。 +现在节点总数为N+2,文件可以分为N+1份片断,由N0到Nn分别传输给Nn+1。**同时使用心跳对节点进行维护**还要处理节点退出以及新节点加入等动态问题。 \ No newline at end of file