From 618342699bcb7a956419eb53403608f0381bb1eb Mon Sep 17 00:00:00 2001 From: Pavel Kirilin <win10@list.ru> Date: Wed, 22 Dec 2021 20:00:38 +0400 Subject: [PATCH] Added Notifications. Description: * Added notification system; * Updated Actix-Web up to 4.0.0; * Changed log provider; * Added Http hooks; * Switched async runtime reactor to tokio. Signed-off-by: Pavel Kirilin <win10@list.ru> --- .pre-commit-config.yaml | 45 + Cargo.lock | 1376 +++++++---------- Cargo.toml | 23 +- README.md | 4 +- imgs/rustus_startup_logo.txt | 7 + src/config.rs | 149 +- src/errors.rs | 15 +- .../models/available_info_storages.rs | 33 +- src/info_storages/models/file_info.rs | 4 +- src/main.rs | 92 +- src/notifiers/http_notifier.rs | 48 + src/notifiers/mod.rs | 9 +- src/notifiers/models/hooks.rs | 20 + src/notifiers/models/message.rs | 7 - src/notifiers/models/message_format.rs | 162 ++ src/notifiers/models/mod.rs | 5 +- src/notifiers/models/notification_manager.rs | 44 + src/notifiers/models/notifier.rs | 10 + src/notifiers/notifier.rs | 6 - src/protocol/core/mod.rs | 2 +- src/protocol/core/routes.rs | 52 +- src/protocol/creation/routes.rs | 51 +- src/protocol/extensions.rs | 21 + src/protocol/mod.rs | 8 +- src/protocol/termination/routes.rs | 22 +- src/storages/file_storage.rs | 49 +- src/storages/models/available_stores.rs | 24 +- src/storages/models/storage.rs | 6 +- src/utils/enums.rs | 28 + src/utils/mod.rs | 1 + 30 files changed, 1285 insertions(+), 1038 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 imgs/rustus_startup_logo.txt create mode 100644 src/notifiers/http_notifier.rs create mode 100644 src/notifiers/models/hooks.rs delete mode 100644 src/notifiers/models/message.rs create mode 100644 src/notifiers/models/message_format.rs create mode 100644 src/notifiers/models/notification_manager.rs create mode 100644 src/notifiers/models/notifier.rs delete mode 100644 src/notifiers/notifier.rs create mode 100644 src/protocol/extensions.rs create mode 100644 src/utils/enums.rs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..4a87a93 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,45 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.1.0 + hooks: + - id: trailing-whitespace + - repo: local + hooks: + + - id: build + types: + - rust + name: cargo build + language: system + entry: cargo + pass_filenames: false + args: + - build + - --features=all + + - id: fmt + types: + - rust + name: cargo fmt + language: system + entry: cargo + pass_filenames: false + args: + - fmt + + - id: clippy + types: + - rust + name: cargo clippy + language: system + pass_filenames: false + entry: cargo + args: + - clippy + - --features=all + - --all + - -- + - -W + - clippy::all + - -W + - clippy::pedantic \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 7f8b165..3fe75eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,111 +4,87 @@ version = 3 [[package]] name = "actix-codec" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" +checksum = "13895df506faee81e423febbae3a33b27fca71831b96bb3d60adf16ebcfea952" dependencies = [ "bitflags", - "bytes 0.5.6", + "bytes", "futures-core", "futures-sink", "log", - "pin-project 0.4.28", - "tokio 0.2.25", - "tokio-util 0.3.1", -] - -[[package]] -name = "actix-connect" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "derive_more", - "either", - "futures-util", - "http", - "log", - "trust-dns-proto", - "trust-dns-resolver", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", ] [[package]] name = "actix-files" -version = "0.5.0" +version = "0.6.0-beta.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51e8a9146c12fce92a6e4c24b8c4d9b05268130bfd8d61bc587e822c32ce689" +checksum = "84080179cb878e592ebba0e5194a0eb890dfb37b4f956710e51db6d4d8e18abb" dependencies = [ + "actix-http", "actix-service", + "actix-utils", "actix-web", + "askama_escape", "bitflags", - "bytes 0.5.6", + "bytes", "derive_more", "futures-core", - "futures-util", + "http-range", "log", "mime", "mime_guess", "percent-encoding", - "v_htmlescape", + "pin-project-lite", ] [[package]] name = "actix-http" -version = "2.2.1" +version = "3.0.0-beta.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cb8958da437716f3f31b0e76f8daf36554128517d7df37ceba7df00f09622ee" +checksum = "6294c508c1413346857838356f53f45dbfd257ea31dca19470d9ce78750a7d37" dependencies = [ "actix-codec", - "actix-connect", "actix-rt", "actix-service", - "actix-threadpool", "actix-utils", + "ahash", "base64", "bitflags", "brotli2", - "bytes 0.5.6", - "cookie", - "copyless", + "bytes", + "bytestring", "derive_more", - "either", "encoding_rs", "flate2", - "futures-channel", "futures-core", - "futures-util", - "fxhash", + "futures-task", "h2", "http", "httparse", - "indexmap", + "httpdate", "itoa 0.4.8", "language-tags", - "lazy_static", + "local-channel", "log", "mime", "percent-encoding", - "pin-project 1.0.8", - "rand 0.7.3", - "regex", - "serde", - "serde_json", - "serde_urlencoded", + "pin-project-lite", + "rand", "sha-1 0.9.8", - "slab", - "time 0.2.27", + "smallvec", + "zstd", ] [[package]] name = "actix-macros" -version = "0.1.3" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655" +checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" dependencies = [ "quote", "syn", @@ -116,11 +92,12 @@ dependencies = [ [[package]] name = "actix-router" -version = "0.2.7" +version = "0.5.0-beta.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad299af73649e1fc893e333ccf86f377751eb95ff875d095131574c6f43452c" +checksum = "ddd9f117b910fbcce6e9f45092ffd4ff017785a346d09e2d4fd049f4e20384f4" dependencies = [ "bytestring", + "firestorm", "http", "log", "regex", @@ -129,115 +106,59 @@ dependencies = [ [[package]] name = "actix-rt" -version = "1.1.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" +checksum = "05c2f80ce8d0c990941c7a7a931f69fd0701b76d521f8d36298edf59cd3fbf1f" dependencies = [ "actix-macros", - "actix-threadpool", - "copyless", - "futures-channel", - "futures-util", - "smallvec", - "tokio 0.2.25", + "futures-core", + "tokio", ] [[package]] name = "actix-server" -version = "1.0.4" +version = "2.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" +checksum = "78c9b22794b8af1c2e02434873ef858f2a7db40dbbf861ce77a04cd81ac6b767" dependencies = [ - "actix-codec", "actix-rt", "actix-service", "actix-utils", - "futures-channel", + "futures-core", "futures-util", "log", - "mio 0.6.23", - "mio-uds", + "mio 0.8.0", "num_cpus", - "slab", - "socket2 0.3.19", + "socket2", + "tokio", ] [[package]] name = "actix-service" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" -dependencies = [ - "futures-util", - "pin-project 0.4.28", -] - -[[package]] -name = "actix-testing" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" -dependencies = [ - "actix-macros", - "actix-rt", - "actix-server", - "actix-service", - "log", - "socket2 0.3.19", -] - -[[package]] -name = "actix-threadpool" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" -dependencies = [ - "derive_more", - "futures-channel", - "lazy_static", - "log", - "num_cpus", - "parking_lot", - "threadpool", -] - -[[package]] -name = "actix-tls" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" dependencies = [ - "actix-codec", - "actix-service", - "actix-utils", - "futures-util", + "futures-core", + "paste", + "pin-project-lite", ] [[package]] name = "actix-utils" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" +checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "bitflags", - "bytes 0.5.6", - "either", - "futures-channel", - "futures-sink", - "futures-util", - "log", - "pin-project 0.4.28", - "slab", + "local-waker", + "pin-project-lite", ] [[package]] name = "actix-web" -version = "3.3.2" +version = "4.0.0-beta.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" +checksum = "4609cf57246040316642d4dc4c03d7f3d4a083a892122829dbd9e6ec8db7cd67" dependencies = [ "actix-codec", "actix-http", @@ -246,38 +167,40 @@ dependencies = [ "actix-rt", "actix-server", "actix-service", - "actix-testing", - "actix-threadpool", - "actix-tls", "actix-utils", "actix-web-codegen", - "awc", - "bytes 0.5.6", + "ahash", + "bytes", + "cfg-if", + "cookie", "derive_more", "encoding_rs", - "futures-channel", "futures-core", "futures-util", - "fxhash", + "itoa 0.4.8", + "language-tags", "log", "mime", - "pin-project 1.0.8", + "once_cell", + "paste", + "pin-project-lite", "regex", "serde", "serde_json", "serde_urlencoded", - "socket2 0.3.19", - "time 0.2.27", - "tinyvec", + "smallvec", + "socket2", + "time 0.3.5", "url", ] [[package]] name = "actix-web-codegen" -version = "0.4.0" +version = "0.5.0-beta.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" +checksum = "30a90b7f6c2fde9a1fe3df4da758c2c3c9d620dfa3eae4da0b6925dc0a13444a" dependencies = [ + "actix-router", "proc-macro2", "quote", "syn", @@ -295,9 +218,9 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.3", + "getrandom", "once_cell", - "version_check 0.9.3", + "version_check", ] [[package]] @@ -315,7 +238,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -324,6 +247,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "askama_escape" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1bb320f97e6edf9f756bf015900038e43c7700e059688e5724a928c8f3b8d5" + [[package]] name = "async-channel" version = "1.6.1" @@ -363,6 +292,7 @@ dependencies = [ "futures-lite", "num_cpus", "once_cell", + "tokio", ] [[package]] @@ -379,9 +309,9 @@ dependencies = [ "parking", "polling", "slab", - "socket2 0.4.2", + "socket2", "waker-fn", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -402,34 +332,6 @@ dependencies = [ "event-listener", ] -[[package]] -name = "async-process" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" -dependencies = [ - "async-io", - "blocking", - "cfg-if 1.0.0", - "event-listener", - "futures-lite", - "libc", - "once_cell", - "signal-hook", - "winapi 0.3.9", -] - -[[package]] -name = "async-rustls" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c86f33abd5a4f3e2d6d9251a9e0c6a7e52eb1113caf893dae8429bf4a53f378" -dependencies = [ - "futures-lite", - "rustls", - "webpki", -] - [[package]] name = "async-std" version = "1.10.0" @@ -440,7 +342,6 @@ dependencies = [ "async-global-executor", "async-io", "async-lock", - "async-process", "crossbeam-utils", "futures-channel", "futures-core", @@ -452,7 +353,7 @@ dependencies = [ "memchr", "num_cpus", "once_cell", - "pin-project-lite 0.2.7", + "pin-project-lite", "pin-utils", "slab", "wasm-bindgen-futures", @@ -498,7 +399,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -513,30 +414,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "awc" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" -dependencies = [ - "actix-codec", - "actix-http", - "actix-rt", - "actix-service", - "base64", - "bytes 0.5.6", - "cfg-if 1.0.0", - "derive_more", - "futures-core", - "log", - "mime", - "percent-encoding", - "rand 0.7.3", - "serde", - "serde_json", - "serde_urlencoded", -] - [[package]] name = "base-x" version = "0.2.8" @@ -640,15 +517,6 @@ dependencies = [ "libc", ] -[[package]] -name = "buf-min" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa17aa1cf56bdd6bb30518767d00e58019d326f3f05d8c3e0730b549d332ea83" -dependencies = [ - "bytes 0.5.6", -] - [[package]] name = "bumpalo" version = "3.8.0" @@ -667,12 +535,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - [[package]] name = "bytes" version = "1.1.0" @@ -685,7 +547,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" dependencies = [ - "bytes 1.1.0", + "bytes", ] [[package]] @@ -699,12 +561,9 @@ name = "cc" version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -723,7 +582,7 @@ dependencies = [ "num-traits", "serde", "time 0.1.44", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -741,18 +600,29 @@ dependencies = [ "vec_map", ] +[[package]] +name = "colored" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + [[package]] name = "combine" version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2b2f5d0ee456f3928812dfc8c6d9a1d592b98678f6d56db9b0cd2b7bc6c8db5" dependencies = [ - "bytes 1.1.0", + "bytes", "futures-core", "memchr", - "pin-project-lite 0.2.7", - "tokio 1.15.0", - "tokio-util 0.6.9", + "pin-project-lite", + "tokio", + "tokio-util", ] [[package]] @@ -778,20 +648,30 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cookie" -version = "0.14.4" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" +checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d" dependencies = [ "percent-encoding", "time 0.2.27", - "version_check 0.9.3", + "version_check", ] [[package]] -name = "copyless" -version = "0.1.5" +name = "core-foundation" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" @@ -823,7 +703,7 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -832,7 +712,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -842,7 +722,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -852,7 +732,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] @@ -882,7 +762,7 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "num_cpus", ] @@ -934,7 +814,7 @@ checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ "libc", "redox_users", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -964,19 +844,7 @@ version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", + "cfg-if", ] [[package]] @@ -1000,13 +868,29 @@ dependencies = [ "instant", ] +[[package]] +name = "fern" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9a4820f0ccc8a7afd67c39a0f1a0f4b07ca1725164271a64939d7aeb9af065" +dependencies = [ + "colored", + "log", +] + +[[package]] +name = "firestorm" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31586bda1b136406162e381a3185a506cdfc1631708dd40cba2f6628d8634499" + [[package]] name = "flate2" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crc32fast", "libc", "miniz_oxide", @@ -1019,36 +903,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "form_urlencoded" -version = "1.0.1" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "matches", - "percent-encoding", + "foreign-types-shared", ] [[package]] -name = "fuchsia-zircon" -version = "0.3.3" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" +name = "form_urlencoded" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] [[package]] name = "futures" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" dependencies = [ "futures-channel", "futures-core", @@ -1061,9 +944,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" dependencies = [ "futures-core", "futures-sink", @@ -1071,15 +954,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" dependencies = [ "futures-core", "futures-task", @@ -1099,9 +982,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" [[package]] name = "futures-lite" @@ -1114,18 +997,16 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.7", + "pin-project-lite", "waker-fn", ] [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" dependencies = [ - "autocfg 1.0.1", - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -1133,15 +1014,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" [[package]] name = "futures-timer" @@ -1151,11 +1032,10 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ - "autocfg 1.0.1", "futures-channel", "futures-core", "futures-io", @@ -1163,22 +1043,11 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.7", + "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "generic-array" version = "0.12.4" @@ -1195,18 +1064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", - "version_check 0.9.3", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", + "version_check", ] [[package]] @@ -1215,9 +1073,9 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1235,11 +1093,11 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd" dependencies = [ - "bytes 0.5.6", + "bytes", "fnv", "futures-core", "futures-sink", @@ -1247,10 +1105,9 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 0.2.25", - "tokio-util 0.3.1", + "tokio", + "tokio-util", "tracing", - "tracing-futures", ] [[package]] @@ -1305,17 +1162,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - [[package]] name = "html_parser" version = "0.6.2" @@ -1337,17 +1183,77 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ - "bytes 1.1.0", + "bytes", "fnv", "itoa 0.4.8", ] +[[package]] +name = "http-body" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" + [[package]] name = "httparse" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 0.4.8", + "pin-project-lite", + "socket2", + "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.2.3" @@ -1375,29 +1281,14 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", + "cfg-if", ] [[package]] -name = "ipconfig" -version = "0.2.2" +name = "ipnet" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2 0.3.19", - "widestring", - "winapi 0.3.9", - "winreg", -] +checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" [[package]] name = "ipnetwork" @@ -1430,22 +1321,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] -name = "js-sys" -version = "0.3.55" +name = "jobserver" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" dependencies = [ - "wasm-bindgen", + "libc", ] [[package]] -name = "kernel32-sys" -version = "0.2.2" +name = "js-sys" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "wasm-bindgen", ] [[package]] @@ -1459,9 +1349,9 @@ dependencies = [ [[package]] name = "language-tags" -version = "0.2.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy_static" @@ -1496,10 +1386,22 @@ dependencies = [ ] [[package]] -name = "linked-hash-map" -version = "0.5.4" +name = "local-channel" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "6246c68cf195087205a0512559c97e15eaf95198bf0e206d662092cdcb03fe9f" +dependencies = [ + "futures-core", + "futures-sink", + "futures-util", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "902eb695eb0591864543cbfbf6d742510642a605a61fc5e97fe6ceb5a30ac4fb" [[package]] name = "lock_api" @@ -1516,31 +1418,16 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "value-bag", ] -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "maplit" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "matches" version = "0.1.9" @@ -1596,25 +1483,6 @@ dependencies = [ "autocfg 1.0.1", ] -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow 0.2.2", - "net2", - "slab", - "winapi 0.2.8", -] - [[package]] name = "mio" version = "0.7.14" @@ -1623,32 +1491,22 @@ checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", - "miow 0.3.7", + "miow", "ntapi", - "winapi 0.3.9", + "winapi", ] [[package]] -name = "mio-uds" -version = "0.6.8" +name = "mio" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2" dependencies = [ - "iovec", "libc", - "mio 0.6.23", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "log", + "miow", + "ntapi", + "winapi", ] [[package]] @@ -1657,7 +1515,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1666,14 +1524,13 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f76d2f2e2dcbb00a8d3b2b09f026a74a82693ea52cd071647aa6cfa7f1ff37e" dependencies = [ - "async-std", "async-trait", "futures-channel", "futures-core", "futures-timer", "futures-util", "log", - "tokio 1.15.0", + "tokio", ] [[package]] @@ -1687,24 +1544,21 @@ dependencies = [ ] [[package]] -name = "net2" -version = "0.2.37" +name = "native-tls" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" dependencies = [ - "cfg-if 0.1.10", + "lazy_static", "libc", - "winapi 0.3.9", -] - -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -dependencies = [ - "memchr", - "version_check 0.1.5", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -1715,7 +1569,7 @@ checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" dependencies = [ "memchr", "minimal-lexical", - "version_check 0.9.3", + "version_check", ] [[package]] @@ -1724,7 +1578,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1762,7 +1616,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.4", + "rand", "smallvec", "zeroize", ] @@ -1826,6 +1680,39 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-probe" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" + +[[package]] +name = "openssl-sys" +version = "0.9.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +dependencies = [ + "autocfg 1.0.1", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking" version = "2.0.0" @@ -1849,14 +1736,20 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", - "redox_syscall 0.2.10", + "redox_syscall", "smallvec", - "winapi 0.3.9", + "winapi", ] +[[package]] +name = "paste" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" + [[package]] name = "pem" version = "0.8.3" @@ -1917,52 +1810,6 @@ dependencies = [ "sha-1 0.8.2", ] -[[package]] -name = "pin-project" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" -dependencies = [ - "pin-project-internal 0.4.28", -] - -[[package]] -name = "pin-project" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" -dependencies = [ - "pin-project-internal 1.0.8", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - [[package]] name = "pin-project-lite" version = "0.2.7" @@ -1987,11 +1834,11 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "log", "wepoll-ffi", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2010,7 +1857,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "version_check 0.9.3", + "version_check", ] [[package]] @@ -2021,7 +1868,7 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", - "version_check 0.9.3", + "version_check", ] [[package]] @@ -2030,12 +1877,6 @@ version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" version = "1.0.34" @@ -2057,32 +1898,13 @@ dependencies = [ "serde_json", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", + "proc-macro2", ] [[package]] @@ -2092,19 +1914,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", - "rand_hc 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", + "rand_hc", ] [[package]] @@ -2114,16 +1926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -2132,16 +1935,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] @@ -2150,7 +1944,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.6.3", + "rand_core", ] [[package]] @@ -2167,7 +1961,7 @@ dependencies = [ "lazy_static", "log", "once_cell", - "rand 0.8.4", + "rand", "rbatis-core", "rbatis-macro-driver", "rbatis_sql", @@ -2254,7 +2048,7 @@ dependencies = [ "hex", "indexmap", "lazy_static", - "rand 0.8.4", + "rand", "serde", "serde_bytes", "serde_json", @@ -2267,27 +2061,20 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a6ddfecac9391fed21cce10e83c65fa4abafd77df05c98b1c647c65374ce9b3" dependencies = [ - "async-std", "async-trait", - "bytes 1.1.0", + "bytes", "combine", "dtoa", "futures-util", "itoa 0.4.8", "percent-encoding", - "pin-project-lite 0.2.7", + "pin-project-lite", "sha1", - "tokio 1.15.0", - "tokio-util 0.6.9", + "tokio", + "tokio-util", "url", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.2.10" @@ -2303,8 +2090,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ - "getrandom 0.2.3", - "redox_syscall 0.2.10", + "getrandom", + "redox_syscall", ] [[package]] @@ -2325,13 +2112,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] -name = "resolv-conf" -version = "0.7.0" +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +checksum = "7c4e0a76dc12a116108933f6301b95e83634e0c47b0afbed6abbaa0601e99258" dependencies = [ - "hostname", - "quick-error", + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", ] [[package]] @@ -2357,7 +2178,7 @@ dependencies = [ "spin", "untrusted", "web-sys", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2374,7 +2195,7 @@ dependencies = [ "num-iter", "num-traits", "pem", - "rand 0.8.4", + "rand", "simple_asn1", "subtle", "zeroize", @@ -2433,18 +2254,21 @@ dependencies = [ "base64", "chrono", "derive_more", + "fern", + "futures", "lazy_static", "log", "mobc-redis", "rbatis", "rbson", + "reqwest", "serde", "serde_json", - "simple-logging", "strfmt", "structopt", "strum", "thiserror", + "tokio", "url", "uuid 1.0.0-alpha.1", ] @@ -2461,6 +2285,16 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -2477,6 +2311,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.9.0" @@ -2570,7 +2427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", @@ -2589,22 +2446,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.9.0", "opaque-debug 0.3.0", ] -[[package]] -name = "signal-hook" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -2614,17 +2461,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simple-logging" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00d48e85675326bb182a2286ea7c1a0b264333ae10f27a937a72be08628b542" -dependencies = [ - "lazy_static", - "log", - "thread-id", -] - [[package]] name = "simple_asn1" version = "0.5.4" @@ -2649,17 +2485,6 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi 0.3.9", -] - [[package]] name = "socket2" version = "0.4.2" @@ -2667,7 +2492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2683,7 +2508,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" dependencies = [ "itertools", - "nom 7.1.0", + "nom", "unicode_categories", ] @@ -2700,7 +2525,7 @@ dependencies = [ "bit-vec", "bitflags", "byteorder", - "bytes 1.1.0", + "bytes", "chrono", "crc", "crossbeam-channel", @@ -2729,7 +2554,7 @@ dependencies = [ "once_cell", "parking_lot", "percent-encoding", - "rand 0.8.4", + "rand", "regex", "rsa", "rust_decimal", @@ -2744,6 +2569,7 @@ dependencies = [ "stringprep", "thiserror", "time 0.2.27", + "tokio-stream", "url", "uuid 0.8.2", "webpki", @@ -2757,8 +2583,10 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d1bd069de53442e7a320f525a6d4deb8bb0621ac7a55f7eccbc2b58b57f43d0" dependencies = [ - "async-rustls", - "async-std", + "actix-rt", + "once_cell", + "tokio", + "tokio-rustls", ] [[package]] @@ -2767,7 +2595,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" dependencies = [ - "version_check 0.9.3", + "version_check", ] [[package]] @@ -2916,6 +2744,20 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -2945,26 +2787,6 @@ dependencies = [ "syn", ] -[[package]] -name = "thread-id" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" -dependencies = [ - "libc", - "redox_syscall 0.1.57", - "winapi 0.3.9", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - [[package]] name = "time" version = "0.1.44" @@ -2972,8 +2794,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "wasi", + "winapi", ] [[package]] @@ -2988,8 +2810,18 @@ dependencies = [ "standback", "stdweb", "time-macros", - "version_check 0.9.3", - "winapi 0.3.9", + "version_check", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" +dependencies = [ + "itoa 0.4.8", + "libc", ] [[package]] @@ -3032,51 +2864,52 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "0.2.25" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "bytes 0.5.6", - "futures-core", - "iovec", - "lazy_static", + "bytes", "libc", "memchr", - "mio 0.6.23", - "mio-uds", - "pin-project-lite 0.1.12", + "mio 0.7.14", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", "signal-hook-registry", - "slab", - "winapi 0.3.9", + "winapi", ] [[package]] -name = "tokio" -version = "1.15.0" +name = "tokio-native-tls" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ - "bytes 1.1.0", - "libc", - "memchr", - "mio 0.7.14", - "num_cpus", - "pin-project-lite 0.2.7", - "winapi 0.3.9", + "native-tls", + "tokio", ] [[package]] -name = "tokio-util" -version = "0.3.1" +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-stream" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" dependencies = [ - "bytes 0.5.6", "futures-core", - "futures-sink", - "log", - "pin-project-lite 0.1.12", - "tokio 0.2.25", + "pin-project-lite", + "tokio", ] [[package]] @@ -3085,23 +2918,28 @@ version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" dependencies = [ - "bytes 1.1.0", + "bytes", "futures-core", "futures-sink", "log", - "pin-project-lite 0.2.7", - "tokio 1.15.0", + "pin-project-lite", + "tokio", ] +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + [[package]] name = "tracing" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ - "cfg-if 1.0.0", - "log", - "pin-project-lite 0.2.7", + "cfg-if", + "pin-project-lite", "tracing-core", ] @@ -3115,53 +2953,10 @@ dependencies = [ ] [[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project 1.0.8", - "tracing", -] - -[[package]] -name = "trust-dns-proto" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cad71a0c0d68ab9941d2fb6e82f8fb2e86d9945b94e1661dd0aaea2b88215a9" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "enum-as-inner", - "futures", - "idna", - "lazy_static", - "log", - "rand 0.7.3", - "smallvec", - "thiserror", - "tokio 0.2.25", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.19.7" +name = "try-lock" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb" -dependencies = [ - "cfg-if 0.1.10", - "futures", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "resolv-conf", - "smallvec", - "thiserror", - "tokio 0.2.25", - "trust-dns-proto", -] +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "typenum" @@ -3181,7 +2976,7 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.9.3", + "version_check", ] [[package]] @@ -3247,7 +3042,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.3", + "getrandom", "serde", ] @@ -3257,39 +3052,7 @@ version = "1.0.0-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb3ab47baa004111b323696c6eaa2752e7356f7f77cf6b6dc7a2087368ce1ca4" dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "v_escape" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e0ab5fab1db278a9413d2ea794cb66f471f898c5b020c3c394f6447625d9d4" -dependencies = [ - "buf-min", - "v_escape_derive", -] - -[[package]] -name = "v_escape_derive" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29769400af8b264944b851c961a4a6930e76604f59b1fcd51246bab6a296c8c" -dependencies = [ - "nom 4.2.3", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "v_htmlescape" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f9a8af610ad6f7fc9989c9d2590d9764bc61f294884e9ee93baa58795174572" -dependencies = [ - "cfg-if 1.0.0", - "v_escape", + "getrandom", ] [[package]] @@ -3299,7 +3062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" dependencies = [ "ctor", - "version_check 0.9.3", + "version_check", ] [[package]] @@ -3314,12 +3077,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "version_check" version = "0.9.3" @@ -3333,10 +3090,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +name = "want" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] [[package]] name = "wasi" @@ -3350,7 +3111,7 @@ version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -3375,7 +3136,7 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -3458,18 +3219,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -3480,12 +3229,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -3500,21 +3243,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi", ] [[package]] @@ -3543,3 +3276,32 @@ dependencies = [ "syn", "synstructure", ] + +[[package]] +name = "zstd" +version = "0.9.0+zstd.1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07749a5dc2cb6b36661290245e350f15ec3bbb304e493db54a1d354480522ccd" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "4.1.1+zstd.1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91c90f2c593b003603e5e0493c837088df4469da25aafff8bce42ba48caf079" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "1.6.1+zstd.1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33" +dependencies = [ + "cc", + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 3528b0d..1ea4fde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,31 +9,36 @@ description = "TUS protocol implementation written in Rust." name = "rustus" [dependencies] -actix-web = "^3.3.2" -actix-files = "^0.5.0" +actix-web = { version = "^4.0.0-beta.15" } +actix-files = { version = "0.6.0-beta.10" } +tokio = { version = "1.4.0", features = ["time"] } derive_more = { version = "^0.99.9", default-features = false, features = ["display", "from", "from_str"] } thiserror = "^1.0" async-trait = "0.1.52" structopt = { version = "^0.3" } uuid = { version = "^1.0.0-alpha.1", features = ["v4"] } -async-std = "^1.10.0" +async-std = { version = "^1.10.0", features = ["tokio1"] } serde = "1" chrono = { version = "^0.4.19", features = ["serde"] } serde_json = "1" log = "^0.4.14" url = "2.2.2" base64 = "^0.13.0" -simple-logging = { version = "^2.0.2" } +fern = { version = "0.6.0", features = ["colored"] } strfmt = "^0.1.6" lazy_static = "1.4.0" strum = { version = "0.23", features = ["derive"] } +futures = { version = "^0.3.19", features = ["executor"] } +reqwest = { version = "^0.11.8", features = ["json"], optional = true } +# Deps for info storages. rbson = { version = "2.0", optional = true } -rbatis = { version = "^3.0", default-features = false, features = ["runtime-async-std-rustls", "all-database"], optional = true } -mobc-redis = { version = "0.7.0", features = ["async-std-comp"], optional = true } - +rbatis = { version = "^3.0", default-features = false, features = ["runtime-actix-rustls", "all-database"], optional = true } +mobc-redis = { version = "^0.7.0", optional = true } [features] default = [] -all = ["redis_info_storage", "db_info_storage"] +all = ["redis_info_storage", "db_info_storage", "http_notifier"] redis_info_storage = ["mobc-redis"] -db_info_storage = ["rbatis", "rbson"] \ No newline at end of file +db_info_storage = ["rbatis", "rbson"] + +http_notifier = ["reqwest"] \ No newline at end of file diff --git a/README.md b/README.md index 9539832..c4c0003 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,9 @@ All options are listed in `rustus --help`. * [x] Database support for info storage; * [x] Redis support for info storage; * [ ] S3 as data storage store support; -* [ ] Notification interface; +* [x] Notification interface; * [ ] Executable files notifications; -* [ ] Notifications via http hooks; +* [x] Notifications via http hooks; * [ ] Notifications via RabbitMQ; * [ ] Rustus helm chart; * [ ] Cloud native rustus operator. diff --git a/imgs/rustus_startup_logo.txt b/imgs/rustus_startup_logo.txt new file mode 100644 index 0000000..381d6f4 --- /dev/null +++ b/imgs/rustus_startup_logo.txt @@ -0,0 +1,7 @@ + ____ __ + / __ \__ _______/ /___ _______ + / /_/ / / / / ___/ __/ / / / ___/ + / _, _/ /_/ (__ ) /_/ /_/ (__ ) + /_/ |_|\__,_/____/\__/\__,_/____/ + Makes file uploads easier. + diff --git a/src/config.rs b/src/config.rs index 2a0a73d..8a1a6f8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,19 +3,33 @@ use std::env; use std::path::PathBuf; use chrono::{Datelike, Timelike}; +use lazy_static::lazy_static; use structopt::StructOpt; -use crate::errors::RustusError; use crate::info_storages::AvailableInfoStores; +use crate::notifiers::{Format, Hook}; +use crate::protocol::extensions::Extensions; + use crate::storages::AvailableStores; +lazy_static! { + /// Freezing ENVS on startup. + static ref ENV_MAP: HashMap<String, String> = { + let mut m = HashMap::new(); + for (key, value) in env::vars() { + m.insert(format!("env[{}]", key), value); + } + m + }; +} + #[derive(StructOpt, Debug, Clone)] pub struct StorageOptions { /// Rustus storage type. /// /// Storages are used to store /// uploads. - #[structopt(long, short, default_value = "file_storage", env = "RUSTUS_STORAGE")] + #[structopt(long, short, default_value = "file-storage", env = "RUSTUS_STORAGE")] pub storage: AvailableStores, /// Rustus data directory @@ -25,7 +39,7 @@ pub struct StorageOptions { #[structopt(long, default_value = "./data")] pub data_dir: PathBuf, - #[structopt(long, short = "dstruct", default_value = "")] + #[structopt(long, default_value = "")] pub dis_structure: String, } @@ -42,7 +56,7 @@ pub struct InfoStoreOptions { #[structopt( long, short, - default_value = "file_info_storage", + default_value = "file-info-storage", env = "RUSTUS_INFO_STORAGE" )] pub info_storage: AvailableInfoStores, @@ -54,18 +68,51 @@ pub struct InfoStoreOptions { #[structopt(long, default_value = "./data", env = "RUSTUS_INFO_DIR")] pub info_dir: PathBuf, + /// Connection string for remote info storages. + /// + /// This connection string is used for storages + /// which require connection. Examples of such storages + /// are `Postgres`, `MySQL` or `Redis`. + /// + /// Value must include all connection details. #[cfg(any(feature = "redis_info_storage", feature = "db_info_storage"))] #[structopt( long, - required_if("info-storage", "db_info_storage"), - required_if("info-storage", "redis_info_storage"), + required_if("info-storage", "db-info-storage"), + required_if("info-storage", "redis-info-storage"), env = "RUSTUS_INFO_DB_DSN" )] pub info_db_dsn: Option<String>, } +#[derive(StructOpt, Debug, Clone)] +pub struct NotificationsOptions { + /// Notifications format. + /// + /// This format will be used in all + /// messages about hooks. + #[structopt(long, default_value = "default", env = "RUSTUS_NOTIFICATION_FORMAT")] + pub notification_format: Format, + + /// Enabled hooks for notifications. + #[structopt( + long, + default_value = "pre-create,post-create,post-receive,post-terminate,post-finish", + env = "RUSTUS_HOOKS", + use_delimiter = true + )] + pub hooks: Vec<Hook>, + + /// List of URLS to send webhooks to. + /// + /// This list will be notified + #[cfg(feature = "http_notifier")] + #[structopt(long, env = "RUSTUS_HOOKS_HTTP_URLS", use_delimiter = true)] + pub hooks_http_urls: Vec<String>, +} + #[derive(Debug, StructOpt, Clone)] -#[structopt(name = "rustus")] +#[structopt(name = "Rustus")] /// Tus protocol implementation. /// /// This program is a web-server that @@ -74,7 +121,7 @@ pub struct InfoStoreOptions { /// You can read more about protocol /// [here](https://tus.io/). pub struct RustusConf { - /// Rustus host + /// Rustus server host #[structopt(short, long, default_value = "0.0.0.0", env = "RUSTUS_HOST")] pub host: String, @@ -86,6 +133,9 @@ pub struct RustusConf { #[structopt(long, default_value = "/files", env = "RUSTUS_URL")] pub url: String, + /// Maximum payload size. + /// + /// This limit used to reduce amount of consumed memory. #[structopt( long, short = "mbs", @@ -94,10 +144,6 @@ pub struct RustusConf { )] pub max_body_size: usize, - /// Enabled hooks for http events - #[structopt(long, default_value = "pre-create,post-finish", env = "RUSTUS_HOOKS")] - pub enabled_hooks: String, - /// Rustus maximum log level #[structopt(long, default_value = "INFO", env = "RUSTUS_LOG_LEVEL")] pub log_level: log::LevelFilter, @@ -110,57 +156,19 @@ pub struct RustusConf { #[structopt( long, default_value = "getting,creation,termination,creation-with-upload,creation-defer-length", - env = "RUSTUS_EXTENSIONS" + env = "RUSTUS_TUS_EXTENSIONS", + use_delimiter = true )] - pub extensions: String, + pub tus_extensions: Vec<Extensions>, #[structopt(flatten)] pub storage_opts: StorageOptions, #[structopt(flatten)] pub info_storage_opts: InfoStoreOptions, -} - -/// Enum of available Protocol Extensions -#[derive(PartialEq, PartialOrd, Ord, Eq)] -pub enum ProtocolExtensions { - CreationDeferLength, - CreationWithUpload, - Creation, - Termination, - Getting, -} - -impl TryFrom<String> for ProtocolExtensions { - type Error = RustusError; - /// Parse string to protocol extension. - /// - /// This function raises an error if unknown protocol was passed. - fn try_from(value: String) -> Result<Self, Self::Error> { - match value.as_str() { - "creation" => Ok(ProtocolExtensions::Creation), - "creation-with-upload" => Ok(ProtocolExtensions::CreationWithUpload), - "creation-defer-length" => Ok(ProtocolExtensions::CreationDeferLength), - "termination" => Ok(ProtocolExtensions::Termination), - "getting" => Ok(ProtocolExtensions::Getting), - _ => Err(RustusError::UnknownExtension(value.clone())), - } - } -} - -impl From<ProtocolExtensions> for String { - /// Mapping protocol extensions to their - /// original names. - fn from(ext: ProtocolExtensions) -> Self { - match ext { - ProtocolExtensions::Creation => "creation".into(), - ProtocolExtensions::CreationWithUpload => "creation-with-upload".into(), - ProtocolExtensions::Termination => "termination".into(), - ProtocolExtensions::Getting => "getting".into(), - ProtocolExtensions::CreationDeferLength => "creation-defer-length".into(), - } - } + #[structopt(flatten)] + pub notification_opts: NotificationsOptions, } impl RustusConf { @@ -193,17 +201,20 @@ impl RustusConf { ) } + /// Check if hook is enabled by user. + pub fn hook_is_active(&self, hook: Hook) -> bool { + self.notification_opts.hooks.contains(&hook) + } + + /// Generate directory name with user template. pub fn dir_struct(&self) -> String { let now = chrono::Utc::now(); - let mut vars: HashMap<String, String> = HashMap::new(); + let mut vars: HashMap<String, String> = ENV_MAP.clone(); vars.insert("day".into(), now.day().to_string()); vars.insert("month".into(), now.month().to_string()); vars.insert("year".into(), now.year().to_string()); vars.insert("hour".into(), now.hour().to_string()); vars.insert("minute".into(), now.minute().to_string()); - for (key, value) in env::vars() { - vars.insert(format!("env[{}]", key), value); - } strfmt::strfmt(self.storage_opts.dis_structure.as_str(), &vars) .unwrap_or_else(|_| "".into()) } @@ -216,27 +227,19 @@ impl RustusConf { /// Protocol extensions must be sorted, /// because Actix doesn't override /// existing methods. - pub fn extensions_vec(&self) -> Vec<ProtocolExtensions> { - let mut ext = self - .extensions - .split(',') - .flat_map(|ext| ProtocolExtensions::try_from(String::from(ext))) - .collect::<Vec<ProtocolExtensions>>(); + pub fn extensions_vec(&self) -> Vec<Extensions> { + let mut ext = self.tus_extensions.clone(); // If create-with-upload extension is enabled // creation extension must be enabled too. - if ext.contains(&ProtocolExtensions::CreationWithUpload) - && !ext.contains(&ProtocolExtensions::Creation) - { - ext.push(ProtocolExtensions::Creation); + if ext.contains(&Extensions::CreationWithUpload) && !ext.contains(&Extensions::Creation) { + ext.push(Extensions::Creation); } // If create-defer-length extension is enabled // creation extension must be enabled too. - if ext.contains(&ProtocolExtensions::CreationDeferLength) - && !ext.contains(&ProtocolExtensions::Creation) - { - ext.push(ProtocolExtensions::Creation); + if ext.contains(&Extensions::CreationDeferLength) && !ext.contains(&Extensions::Creation) { + ext.push(Extensions::Creation); } ext.sort(); diff --git a/src/errors.rs b/src/errors.rs index 585adc0..9056373 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,8 +1,7 @@ use std::io::{Error, ErrorKind}; -use actix_web::dev::HttpResponseBuilder; use actix_web::http::StatusCode; -use actix_web::{HttpResponse, ResponseError}; +use actix_web::{HttpResponse, HttpResponseBuilder, ResponseError}; pub type RustusResult<T> = Result<T, RustusError>; @@ -16,6 +15,8 @@ pub enum RustusError { WrongOffset, #[error("Unknown error")] Unknown, + #[error("File is frozen")] + FrozenFile, #[error("Unable to serialize object")] UnableToSerialize(#[from] serde_json::Error), #[cfg(feature = "db_info_storage")] @@ -39,6 +40,13 @@ pub enum RustusError { UnableToPrepareStorage(String), #[error("Unknown extension: {0}")] UnknownExtension(String), + #[cfg(feature = "http_notifier")] + #[error("Http request failed: {0}")] + HttpRequestError(#[from] reqwest::Error), + #[error("Hook invocation failed. Reason: {0}")] + HookError(String), + #[error("Unable to configure logging: {0}")] + LogConfigError(#[from] log::SetLoggerError), } /// This conversion allows us to use `RustusError` in the `main` function. @@ -52,7 +60,7 @@ impl From<RustusError> for Error { impl ResponseError for RustusError { fn error_response(&self) -> HttpResponse { HttpResponseBuilder::new(self.status_code()) - .set_header("Content-Type", "text/html; charset=utf-8") + .insert_header(("Content-Type", "text/html; charset=utf-8")) .body(format!("{}", self)) } @@ -60,6 +68,7 @@ impl ResponseError for RustusError { match self { RustusError::FileNotFound => StatusCode::NOT_FOUND, RustusError::WrongOffset => StatusCode::CONFLICT, + RustusError::FrozenFile | RustusError::HookError(_) => StatusCode::BAD_REQUEST, _ => StatusCode::INTERNAL_SERVER_ERROR, } } diff --git a/src/info_storages/models/available_info_storages.rs b/src/info_storages/models/available_info_storages.rs index 256fb34..66a84cd 100644 --- a/src/info_storages/models/available_info_storages.rs +++ b/src/info_storages/models/available_info_storages.rs @@ -1,12 +1,10 @@ -use std::str::FromStr; - use derive_more::{Display, From}; use crate::errors::RustusResult; -use crate::RustusConf; +use crate::{from_str, RustusConf}; use crate::info_storages::{file_info_storage, InfoStorage}; -use strum::{EnumIter, IntoEnumIterator}; +use strum::EnumIter; #[cfg(feature = "db_info_storage")] use crate::info_storages::db_info_storage; @@ -16,36 +14,17 @@ use crate::info_storages::redis_info_storage; #[derive(PartialEq, From, Display, Clone, Debug, EnumIter)] pub enum AvailableInfoStores { - #[display(fmt = "file_info_storage")] + #[display(fmt = "file-info-storage")] Files, #[cfg(feature = "db_info_storage")] - #[display(fmt = "db_info_storage")] + #[display(fmt = "db-info-storage")] DB, #[cfg(feature = "redis_info_storage")] - #[display(fmt = "redis_info_storage")] + #[display(fmt = "redis-info-storage")] Redis, } -impl FromStr for AvailableInfoStores { - type Err = String; - - fn from_str(input: &str) -> Result<Self, Self::Err> { - let available_stores = AvailableInfoStores::iter() - .map(|info_store| format!("\t* {}", info_store.to_string())) - .collect::<Vec<String>>() - .join("\n"); - let inp_string = String::from(input); - for store in AvailableInfoStores::iter() { - if inp_string == store.to_string() { - return Ok(store); - } - } - Err(format!( - "Unknown info storage type.\n Available storages:\n{}", - available_stores - )) - } -} +from_str!(AvailableInfoStores, "info storage"); impl AvailableInfoStores { /// Convert `AvailableInfoStores` to the impl `InfoStorage`. diff --git a/src/info_storages/models/file_info.rs b/src/info_storages/models/file_info.rs index 4d2ff9a..154984e 100644 --- a/src/info_storages/models/file_info.rs +++ b/src/info_storages/models/file_info.rs @@ -11,7 +11,7 @@ pub struct FileInfo { pub id: String, pub offset: usize, pub length: usize, - pub path: String, + pub path: Option<String>, #[serde(with = "ts_seconds")] pub created_at: DateTime<Utc>, pub deferred_size: bool, @@ -31,7 +31,7 @@ impl FileInfo { pub fn new( file_id: &str, file_size: Option<usize>, - path: String, + path: Option<String>, initial_metadata: Option<HashMap<String, String>>, ) -> FileInfo { let id = String::from(file_id); diff --git a/src/main.rs b/src/main.rs index f906b87..9c737dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,8 +6,12 @@ use actix_web::{ dev::{Server, Service}, middleware, web, App, HttpServer, }; -use log::{error, info}; +use fern::colors::{Color, ColoredLevelConfig}; +use fern::Dispatch; +use log::LevelFilter; +use crate::errors::RustusResult; +use crate::notifiers::models::notification_manager::NotificationManager; use config::RustusConf; use crate::storages::Storage; @@ -25,12 +29,25 @@ fn greeting(app_conf: &RustusConf) { let extensions = app_conf .extensions_vec() .into_iter() - .map(String::from) + .map(|x| x.to_string()) .collect::<Vec<String>>() - .join(","); - info!("Welcome to rustus!"); - info!("Base URL: {}", app_conf.base_url()); - info!("Available extensions {}", extensions); + .join(", "); + let hooks = app_conf + .notification_opts + .hooks + .clone() + .into_iter() + .map(|x| x.to_string()) + .collect::<Vec<String>>() + .join(", "); + let rustus_logo = include_str!("../imgs/rustus_startup_logo.txt"); + eprintln!("\n\n{}", rustus_logo); + eprintln!("Welcome to rustus!"); + eprintln!("Base URL: {}", app_conf.base_url()); + eprintln!("Available extensions: {}", extensions); + eprintln!("Enabled hooks: {}", hooks); + eprintln!(); + eprintln!(); } /// Creates Actix server. @@ -49,24 +66,29 @@ fn greeting(app_conf: &RustusConf) { pub fn create_server( storage: Box<dyn Storage + Send + Sync>, app_conf: RustusConf, + notification_manager: NotificationManager, ) -> Result<Server, std::io::Error> { let host = app_conf.host.clone(); let port = app_conf.port; let workers = app_conf.workers; + let app_conf_data = web::Data::new(app_conf.clone()); let storage_data: web::Data<Box<dyn Storage + Send + Sync>> = web::Data::from(Arc::new(storage)); + let manager_data: web::Data<Box<NotificationManager>> = + web::Data::from(Arc::new(Box::new(notification_manager))); let mut server = HttpServer::new(move || { App::new() - .data(app_conf.clone()) + .app_data(app_conf_data.clone()) .app_data(storage_data.clone()) + .app_data(manager_data.clone()) // Adds all routes. .configure(protocol::setup(app_conf.clone())) // Main middleware that appends TUS headers. .wrap( middleware::DefaultHeaders::new() - .header("Tus-Resumable", "1.0.0") - .header("Tus-Max-Size", app_conf.max_body_size.to_string()) - .header("Tus-Version", "1.0.0"), + .add(("Tus-Resumable", "1.0.0")) + .add(("Tus-Max-Size", app_conf.max_body_size.to_string())) + .add(("Tus-Version", "1.0.0")), ) .wrap(middleware::Logger::new("\"%r\" \"-\" \"%s\" \"%a\" \"%D\"")) // Middleware that overrides method of a request if @@ -95,24 +117,60 @@ pub fn create_server( Ok(server.run()) } +fn setup_logging(app_config: &RustusConf) -> RustusResult<()> { + let colors = ColoredLevelConfig::new() + // use builder methods + .info(Color::Green) + .warn(Color::Yellow) + .debug(Color::BrightCyan) + .error(Color::BrightRed) + .trace(Color::Blue); + + Dispatch::new() + .level(app_config.log_level) + .level_for("rbatis", LevelFilter::Error) + .chain(std::io::stdout()) + .format(move |out, message, record| { + out.finish(format_args!( + "{}[{}] {}", + chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S%:z]"), + colors.color(record.level()), + message + )); + }) + .apply()?; + Ok(()) +} + /// Main program entrypoint. #[actix_web::main] async fn main() -> std::io::Result<()> { let app_conf = RustusConf::from_args(); - simple_logging::log_to_stderr(app_conf.log_level); + // Configuring logging. + // I may change it to another log system like `fern` later, idk. + setup_logging(&app_conf)?; + // Printing cool message. + greeting(&app_conf); + // Creating info storage. + // It's used to store info about files. let mut info_storage = app_conf .info_storage_opts .info_storage .get(&app_conf) .await?; + // Preparing it, lol. info_storage.prepare().await?; + + // Creating file storage. let mut storage = app_conf.storage_opts.storage.get(&app_conf, info_storage); - if let Err(err) = storage.prepare().await { - error!("{}", err); - return Err(err.into()); - } - greeting(&app_conf); - let server = create_server(storage, app_conf)?; + // Preparing it. + storage.prepare().await?; + + // Creating notification manager. + let notification_manager = NotificationManager::new(&app_conf); + + // Creating actual server and running it. + let server = create_server(storage, app_conf, notification_manager)?; server.await } diff --git a/src/notifiers/http_notifier.rs b/src/notifiers/http_notifier.rs new file mode 100644 index 0000000..dcd50b3 --- /dev/null +++ b/src/notifiers/http_notifier.rs @@ -0,0 +1,48 @@ +use crate::errors::RustusResult; + +use crate::notifiers::{Hook, Notifier}; + +use async_trait::async_trait; +use futures::future::try_join_all; +use log::debug; +use reqwest::Client; +use std::time::Duration; + +pub struct HttpNotifier { + urls: Vec<String>, + client: Client, +} + +impl HttpNotifier { + pub fn new(urls: Vec<String>) -> Self { + let client = Client::new(); + Self { urls, client } + } +} + +#[async_trait] +impl Notifier for HttpNotifier { + async fn prepare(&mut self) -> RustusResult<()> { + Ok(()) + } + + async fn send_message(&self, message: String, hook: Hook) -> RustusResult<()> { + debug!("Starting HTTP Hook."); + let idempotency_key = uuid::Uuid::new_v4().to_string(); + let requests_vec = self.urls.iter().map(|url| { + debug!("Preparing request for {}", url); + self.client + .post(url.as_str()) + .header("Idempotency-Key", idempotency_key.as_str()) + .header("Hook-Name", hook.clone().to_string()) + .timeout(Duration::from_secs(2)) + .body(message.clone()) + .send() + }); + let responses = try_join_all(requests_vec).await?; + for resp in responses { + resp.error_for_status()?; + } + Ok(()) + } +} diff --git a/src/notifiers/mod.rs b/src/notifiers/mod.rs index feb8e34..096a525 100644 --- a/src/notifiers/mod.rs +++ b/src/notifiers/mod.rs @@ -1,2 +1,7 @@ -mod models; -mod notifier; +#[cfg(feature = "http_notifier")] +pub mod http_notifier; +pub mod models; + +pub use models::hooks::Hook; +pub use models::message_format::Format; +pub use models::notifier::Notifier; diff --git a/src/notifiers/models/hooks.rs b/src/notifiers/models/hooks.rs new file mode 100644 index 0000000..fc33fb1 --- /dev/null +++ b/src/notifiers/models/hooks.rs @@ -0,0 +1,20 @@ +use crate::from_str; +use derive_more::{Display, From}; +use strum::EnumIter; + +/// Hooks for notifications. +#[derive(Copy, Clone, Debug, Display, From, EnumIter, Eq, PartialEq)] +pub enum Hook { + #[display(fmt = "pre-create")] + PreCreate, + #[display(fmt = "post-create")] + PostCreate, + #[display(fmt = "post-receive")] + PostReceive, + #[display(fmt = "post-terminate")] + PostTerminate, + #[display(fmt = "post-finish")] + PostFinish, +} + +from_str!(Hook, "hook"); diff --git a/src/notifiers/models/message.rs b/src/notifiers/models/message.rs deleted file mode 100644 index 4006433..0000000 --- a/src/notifiers/models/message.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::info_storages::FileInfo; -use actix_web::HttpRequest; - -pub struct Message<'a> { - request: &'a HttpRequest, - file_info: FileInfo, -} diff --git a/src/notifiers/models/message_format.rs b/src/notifiers/models/message_format.rs new file mode 100644 index 0000000..d640192 --- /dev/null +++ b/src/notifiers/models/message_format.rs @@ -0,0 +1,162 @@ +use crate::errors::RustusResult; +use crate::info_storages::FileInfo; +use actix_web::HttpRequest; +use derive_more::{Display, From}; +use serde::Serialize; +use serde_json::Map; +use serde_json::Value; +use std::collections::HashMap; + +use crate::from_str; +use strum::EnumIter; + +#[derive(Clone, Debug, Eq, Display, From, PartialEq, EnumIter)] +pub enum Format { + #[display(fmt = "default")] + Default, + #[display(fmt = "tusd")] + Tusd, + #[display(fmt = "celery")] + Celery, +} + +from_str!(Format, "format"); + +impl Format { + pub fn format(&self, request: &HttpRequest, file_info: &FileInfo) -> RustusResult<String> { + match self { + Self::Default => default_format(request, file_info), + Self::Tusd => tusd_format(request, file_info), + Self::Celery => celery_format(request, file_info), + } + } +} + +#[derive(Serialize)] +#[serde(rename_all = "PascalCase")] +struct TusdStorageInfo { + #[serde(rename = "Type")] + storage_type: String, + path: Option<String>, +} + +#[derive(Serialize)] +#[serde(rename_all = "PascalCase")] +struct TusdFileInfo { + #[serde(rename = "ID")] + id: String, + offset: usize, + size: usize, + is_final: bool, + is_partial: bool, + partial_uploads: Option<Vec<String>>, + metadata: HashMap<String, String>, + storage: TusdStorageInfo, +} + +impl From<FileInfo> for TusdFileInfo { + fn from(file_info: FileInfo) -> Self { + Self { + id: file_info.id, + offset: file_info.offset, + size: file_info.length, + is_final: true, + is_partial: false, + partial_uploads: None, + metadata: file_info.metadata, + storage: TusdStorageInfo { + storage_type: "filestore".into(), + path: file_info.path, + }, + } + } +} + +/// Turn request into `serde_json::Value`. +/// +/// This function is used by different formats. +fn serialize_request( + request: &HttpRequest, + method_str: String, + remote_addr_str: String, + headers_str: String, + use_arrays: bool, +) -> Value { + let mut map = Map::new(); + map.insert("URI".into(), Value::String(request.uri().to_string())); + map.insert(method_str, Value::String(request.method().to_string())); + map.insert( + remote_addr_str, + Value::String( + request + .connection_info() + .realip_remote_addr() + .map_or_else(String::new, String::from), + ), + ); + let mut headers_map = Map::new(); + for (name, value) in request.headers() { + if let Ok(header_val) = value.to_str().map(String::from) { + if use_arrays { + headers_map.insert( + name.to_string(), + Value::Array(vec![Value::String(header_val)]), + ); + } else { + headers_map.insert(name.to_string(), Value::String(header_val)); + } + } + } + map.insert(headers_str, Value::Object(headers_map)); + Value::Object(map) +} + +/// Default format is specific for Rustus. +/// +/// This format is a simple serialized `FileInfo` and some parts of the request. +pub fn default_format(request: &HttpRequest, file_info: &FileInfo) -> RustusResult<String> { + let mut result_map = Map::new(); + result_map.insert("upload".into(), serde_json::to_value(file_info)?); + result_map.insert( + "request".into(), + serialize_request( + request, + "method".into(), + "remote_addr".into(), + "headers".into(), + false, + ), + ); + Ok(Value::Object(result_map).to_string()) +} + +/// This format follows TUSD hooks. +/// +/// You can read more about tusd hooks +/// [here](https://github.com/tus/tusd/blob/master/docs/hooks.md). +/// +/// Generally speaking, it's almost the same as the default format, +/// but some variables are ommited and headers are added to the request. +pub fn tusd_format(request: &HttpRequest, file_info: &FileInfo) -> RustusResult<String> { + let mut result_map = Map::new(); + + result_map.insert( + "Upload".into(), + serde_json::to_value(TusdFileInfo::from(file_info.clone()))?, + ); + result_map.insert( + "HTTPRequest".into(), + serialize_request( + request, + "Method".into(), + "RemoteAddr".into(), + "Header".into(), + true, + ), + ); + Ok(Value::Object(result_map).to_string()) +} + +pub fn celery_format(_request: &HttpRequest, _file_info: &FileInfo) -> RustusResult<String> { + todo!() +} diff --git a/src/notifiers/models/mod.rs b/src/notifiers/models/mod.rs index e216a50..e8571be 100644 --- a/src/notifiers/models/mod.rs +++ b/src/notifiers/models/mod.rs @@ -1 +1,4 @@ -pub mod message; +pub mod hooks; +pub mod message_format; +pub mod notification_manager; +pub mod notifier; diff --git a/src/notifiers/models/notification_manager.rs b/src/notifiers/models/notification_manager.rs new file mode 100644 index 0000000..10ccb4f --- /dev/null +++ b/src/notifiers/models/notification_manager.rs @@ -0,0 +1,44 @@ +use crate::errors::{RustusError, RustusResult}; +#[cfg(feature = "http_notifier")] +use crate::notifiers::http_notifier; +use crate::notifiers::{Hook, Notifier}; +use crate::RustusConf; +use futures::future::try_join_all; +use log::debug; + +pub struct NotificationManager { + notifiers: Vec<Box<dyn Notifier + Send + Sync>>, +} + +impl NotificationManager { + pub fn new(tus_config: &RustusConf) -> Self { + let mut manager = Self { + notifiers: Vec::new(), + }; + debug!("Initializing notification manager."); + #[cfg(feature = "http_notifier")] + if !tus_config.notification_opts.hooks_http_urls.is_empty() { + debug!("Found http hook urls."); + manager + .notifiers + .push(Box::new(http_notifier::HttpNotifier::new( + tus_config.notification_opts.hooks_http_urls.clone(), + ))); + } + debug!("Notification manager initialized."); + manager + } + + pub async fn send_message(&self, message: String, hook: Hook) -> RustusResult<()> { + let mut futures = Vec::new(); + for notifier in &self.notifiers { + futures.push(notifier.send_message(message.clone(), hook)); + } + if !futures.is_empty() { + try_join_all(futures) + .await + .map_err(|err| RustusError::HookError(err.to_string()))?; + } + Ok(()) + } +} diff --git a/src/notifiers/models/notifier.rs b/src/notifiers/models/notifier.rs new file mode 100644 index 0000000..1b5b9c8 --- /dev/null +++ b/src/notifiers/models/notifier.rs @@ -0,0 +1,10 @@ +use crate::errors::RustusResult; + +use crate::notifiers::Hook; +use async_trait::async_trait; + +#[async_trait] +pub trait Notifier { + async fn prepare(&mut self) -> RustusResult<()>; + async fn send_message(&self, message: String, hook: Hook) -> RustusResult<()>; +} diff --git a/src/notifiers/notifier.rs b/src/notifiers/notifier.rs deleted file mode 100644 index f71f3cd..0000000 --- a/src/notifiers/notifier.rs +++ /dev/null @@ -1,6 +0,0 @@ -use async_trait::async_trait; - -#[async_trait] -trait Notifier { - async fn send_message(); -} diff --git a/src/protocol/core/mod.rs b/src/protocol/core/mod.rs index 312ea32..df00d5c 100644 --- a/src/protocol/core/mod.rs +++ b/src/protocol/core/mod.rs @@ -40,7 +40,7 @@ pub fn add_extension(web_app: &mut web::ServiceConfig, app_conf: &RustusConf) { .name("core:file_info") .guard(guard::Head()) // Header to prevent the client and/or proxies from caching the response. - .wrap(middleware::DefaultHeaders::new().header("Cache-Control", "no-store")) + .wrap(middleware::DefaultHeaders::new().add(("Cache-Control", "no-store"))) .to(routes::get_file_info), ); } diff --git a/src/protocol/core/routes.rs b/src/protocol/core/routes.rs index 3620b79..8fe8366 100644 --- a/src/protocol/core/routes.rs +++ b/src/protocol/core/routes.rs @@ -1,24 +1,19 @@ -use actix_web::{ - dev::HttpResponseBuilder, - http::StatusCode, - web, - web::{Buf, Bytes}, - HttpRequest, HttpResponse, -}; +use actix_web::{http::StatusCode, web, web::Bytes, HttpRequest, HttpResponse}; +use crate::notifiers::Hook; use crate::utils::headers::{check_header, parse_header}; -use crate::{RustusConf, Storage}; +use crate::{NotificationManager, RustusConf, Storage}; #[allow(clippy::needless_pass_by_value)] pub fn server_info(app_conf: web::Data<RustusConf>) -> HttpResponse { let ext_str = app_conf .extensions_vec() .into_iter() - .map(String::from) + .map(|x| x.to_string()) .collect::<Vec<String>>() .join(","); - HttpResponseBuilder::new(StatusCode::OK) - .set_header("Tus-Extension", ext_str.as_str()) + HttpResponse::Ok() + .insert_header(("Tus-Extension", ext_str.as_str())) .body("") } @@ -26,15 +21,15 @@ pub async fn get_file_info( storage: web::Data<Box<dyn Storage + Send + Sync>>, request: HttpRequest, ) -> actix_web::Result<HttpResponse> { - let mut builder = HttpResponseBuilder::new(StatusCode::OK); + let mut builder = HttpResponse::Ok(); if let Some(file_id) = request.match_info().get("file_id") { let file_info = storage.get_file_info(file_id).await?; builder - .set_header("Upload-Offset", file_info.offset.to_string()) - .set_header("Upload-Length", file_info.length.to_string()) - .set_header("Content-Length", file_info.offset.to_string()); + .insert_header(("Upload-Offset", file_info.offset.to_string())) + .insert_header(("Upload-Length", file_info.length.to_string())) + .insert_header(("Content-Length", file_info.offset.to_string())); if file_info.deferred_size { - builder.set_header("Upload-Defer-Length", "1"); + builder.insert_header(("Upload-Defer-Length", "1")); } } else { builder.status(StatusCode::NOT_FOUND); @@ -46,6 +41,8 @@ pub async fn write_bytes( request: HttpRequest, bytes: Bytes, storage: web::Data<Box<dyn Storage + Send + Sync>>, + notification_manager: web::Data<Box<NotificationManager>>, + app_conf: web::Data<RustusConf>, ) -> actix_web::Result<HttpResponse> { if !check_header(&request, "Content-Type", "application/offset+octet-stream") { return Ok(HttpResponse::UnsupportedMediaType().body("")); @@ -53,17 +50,28 @@ pub async fn write_bytes( let offset = parse_header(&request, "Upload-Offset"); if offset.is_none() { - return Ok(HttpResponseBuilder::new(StatusCode::UNSUPPORTED_MEDIA_TYPE).body("")); + return Ok(HttpResponse::UnsupportedMediaType().body("")); } if let Some(file_id) = request.match_info().get("file_id") { - let offset = storage - .add_bytes(file_id, offset.unwrap(), bytes.bytes()) + let file_info = storage + .add_bytes(file_id, offset.unwrap(), bytes.as_ref()) .await?; - Ok(HttpResponseBuilder::new(StatusCode::NO_CONTENT) - .set_header("Upload-Offset", offset.to_string()) + let mut hook = Hook::PostReceive; + if file_info.length == file_info.offset { + hook = Hook::PostFinish; + } + if app_conf.hook_is_active(hook) { + let message = app_conf + .notification_opts + .notification_format + .format(&request, &file_info)?; + tokio::spawn(async move { notification_manager.send_message(message, hook).await }); + } + Ok(HttpResponse::NoContent() + .insert_header(("Upload-Offset", file_info.offset.to_string())) .body("")) } else { - Ok(HttpResponseBuilder::new(StatusCode::NOT_FOUND).body("")) + Ok(HttpResponse::NotFound().body("")) } } diff --git a/src/protocol/creation/routes.rs b/src/protocol/creation/routes.rs index 2bd587d..79079dd 100644 --- a/src/protocol/creation/routes.rs +++ b/src/protocol/creation/routes.rs @@ -1,11 +1,13 @@ use std::collections::HashMap; -use actix_web::web::{Buf, Bytes}; +use actix_web::web::Bytes; use actix_web::{web, HttpRequest, HttpResponse}; -use crate::config::ProtocolExtensions; +use crate::info_storages::FileInfo; +use crate::notifiers::Hook; +use crate::protocol::extensions::Extensions; use crate::utils::headers::{check_header, parse_header}; -use crate::{RustusConf, Storage}; +use crate::{NotificationManager, RustusConf, Storage}; /// Get metadata info from request. /// @@ -49,6 +51,7 @@ fn get_metadata(request: &HttpRequest) -> Option<HashMap<String, String>> { pub async fn create_file( storage: web::Data<Box<dyn Storage + Send + Sync>>, + notification_manager: web::Data<Box<NotificationManager>>, app_conf: web::Data<RustusConf>, request: HttpRequest, bytes: Bytes, @@ -61,7 +64,7 @@ pub async fn create_file( // Indicator that creation-defer-length is enabled. let defer_ext = app_conf .extensions_vec() - .contains(&ProtocolExtensions::CreationDeferLength); + .contains(&Extensions::CreationDeferLength); // Check that Upload-Length header is provided. // Otherwise checking that defer-size feature is enabled @@ -71,30 +74,52 @@ pub async fn create_file( } let meta = get_metadata(&request); + + if app_conf.hook_is_active(Hook::PreCreate) { + let initial_file_info = FileInfo::new("", length, None, meta.clone()); + let message = app_conf + .notification_opts + .notification_format + .format(&request, &initial_file_info)?; + notification_manager + .send_message(message, Hook::PreCreate) + .await?; + } + // Create file and get the id. - let file_id = storage.create_file(length, meta).await?; + let mut file_info = storage.create_file(length, meta).await?; // Create upload URL for this file. - let upload_url = request.url_for("core:write_bytes", &[file_id.clone()])?; - - let mut upload_offset = 0; + let upload_url = request.url_for("core:write_bytes", &[file_info.id.clone()])?; // Checking if creation-with-upload extension is enabled. let with_upload = app_conf .extensions_vec() - .contains(&ProtocolExtensions::CreationWithUpload); + .contains(&Extensions::CreationWithUpload); if with_upload && !bytes.is_empty() { if !check_header(&request, "Content-Type", "application/offset+octet-stream") { return Ok(HttpResponse::BadRequest().body("")); } // Writing first bytes. - upload_offset = storage - .add_bytes(file_id.as_str(), 0, bytes.bytes()) + file_info = storage + .add_bytes(file_info.id.as_str(), 0, bytes.as_ref()) .await?; } + if app_conf.hook_is_active(Hook::PostCreate) { + let message = app_conf + .notification_opts + .notification_format + .format(&request, &file_info)?; + tokio::spawn(async move { + notification_manager + .send_message(message, Hook::PostCreate) + .await + }); + } + Ok(HttpResponse::Created() - .set_header("Location", upload_url.as_str()) - .set_header("Upload-Offset", upload_offset.to_string()) + .insert_header(("Location", upload_url.as_str())) + .insert_header(("Upload-Offset", file_info.offset.to_string())) .body("")) } diff --git a/src/protocol/extensions.rs b/src/protocol/extensions.rs new file mode 100644 index 0000000..5624b83 --- /dev/null +++ b/src/protocol/extensions.rs @@ -0,0 +1,21 @@ +use derive_more::{Display, From}; +use strum::EnumIter; + +use crate::from_str; + +/// Enum of available Protocol Extensions +#[derive(PartialEq, Debug, PartialOrd, Display, EnumIter, From, Clone, Ord, Eq)] +pub enum Extensions { + #[display(fmt = "creation-defer-length")] + CreationDeferLength, + #[display(fmt = "creation-with-upload")] + CreationWithUpload, + #[display(fmt = "creation")] + Creation, + #[display(fmt = "termination")] + Termination, + #[display(fmt = "getting")] + Getting, +} + +from_str!(Extensions, "extension"); diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 38d198c..ecd6dba 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -1,10 +1,10 @@ use actix_web::web; -use crate::config::ProtocolExtensions; use crate::RustusConf; mod core; mod creation; +pub mod extensions; mod getting; mod termination; @@ -16,11 +16,11 @@ pub fn setup(app_conf: RustusConf) -> Box<dyn Fn(&mut web::ServiceConfig)> { Box::new(move |web_app| { for extension in app_conf.extensions_vec() { match extension { - ProtocolExtensions::Creation => creation::add_extension(web_app, &app_conf), - ProtocolExtensions::Termination => { + extensions::Extensions::Creation => creation::add_extension(web_app, &app_conf), + extensions::Extensions::Termination => { termination::add_extension(web_app, &app_conf); } - ProtocolExtensions::Getting => { + extensions::Extensions::Getting => { getting::add_extension(web_app, &app_conf); } _ => {} diff --git a/src/protocol/termination/routes.rs b/src/protocol/termination/routes.rs index 2ae818c..7222b4f 100644 --- a/src/protocol/termination/routes.rs +++ b/src/protocol/termination/routes.rs @@ -1,9 +1,8 @@ -use actix_web::dev::HttpResponseBuilder; -use actix_web::http::StatusCode; use actix_web::{web, HttpRequest, HttpResponse}; use crate::errors::RustusResult; -use crate::Storage; +use crate::notifiers::Hook; +use crate::{NotificationManager, RustusConf, Storage}; /// Terminate uploading. /// @@ -12,10 +11,23 @@ use crate::Storage; pub async fn terminate( storage: web::Data<Box<dyn Storage + Send + Sync>>, request: HttpRequest, + notification_manager: web::Data<Box<NotificationManager>>, + app_conf: web::Data<RustusConf>, ) -> RustusResult<HttpResponse> { let file_id_opt = request.match_info().get("file_id").map(String::from); if let Some(file_id) = file_id_opt { - storage.remove_file(file_id.as_str()).await?; + let file_info = storage.remove_file(file_id.as_str()).await?; + if app_conf.hook_is_active(Hook::PostTerminate) { + let message = app_conf + .notification_opts + .notification_format + .format(&request, &file_info)?; + tokio::spawn(async move { + notification_manager + .send_message(message, Hook::PostTerminate) + .await + }); + } } - Ok(HttpResponseBuilder::new(StatusCode::NO_CONTENT).body("")) + Ok(HttpResponse::NoContent().body("")) } diff --git a/src/storages/file_storage.rs b/src/storages/file_storage.rs index ccd93bf..bad2c39 100644 --- a/src/storages/file_storage.rs +++ b/src/storages/file_storage.rs @@ -35,7 +35,12 @@ impl FileStorage { .app_conf .storage_opts .data_dir - .join(self.app_conf.dir_struct()); + .canonicalize() + .map_err(|err| { + error!("{}", err); + RustusError::UnableToWrite(err.to_string()) + })? + .join(self.app_conf.dir_struct().as_str()); create_dir_all(dir.as_path()).await.map_err(|err| { error!("{}", err); RustusError::UnableToWrite(err.to_string()) @@ -62,10 +67,15 @@ impl Storage for FileStorage { async fn get_contents(&self, file_id: &str) -> RustusResult<NamedFile> { let info = self.info_storage.get_info(file_id).await?; - NamedFile::open(info.path.as_str()).map_err(|err| { - error!("{:?}", err); - RustusError::FileNotFound - }) + if info.path.is_none() { + return Err(RustusError::FileNotFound); + } + NamedFile::open_async(info.path.unwrap().as_str()) + .await + .map_err(|err| { + error!("{:?}", err); + RustusError::FileNotFound + }) } async fn add_bytes( @@ -73,16 +83,22 @@ impl Storage for FileStorage { file_id: &str, request_offset: usize, bytes: &[u8], - ) -> RustusResult<usize> { + ) -> RustusResult<FileInfo> { let mut info = self.info_storage.get_info(file_id).await?; if info.offset != request_offset { return Err(RustusError::WrongOffset); } + if info.path.is_none() { + return Err(RustusError::FileNotFound); + } + if info.offset == info.length { + return Err(RustusError::FrozenFile); + } let mut file = OpenOptions::new() .write(true) .append(true) .create(false) - .open(info.path.as_str()) + .open(info.path.as_ref().unwrap()) .await .map_err(|err| { error!("{:?}", err); @@ -90,18 +106,18 @@ impl Storage for FileStorage { })?; file.write_all(bytes).await.map_err(|err| { error!("{:?}", err); - RustusError::UnableToWrite(info.path.clone()) + RustusError::UnableToWrite(info.path.clone().unwrap()) })?; info.offset += bytes.len(); self.info_storage.set_info(&info, false).await?; - Ok(info.offset) + Ok(info) } async fn create_file( &self, file_size: Option<usize>, metadata: Option<HashMap<String, String>>, - ) -> RustusResult<String> { + ) -> RustusResult<FileInfo> { let file_id = Uuid::new_v4().simple().to_string(); let file_path = self.data_file_path(file_id.as_str()).await?; let mut file = OpenOptions::new() @@ -124,20 +140,23 @@ impl Storage for FileStorage { let file_info = FileInfo::new( file_id.as_str(), file_size, - file_path.display().to_string(), + Some(file_path.display().to_string()), metadata, ); self.info_storage.set_info(&file_info, true).await?; - Ok(file_id) + Ok(file_info) } - async fn remove_file(&self, file_id: &str) -> RustusResult<()> { + async fn remove_file(&self, file_id: &str) -> RustusResult<FileInfo> { let info = self.info_storage.get_info(file_id).await?; + if info.path.is_none() { + return Err(RustusError::FileNotFound); + } self.info_storage.remove_info(file_id).await?; - let data_path = PathBuf::from(info.path.clone()); + let data_path = PathBuf::from(info.path.as_ref().unwrap().clone()); if !data_path.exists() { return Err(RustusError::FileNotFound); } @@ -145,6 +164,6 @@ impl Storage for FileStorage { error!("{:?}", err); RustusError::UnableToRemove(String::from(file_id)) })?; - Ok(()) + Ok(info) } } diff --git a/src/storages/models/available_stores.rs b/src/storages/models/available_stores.rs index e13c670..931922a 100644 --- a/src/storages/models/available_stores.rs +++ b/src/storages/models/available_stores.rs @@ -1,31 +1,17 @@ use crate::info_storages::InfoStorage; use crate::storages::file_storage; -use crate::{RustusConf, Storage}; +use crate::{from_str, RustusConf, Storage}; use derive_more::{Display, From}; -use std::str::FromStr; +use strum::EnumIter; /// Enum of available Storage implementations. -#[derive(PartialEq, From, Display, Clone, Debug)] +#[derive(PartialEq, From, Display, EnumIter, Clone, Debug)] pub enum AvailableStores { - #[display(fmt = "FileStorage")] + #[display(fmt = "file-storage")] FileStorage, } -impl FromStr for AvailableStores { - type Err = String; - - /// This function converts string to the `AvailableStore` item. - /// This function is used by structopt to parse CLI parameters. - /// - /// # Params - /// `input` - input string. - fn from_str(input: &str) -> Result<AvailableStores, Self::Err> { - match input { - "file_storage" => Ok(AvailableStores::FileStorage), - _ => Err(String::from("Unknown storage type")), - } - } -} +from_str!(AvailableStores, "storage"); impl AvailableStores { /// Convert `AvailableStores` to the Storage. diff --git a/src/storages/models/storage.rs b/src/storages/models/storage.rs index 89bed1b..955ad34 100644 --- a/src/storages/models/storage.rs +++ b/src/storages/models/storage.rs @@ -44,7 +44,7 @@ pub trait Storage { file_id: &str, request_offset: usize, bytes: &[u8], - ) -> RustusResult<usize>; + ) -> RustusResult<FileInfo>; /// Create file in storage. /// @@ -57,7 +57,7 @@ pub trait Storage { &self, file_size: Option<usize>, metadata: Option<HashMap<String, String>>, - ) -> RustusResult<String>; + ) -> RustusResult<FileInfo>; /// Remove file from storage /// @@ -66,5 +66,5 @@ pub trait Storage { /// /// # Params /// `file_id` - unique file identifier; - async fn remove_file(&self, file_id: &str) -> RustusResult<()>; + async fn remove_file(&self, file_id: &str) -> RustusResult<FileInfo>; } diff --git a/src/utils/enums.rs b/src/utils/enums.rs new file mode 100644 index 0000000..0ae1ae3 --- /dev/null +++ b/src/utils/enums.rs @@ -0,0 +1,28 @@ +#[macro_export] +macro_rules! from_str { + ($enum_name:ty, $name:literal) => { + use std::str::FromStr; + use strum::IntoEnumIterator; + + impl FromStr for $enum_name { + type Err = String; + + fn from_str(input: &str) -> Result<Self, Self::Err> { + let available_stores = <$enum_name>::iter() + .map(|info_store| format!("\t* {}", info_store.to_string())) + .collect::<Vec<String>>() + .join("\n"); + let inp_string = String::from(input); + for store in <$enum_name>::iter() { + if inp_string == store.to_string() { + return Ok(store); + } + } + Err(format!( + "Unknown {} '{}'.\n Available {}s:\n{}", + $name, input, $name, available_stores + )) + } + } + }; +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 7b67a24..0f6b300 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1 +1,2 @@ +pub mod enums; pub mod headers; -- GitLab