From 943fc531ddde25b36c77f79f9d97e34ecd64a7f1 Mon Sep 17 00:00:00 2001 From: Fedor Sakharov Date: Mon, 10 Jan 2022 12:35:36 +0300 Subject: [PATCH] rouille -> warp (#131) * Initial commit * A bit more errors * clippy * more clippy * No default dist-server * more async cod * remove all blocking reqwests * fmt * Fix content types and test harness * maybe green ci * bump timeout a bit and create a client only once * remove unused code * make thiserror optional * bring back void * do not change CI docker script * fork is not async friendly * async bind * fmt * more fixes * async handle_assign_job * async basic_compile * minor fixes * fmt * Adds a comment on native-tls --- Cargo.lock | 1599 +++++++++++--------------- Cargo.toml | 8 +- src/bin/cachepot-dist/build.rs | 12 +- src/bin/cachepot-dist/main.rs | 62 +- src/bin/cachepot-dist/token_check.rs | 46 +- src/compiler/args.rs | 2 + src/config.rs | 4 +- src/dist/client_auth.rs | 15 +- src/dist/http.rs | 1498 ++++++++++++++++-------- src/dist/mod.rs | 32 +- src/lib.rs | 3 - src/util.rs | 49 +- tests/dist.rs | 73 +- tests/harness/mod.rs | 277 ++--- 14 files changed, 2012 insertions(+), 1668 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b5d6019..3eea607d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,69 +4,50 @@ version = 3 [[package]] name = "adler" -version = "0.2.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" -version = "0.3.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ "generic-array", ] [[package]] name = "aes" -version = "0.4.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7001367fde4c768a19d1029f0a8be5abd9308e1119846d5bd9ad26297b8faf5" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ - "aes-soft", - "aesni", - "block-cipher", + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "opaque-debug", ] [[package]] name = "aes-gcm" -version = "0.6.0" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f5007801316299f922a6198d1d09a0bae95786815d066d5880d13f7c45ead1" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" dependencies = [ "aead", "aes", - "block-cipher", + "cipher", + "ctr", "ghash", "subtle", ] -[[package]] -name = "aes-soft" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4925647ee64e5056cf231608957ce7c81e12d6d6e316b9ce1404778cc1d35fa7" -dependencies = [ - "block-cipher", - "byteorder", - "opaque-debug 0.2.3", -] - -[[package]] -name = "aesni" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050d39b0b7688b3a3254394c3e30a9d66c41dcf9b05b0e2dbdc623f6505d264" -dependencies = [ - "block-cipher", - "opaque-debug 0.2.3", -] - [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -82,9 +63,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.37" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" +checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" [[package]] name = "ar" @@ -110,20 +91,15 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" -[[package]] -name = "ascii" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14" - [[package]] name = "assert_cmd" -version = "1.0.2" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc1679af9a1ab4bea16f228b05d18f8363f8327b1fa8db00d2760cfafc6b61e" +checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe" dependencies = [ + "bstr", "doc-comment", - "predicates", + "predicates 2.1.0", "predicates-core", "predicates-tree", "wait-timeout", @@ -137,9 +113,9 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-trait" -version = "0.1.42" +version = "0.1.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" +checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" dependencies = [ "proc-macro2", "quote", @@ -169,16 +145,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder", - "safemem", -] - [[package]] name = "base64" version = "0.10.1" @@ -202,30 +168,18 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bincode" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "byteorder", "serde", ] [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "blake3" @@ -251,15 +205,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-cipher" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10" -dependencies = [ - "generic-array", -] - [[package]] name = "block-padding" version = "0.2.1" @@ -272,6 +217,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426" +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", +] + [[package]] name = "buf_redux" version = "0.8.4" @@ -290,9 +246,9 @@ checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" [[package]] name = "bumpalo" -version = "3.4.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" [[package]] name = "byteorder" @@ -351,11 +307,11 @@ dependencies = [ "futures-locks", "gzp", "hmac 0.10.1", - "http 0.2.4", + "http 0.2.5", "hyper", "hyper-tls", "hyperx", - "itertools 0.10.0", + "itertools", "jobserver", "jsonwebtoken", "lazy_static", @@ -363,9 +319,10 @@ dependencies = [ "libmount", "linked-hash-map", "local-encoding", - "log 0.4.11", + "log", "md-5", "memcached-rs", + "native-tls", "nix 0.19.1", "num_cpus", "number_prefix", @@ -373,15 +330,14 @@ dependencies = [ "parity-tokio-ipc", "percent-encoding 2.1.0", "picky", - "predicates", - "rand 0.8.3", + "predicates 1.0.8", + "rand 0.8.4", "redis", "regex", "reqwest", "retry", "ring", - "rouille", - "rsa 0.4.0", + "rsa", "rusoto_core", "rusoto_s3", "serde", @@ -397,17 +353,19 @@ dependencies = [ "tar", "tempfile", "thirtyfour_sync", - "tokio 1.13.0", + "thiserror", + "tokio 1.15.0", "tokio-serde", "tokio-util", "toml", "tower", "untrusted", - "url 2.2.0", + "url", "uuid", "version-compare", "void", "walkdir", + "warp", "which", "winapi 0.3.9", "zip", @@ -416,9 +374,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.66" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" dependencies = [ "jobserver", ] @@ -450,10 +408,13 @@ dependencies = [ ] [[package]] -name = "chunked_transfer" -version = "0.3.1" +name = "cipher" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] [[package]] name = "clap" @@ -470,15 +431,6 @@ dependencies = [ "vec_map", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - [[package]] name = "combine" version = "4.6.2" @@ -489,7 +441,7 @@ dependencies = [ "futures-core", "memchr", "pin-project-lite 0.2.7", - "tokio 1.13.0", + "tokio 1.15.0", "tokio-util", ] @@ -499,7 +451,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d6364d028778d0d98b6014fa5882da377cd10d3492b7734d266a428e9b1fca" dependencies = [ - "log 0.4.11", + "log", "md5", ] @@ -511,9 +463,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "core-foundation" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" dependencies = [ "core-foundation-sys", "libc", @@ -521,9 +473,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "core_affinity" @@ -544,42 +496,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384f8c53175c890920b6e0127b730709d2a173ca6c4dfdc81618ac9b46f648fe" [[package]] -name = "cpuid-bool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" - -[[package]] -name = "cpuid-bool" -version = "0.2.0" +name = "cpufeatures" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "crossbeam-utils" -version = "0.8.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg 1.0.1", "cfg-if 1.0.0", "lazy_static", ] [[package]] name = "crypto-mac" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" dependencies = [ "generic-array", "subtle", @@ -595,6 +543,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + [[package]] name = "daemonize" version = "0.4.1" @@ -611,6 +568,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "digest" version = "0.9.0" @@ -622,24 +585,13 @@ dependencies = [ [[package]] name = "directories" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fed639d60b58d0f53498ab13d26f621fd77569cc6edb031f4cc36a2ad9da0f" +checksum = "e69600ff1703123957937708eb27f7a564e48885c537782722ed0ba3189ce1d7" dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" -dependencies = [ - "libc", - "redox_users 0.3.5", - "winapi 0.3.9", -] - [[package]] name = "dirs-next" version = "2.0.0" @@ -652,12 +604,12 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ "libc", - "redox_users 0.3.5", + "redox_users", "winapi 0.3.9", ] @@ -668,7 +620,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users 0.4.0", + "redox_users", "winapi 0.3.9", ] @@ -691,9 +643,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dtoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" [[package]] name = "either" @@ -703,22 +655,22 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "encoding_rs" -version = "0.8.26" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801bbab217d7f79c0062f4f7205b5d4427c6d1a7bd7aafdd1475f7c59d62b283" +checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "env_logger" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "atty", "humantime", - "log 0.4.11", + "log", "regex", "termcolor", ] @@ -729,26 +681,26 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" dependencies = [ - "version_check 0.9.2", + "version_check", ] [[package]] name = "filetime" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c122a393ea57648015bf06fbd3d372378992e86b9ff5a7a497b076a28c79efe" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.1.57", + "redox_syscall", "winapi 0.3.9", ] [[package]] name = "flate2" -version = "1.0.19" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" dependencies = [ "cfg-if 1.0.0", "crc32fast", @@ -801,9 +753,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ "matches", "percent-encoding 2.1.0", @@ -823,9 +775,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures" -version = "0.3.9" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c70be434c505aee38639abccb918163b63158a4b4bb791b45b7023044bdc3c9c" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" dependencies = [ "futures-channel", "futures-core", @@ -838,9 +790,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", @@ -848,15 +800,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.9" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee9ca2f7eb4475772cf39dd1cd06208dce2670ad38f4d9c7262b3e15f127068" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" dependencies = [ "futures-core", "futures-task", @@ -865,9 +817,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-locks" @@ -876,17 +828,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50c4e684ddb2d8a4db5ca8a02b35156da129674ba4412b6f528698d58c594954" dependencies = [ "futures", - "tokio 0.2.24", + "tokio 0.2.25", ] [[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", @@ -894,23 +844,22 @@ 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-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", @@ -920,8 +869,6 @@ dependencies = [ "memchr", "pin-project-lite 0.2.7", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -932,7 +879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", - "version_check 0.9.2", + "version_check", ] [[package]] @@ -964,26 +911,20 @@ dependencies = [ "cfg-if 1.0.0", "js-sys", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", + "wasi 0.10.2+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "ghash" -version = "0.3.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" dependencies = [ - "opaque-debug 0.3.0", + "opaque-debug", "polyval", ] -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - [[package]] name = "gzp" version = "0.9.2" @@ -1001,28 +942,53 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" +checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd" dependencies = [ "bytes 1.1.0", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.4", + "http 0.2.5", "indexmap", "slab", - "tokio 1.13.0", + "tokio 1.15.0", "tokio-util", "tracing", ] [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "headers" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c4eb0471fcb85846d8b0690695ef354f9afb11cb03cac2e1d7c9253351afb0" +dependencies = [ + "base64 0.13.0", + "bitflags", + "bytes 1.1.0", + "headers-core", + "http 0.2.5", + "httpdate", + "mime", + "sha-1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http 0.2.5", +] [[package]] name = "heck" @@ -1035,9 +1001,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -1054,7 +1020,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" dependencies = [ - "crypto-mac 0.10.0", + "crypto-mac 0.10.1", "digest", ] @@ -1076,18 +1042,18 @@ checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" dependencies = [ "bytes 0.4.12", "fnv", - "itoa", + "itoa 0.4.8", ] [[package]] name = "http" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ "bytes 1.1.0", "fnv", - "itoa", + "itoa 0.4.8", ] [[package]] @@ -1097,7 +1063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ "bytes 1.1.0", - "http 0.2.4", + "http 0.2.5", "pin-project-lite 0.2.7", ] @@ -1109,35 +1075,35 @@ checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "humantime" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.14" +version = "0.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b91bb1f221b6ea1f1e4371216b70f40748774c2fb5971b450c07773fb92d26b" +checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" dependencies = [ "bytes 1.1.0", "futures-channel", "futures-core", "futures-util", "h2", - "http 0.2.4", + "http 0.2.5", "http-body", "httparse", "httpdate", - "itoa", + "itoa 0.4.8", "pin-project-lite 0.2.7", - "socket2 0.4.2", - "tokio 1.13.0", + "socket2", + "tokio 1.15.0", "tower-service", "tracing", "want", @@ -1152,7 +1118,7 @@ dependencies = [ "bytes 1.1.0", "hyper", "native-tls", - "tokio 1.13.0", + "tokio 1.15.0", "tokio-native-tls", ] @@ -1167,29 +1133,18 @@ dependencies = [ "http 0.1.21", "httparse", "language-tags", - "log 0.4.11", - "mime 0.3.16", + "log", + "mime", "percent-encoding 1.0.1", "time", - "unicase 2.6.0", -] - -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "unicase", ] [[package]] name = "idna" -version = "0.2.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", @@ -1198,9 +1153,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg 1.0.1", "hashbrown", @@ -1208,9 +1163,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", ] @@ -1226,48 +1181,45 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" +checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" [[package]] name = "itertools" -version = "0.9.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] [[package]] -name = "itertools" -version = "0.10.0" +name = "itoa" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" -dependencies = [ - "either", -] +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "jobserver" -version = "0.1.21" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.46" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] @@ -1319,9 +1271,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.98" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libm" @@ -1342,9 +1294,9 @@ dependencies = [ [[package]] name = "linked-hash-map" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "local-encoding" @@ -1359,36 +1311,27 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] [[package]] name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -dependencies = [ - "log 0.4.11", -] - -[[package]] -name = "log" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", ] [[package]] name = "matches" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "md-5" @@ -1398,7 +1341,7 @@ checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" dependencies = [ "block-buffer", "digest", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -1416,7 +1359,7 @@ dependencies = [ "bufstream", "byteorder", "conhash", - "log 0.4.11", + "log", "rand 0.7.3", "semver 0.9.0", "unix_socket", @@ -1424,18 +1367,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" - -[[package]] -name = "mime" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -dependencies = [ - "log 0.3.9", -] +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "mime" @@ -1445,21 +1379,19 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "mime_guess" -version = "1.8.8" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216929a5ee4dd316b1702eedf5e74548c123d370f47841ceaac38ca154690ca3" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" dependencies = [ - "mime 0.2.6", - "phf", - "phf_codegen", - "unicase 1.4.2", + "mime", + "unicase", ] [[package]] name = "miniz_oxide" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", "autocfg 1.0.1", @@ -1472,7 +1404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", - "log 0.4.11", + "log", "miow", "ntapi", "winapi 0.3.9", @@ -1480,29 +1412,28 @@ dependencies = [ [[package]] name = "miow" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "socket2 0.3.19", "winapi 0.3.9", ] [[package]] name = "multipart" -version = "0.15.4" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adba94490a79baf2d6a23eac897157047008272fa3eecb3373ae6377b91eca28" +checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" dependencies = [ "buf_redux", "httparse", - "log 0.4.11", - "mime 0.2.6", + "log", + "mime", "mime_guess", "quick-error", - "rand 0.4.6", + "rand 0.8.4", "safemem", - "tempdir", + "tempfile", "twoway", ] @@ -1523,7 +1454,7 @@ checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" dependencies = [ "lazy_static", "libc", - "log 0.4.11", + "log", "openssl", "openssl-probe", "openssl-sys", @@ -1586,34 +1517,15 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg 1.0.1", "num-integer", "num-traits", ] -[[package]] -name = "num-bigint-dig" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d51546d704f52ef14b3c962b5776e53d5b862e5790e40a350d366c209bd7f7a" -dependencies = [ - "autocfg 0.1.7", - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.7.3", - "serde", - "smallvec", - "zeroize", -] - [[package]] name = "num-bigint-dig" version = "0.7.0" @@ -1627,7 +1539,8 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.3", + "rand 0.8.4", + "serde", "smallvec", "zeroize", ] @@ -1665,9 +1578,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -1681,24 +1594,18 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "oid" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293d5f18898078ea69ba1c84f3688d1f2b6744df8211da36197153157cee7055" +checksum = "9c19903c598813dba001b53beeae59bb77ad4892c5c1b9b3500ce4293a0d06c2" dependencies = [ "serde", ] [[package]] name = "once_cell" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" - -[[package]] -name = "opaque-debug" -version = "0.2.3" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "opaque-debug" @@ -1708,29 +1615,29 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.32" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", "cfg-if 1.0.0", "foreign-types", - "lazy_static", "libc", + "once_cell", "openssl-sys", ] [[package]] name = "openssl-probe" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" +checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-sys" -version = "0.9.60" +version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ "autocfg 1.0.1", "cc", @@ -1747,17 +1654,17 @@ checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" dependencies = [ "futures", "libc", - "log 0.4.11", + "log", "rand 0.7.3", - "tokio 1.13.0", + "tokio 1.15.0", "winapi 0.3.9", ] [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -1766,23 +1673,23 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.8", + "redox_syscall", "smallvec", "winapi 0.3.9", ] [[package]] name = "pem" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c220d01f863d13d96ca82359d1e81e64a7c6bf0637bcde7b2349630addf0c6" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" dependencies = [ "base64 0.13.0", "once_cell", @@ -1802,74 +1709,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] -name = "phf" -version = "0.7.24" +name = "picky" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +checksum = "fd6b25b296bb2a45678748f61c51f5a548ea56b25b0ad4966183709b386eaecf" dependencies = [ - "phf_shared", -] - -[[package]] -name = "phf_codegen" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" -dependencies = [ - "phf_shared", - "rand 0.6.5", -] - -[[package]] -name = "phf_shared" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" -dependencies = [ - "siphasher", - "unicase 1.4.2", -] - -[[package]] -name = "picky" -version = "6.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3c0575d4f2163ffd3e23992ed7f4fa304304c49fe2c22ce20b1b694437f0c4" -dependencies = [ - "aes-gcm", - "base64 0.12.3", - "digest", - "http 0.2.4", - "num-bigint-dig 0.6.1", - "oid", - "picky-asn1", - "picky-asn1-der", - "picky-asn1-x509", - "rand 0.7.3", - "rsa 0.3.0", - "serde", - "serde_json", - "sha-1", - "sha2", - "sha3", - "thiserror", + "aes-gcm", + "base64 0.13.0", + "digest", + "http 0.2.5", + "num-bigint-dig", + "oid", + "picky-asn1", + "picky-asn1-der", + "picky-asn1-x509", + "rand 0.8.4", + "rsa", + "serde", + "serde_json", + "sha-1", + "sha2", + "sha3", + "thiserror", ] [[package]] name = "picky-asn1" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e3f783e3e499bdb8e66d2a48c9da561fc369f96853eb83fb31e28931e4a492" +checksum = "889bbb26c80acf919e89980dfc8e04eb19df272d8a9893ec9b748d3a1675abde" dependencies = [ "oid", "serde", @@ -1878,9 +1746,9 @@ dependencies = [ [[package]] name = "picky-asn1-der" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233e556fc14cd42f38290ecd53f23a9fe047df2837d3d7494d27872b40a64bca" +checksum = "acbbd5390ab967396cc7473e6e0848684aec7166e657c6088604e07b54a73dbe" dependencies = [ "picky-asn1", "serde", @@ -1889,12 +1757,12 @@ dependencies = [ [[package]] name = "picky-asn1-x509" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c40870d0d056271c2976f7c1747b1df4332f979ab78634574ef5b534e6b0f0f" +checksum = "f3033675030de806aba1d5470949701b7c9f1dbf77e3bb17bd12e5f945e560ba" dependencies = [ - "base64 0.12.3", - "num-bigint-dig 0.6.1", + "base64 0.13.0", + "num-bigint-dig", "oid", "picky-asn1", "picky-asn1-der", @@ -1903,18 +1771,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" +checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" +checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" dependencies = [ "proc-macro2", "quote", @@ -1923,9 +1791,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" @@ -1941,32 +1809,33 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "polyval" -version = "0.4.5" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" dependencies = [ - "cpuid-bool 0.2.0", - "opaque-debug 0.3.0", + "cfg-if 1.0.0", + "cpufeatures", + "opaque-debug", "universal-hash", ] [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" [[package]] name = "predicates" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73dd9b7b200044694dfede9edf907c1ca19630908443e9447e624993700c6932" +checksum = "f49cfaf7fdaa3bfacc6fa3e7054e65148878354a5cfddcf661df4c851f8021df" dependencies = [ "difference", "float-cmp", @@ -1975,20 +1844,31 @@ dependencies = [ "regex", ] +[[package]] +name = "predicates" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e5a7689e456ab905c22c2b48225bb921aba7c8dfa58440d68ba13f6222a715" +dependencies = [ + "difflib", + "itertools", + "predicates-core", +] + [[package]] name = "predicates-core" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3dbeaaf793584e29c58c7e3a82bbb3c7c06b63cea68d13b0e3cddc124104dc" +checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" [[package]] name = "predicates-tree" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aee95d988ee893cb35c06b148c80ed2cd52c8eea927f50ba7a0be1a786aeab73" +checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7" dependencies = [ "predicates-core", - "treeline", + "termtree", ] [[package]] @@ -2001,7 +1881,7 @@ dependencies = [ "proc-macro2", "quote", "syn", - "version_check 0.9.2", + "version_check", ] [[package]] @@ -2012,26 +1892,14 @@ checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", - "version_check 0.9.2", + "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" - [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" dependencies = [ "unicode-xid", ] @@ -2053,9 +1921,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -2073,38 +1941,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "rand" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "winapi 0.3.9", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.7", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi 0.3.9", -] - [[package]] name = "rand" version = "0.7.3" @@ -2120,24 +1956,14 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.0", - "rand_core 0.6.2", - "rand_hc 0.3.0", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.3.1", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", ] [[package]] @@ -2152,12 +1978,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -2186,22 +2012,13 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom 0.2.3", ] -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -2213,64 +2030,11 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core 0.6.2", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.3.1", + "rand_core 0.6.3", ] [[package]] @@ -2293,40 +2057,23 @@ dependencies = [ "combine", "dtoa", "futures-util", - "itoa", + "itoa 0.4.8", "percent-encoding 2.1.0", "pin-project-lite 0.2.7", - "tokio 1.13.0", + "tokio 1.15.0", "tokio-util", - "url 2.2.0", + "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.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] -[[package]] -name = "redox_users" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" -dependencies = [ - "getrandom 0.1.16", - "redox_syscall 0.1.57", - "rust-argon2", -] - [[package]] name = "redox_users" version = "0.4.0" @@ -2334,26 +2081,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom 0.2.3", - "redox_syscall 0.2.8", + "redox_syscall", ] [[package]] name = "regex" -version = "1.4.2" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" -version = "0.6.21" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remove_dir_all" @@ -2366,33 +2118,34 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280" +checksum = "7c4e0a76dc12a116108933f6301b95e83634e0c47b0afbed6abbaa0601e99258" dependencies = [ "base64 0.13.0", "bytes 1.1.0", "encoding_rs", "futures-core", "futures-util", - "http 0.2.4", + "http 0.2.5", "http-body", "hyper", "hyper-tls", "ipnet", "js-sys", "lazy_static", - "log 0.4.11", - "mime 0.3.16", + "log", + "mime", "native-tls", "percent-encoding 2.1.0", "pin-project-lite 0.2.7", "serde", "serde_json", "serde_urlencoded", - "tokio 1.13.0", + "tokio 1.15.0", "tokio-native-tls", - "url 2.2.0", + "tokio-util", + "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2401,9 +2154,9 @@ dependencies = [ [[package]] name = "retry" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15ef4789108d066d7fd85dcec330eab9b8e51244275922a9b7161afc4f46dda" +checksum = "1d7cf7a37d3ec90193e5a553d7f5ce283665a29c5e7e3973ceb08568c902dc07" dependencies = [ "rand 0.7.3", ] @@ -2423,67 +2176,22 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "rouille" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112568052ec17fa26c6c11c40acbb30d3ad244bf3d6da0be181f5e7e42e5004f" -dependencies = [ - "base64 0.9.3", - "chrono", - "filetime", - "multipart", - "num_cpus", - "rand 0.5.6", - "serde", - "serde_derive", - "serde_json", - "sha1", - "term", - "threadpool", - "time", - "tiny_http", - "url 1.7.2", -] - [[package]] name = "rsa" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3648b669b10afeab18972c105e284a7b953a669b0be3514c27f9b17acab2f9cd" -dependencies = [ - "byteorder", - "digest", - "lazy_static", - "num-bigint-dig 0.6.1", - "num-integer", - "num-iter", - "num-traits", - "pem", - "rand 0.7.3", - "sha2", - "simple_asn1 0.4.1", - "subtle", - "thiserror", - "zeroize", -] - -[[package]] -name = "rsa" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ef841a26fc5d040ced0417c6c6a64ee851f42489df11cdf0218e545b6f8d28" +checksum = "7b0aeddcca1082112a6eeb43bf25fd7820b066aaf6eaef776e19d0a1febe38fe" dependencies = [ "byteorder", "digest", "lazy_static", - "num-bigint-dig 0.7.0", + "num-bigint-dig", "num-integer", "num-iter", "num-traits", "pem", - "rand 0.8.3", - "simple_asn1 0.5.2", + "rand 0.8.4", + "simple_asn1 0.5.4", "subtle", "zeroize", ] @@ -2499,17 +2207,17 @@ dependencies = [ "bytes 1.1.0", "crc32fast", "futures", - "http 0.2.4", + "http 0.2.5", "hyper", "hyper-tls", "lazy_static", - "log 0.4.11", + "log", "rusoto_credential", "rusoto_signature", "rustc_version", "serde", "serde_json", - "tokio 1.13.0", + "tokio 1.15.0", "xml-rs", ] @@ -2527,7 +2235,7 @@ dependencies = [ "serde", "serde_json", "shlex", - "tokio 1.13.0", + "tokio 1.15.0", "zeroize", ] @@ -2557,9 +2265,9 @@ dependencies = [ "futures", "hex", "hmac 0.11.0", - "http 0.2.4", + "http 0.2.5", "hyper", - "log 0.4.11", + "log", "md-5", "percent-encoding 2.1.0", "pin-project-lite 0.2.7", @@ -2567,41 +2275,42 @@ dependencies = [ "rustc_version", "serde", "sha2", - "tokio 1.13.0", + "tokio 1.15.0", ] [[package]] -name = "rust-argon2" -version = "0.8.3" +name = "rustc_version" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "base64 0.13.0", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", + "semver 1.0.4", ] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rustls" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ - "semver 1.0.4", + "base64 0.13.0", + "log", + "ring", + "sct", + "webpki", ] [[package]] name = "rustversion" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "safemem" @@ -2628,17 +2337,33 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" -version = "2.0.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" dependencies = [ "bitflags", "core-foundation", @@ -2649,9 +2374,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.0.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" dependencies = [ "core-foundation-sys", "libc", @@ -2680,9 +2405,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.118" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" dependencies = [ "serde_derive", ] @@ -2698,9 +2423,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.118" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", @@ -2709,12 +2434,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.61" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ "indexmap", - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -2737,7 +2462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" dependencies = [ "form_urlencoded", - "itoa", + "itoa 0.4.8", "ryu", "serde", ] @@ -2766,34 +2491,28 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer", "cfg-if 1.0.0", - "cpuid-bool 0.1.2", + "cpufeatures", "digest", - "opaque-debug 0.3.0", + "opaque-debug", ] -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - [[package]] name = "sha2" -version = "0.9.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer", "cfg-if 1.0.0", - "cpuid-bool 0.1.2", + "cpufeatures", "digest", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -2805,7 +2524,7 @@ dependencies = [ "block-buffer", "digest", "keccak", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -2816,9 +2535,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signal-hook-registry" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] @@ -2836,22 +2555,16 @@ dependencies = [ [[package]] name = "simple_asn1" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0e9076e5242ff5a58e854cb478ea9caebce01088f86d3d9c6ad336b7655263" +checksum = "8eb4ea60fb301dc81dfc113df680571045d375ab7345d171c5dc7d7e13107a80" dependencies = [ "chrono", - "num-bigint 0.4.0", + "num-bigint 0.4.3", "num-traits", "thiserror", ] -[[package]] -name = "siphasher" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" - [[package]] name = "skeptic" version = "0.4.0" @@ -2864,26 +2577,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" - -[[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", -] +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "socket2" @@ -2921,9 +2623,9 @@ dependencies = [ [[package]] name = "strip-ansi-escapes" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d63676e2abafa709460982ddc02a3bb586b6d15a49b75c212e06edd3933acee" +checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8" dependencies = [ "vte", ] @@ -2982,15 +2684,15 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.58" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -2999,9 +2701,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.12.4" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", @@ -3017,19 +2719,18 @@ checksum = "9a5d8ef1b679c07976f3ee336a436453760c470f54b5e7237556728b8589515d" dependencies = [ "error-chain", "libc", - "log 0.4.11", + "log", "time", ] [[package]] name = "tar" -version = "0.4.30" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489997b7557e9a43e192c527face4feacc78bfbe6eed67fd55c4c9e381cba290" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" dependencies = [ "filetime", "libc", - "redox_syscall 0.1.57", "xattr", ] @@ -3045,29 +2746,18 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", - "rand 0.7.3", - "redox_syscall 0.1.57", + "rand 0.8.4", + "redox_syscall", "remove_dir_all", "winapi 0.3.9", ] -[[package]] -name = "term" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" -dependencies = [ - "byteorder", - "dirs", - "winapi 0.3.9", -] - [[package]] name = "termcolor" version = "1.1.2" @@ -3077,6 +2767,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "termtree" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" + [[package]] name = "textwrap" version = "0.11.0" @@ -3097,14 +2793,14 @@ dependencies = [ "chrono", "displaydoc", "futures", - "log 0.4.11", + "log", "reqwest", "serde", "serde_json", "serde_repr", "stringmatch", "thiserror", - "tokio 1.13.0", + "tokio 1.15.0", "urlparse", ] @@ -3115,7 +2811,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3f5d2d34330c292d7deb0470bee091ea0c5c935f0ce66c528756251b5bbd65" dependencies = [ "base64 0.13.0", - "log 0.4.11", + "log", "reqwest", "serde", "serde_json", @@ -3143,54 +2839,21 @@ dependencies = [ "syn", ] -[[package]] -name = "thread_local" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447" -dependencies = [ - "lazy_static", -] - -[[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" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "wasi 0.10.0+wasi-snapshot-preview1", "winapi 0.3.9", ] -[[package]] -name = "tiny_http" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1661fa0a44c95d01604bd05c66732a446c657efb62b5164a7a083a3b552b4951" -dependencies = [ - "ascii", - "chrono", - "chunked_transfer", - "log 0.4.11", - "openssl", - "url 1.7.2", -] - [[package]] name = "tinyvec" -version = "1.1.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -3203,22 +2866,21 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" dependencies = [ "bytes 0.5.6", - "pin-project-lite 0.1.11", + "pin-project-lite 0.1.12", "slab", ] [[package]] name = "tokio" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "588b2d10a336da58d877567cd8fb8a14b463e2104910f8132cd054b4b96e29ee" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "autocfg 1.0.1", "bytes 1.1.0", "libc", "memchr", @@ -3233,9 +2895,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.5.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114383b041aa6212c579467afa0075fbbdd0718de036100bc0ba7961d8cb9095" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", @@ -3249,7 +2911,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", - "tokio 1.13.0", + "tokio 1.15.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio 1.15.0", + "webpki", ] [[package]] @@ -3264,6 +2937,30 @@ dependencies = [ "pin-project", ] +[[package]] +name = "tokio-stream" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" +dependencies = [ + "futures-core", + "pin-project-lite 0.2.7", + "tokio 1.15.0", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" +dependencies = [ + "futures-util", + "log", + "pin-project", + "tokio 1.15.0", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.6.9" @@ -3273,9 +2970,9 @@ dependencies = [ "bytes 1.1.0", "futures-core", "futures-sink", - "log 0.4.11", + "log", "pin-project-lite 0.2.7", - "tokio 1.13.0", + "tokio 1.15.0", ] [[package]] @@ -3289,9 +2986,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00e500fff5fa1131c866b246041a6bf96da9c965f8fe4128cb1421f23e93c00" +checksum = "5651b5f6860a99bd1adb59dbfe1db8beb433e73709d9032b413a77e2fb7c066a" dependencies = [ "futures-core", "pin-project", @@ -3315,12 +3012,12 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.22" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if 1.0.0", - "log 0.4.11", + "log", "pin-project-lite 0.2.7", "tracing-attributes", "tracing-core", @@ -3328,9 +3025,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.11" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" dependencies = [ "proc-macro2", "quote", @@ -3339,25 +3036,38 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.17" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" dependencies = [ "lazy_static", ] -[[package]] -name = "treeline" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" - [[package]] name = "try-lock" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "tungstenite" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" +dependencies = [ + "base64 0.13.0", + "byteorder", + "bytes 1.1.0", + "http 0.2.5", + "httparse", + "log", + "rand 0.8.4", + "sha-1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "twoway" version = "0.1.8" @@ -3369,18 +3079,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" - -[[package]] -name = "unicase" -version = "1.4.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -dependencies = [ - "version_check 0.1.5", -] +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "unicase" @@ -3388,23 +3089,20 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.9.2", + "version_check", ] [[package]] name = "unicode-bidi" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -dependencies = [ - "matches", -] +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] @@ -3417,21 +3115,21 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "universal-hash" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ "generic-array", "subtle", @@ -3455,23 +3153,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "1.7.2" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - -[[package]] -name = "url" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", - "idna 0.2.0", + "idna", "matches", "percent-encoding 2.1.0", ] @@ -3482,26 +3169,32 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "110352d4e9076c67839003c7788d8604e24dcded13e0b375af3efaa8cf468517" +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" +checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" [[package]] name = "uuid" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "rand 0.7.3", + "getrandom 0.2.3", ] [[package]] name = "vcpkg" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" @@ -3517,15 +3210,9 @@ checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" [[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.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "void" @@ -3535,11 +3222,23 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "vte" -version = "0.3.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f42f536e22f7fcbb407639765c8fd78707a33109301f834a594758bedd6e8cf" +checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" dependencies = [ + "arrayvec 0.5.2", "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte_generate_state_changes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +dependencies = [ + "proc-macro2", + "quote", ] [[package]] @@ -3553,9 +3252,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi 0.3.9", @@ -3568,10 +3267,41 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.11", + "log", "try-lock", ] +[[package]] +name = "warp" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e" +dependencies = [ + "bytes 1.1.0", + "futures-channel", + "futures-util", + "headers", + "http 0.2.5", + "hyper", + "log", + "mime", + "mime_guess", + "multipart", + "percent-encoding 2.1.0", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio 1.15.0", + "tokio-rustls", + "tokio-stream", + "tokio-tungstenite", + "tokio-util", + "tower-service", + "tracing", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -3580,15 +3310,15 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.69" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3596,13 +3326,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.69" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", - "log 0.4.11", + "log", "proc-macro2", "quote", "syn", @@ -3611,9 +3341,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.19" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe9756085a84584ee9457a002b7cdfe0bfff169f45d2591d8be1345a6780e35" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3623,9 +3353,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.69" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3633,9 +3363,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.69" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", @@ -3646,28 +3376,39 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.69" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "web-sys" -version = "0.3.46" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "which" -version = "4.0.2" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef" +checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9" dependencies = [ + "either", + "lazy_static", "libc", - "thiserror", ] [[package]] @@ -3748,9 +3489,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.1.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" +checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73" dependencies = [ "proc-macro2", "quote", @@ -3760,9 +3501,9 @@ dependencies = [ [[package]] name = "zip" -version = "0.5.9" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2896475a242c41366941faa27264df2cb935185a92e059a004d0048feb2ac5" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" dependencies = [ "byteorder", "crc32fast", @@ -3771,18 +3512,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.6.0+zstd.1.4.8" +version = "0.6.1+zstd.1.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e44664feba7f2f1a9f300c1f6157f2d1bfc3c15c6f3cf4beabf3f5abe9c237" +checksum = "5de55e77f798f205d8561b8fe2ef57abfb6e0ff2abe7fd3c089e119cdb5631a3" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "3.0.0+zstd.1.4.8" +version = "3.0.1+zstd.1.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9447afcd795693ad59918c7bbffe42fdd6e467d708f3537e3dc14dc598c573f" +checksum = "1387cabcd938127b30ce78c4bf00b30387dddf704e3f0881dbc4ff62b5566f8c" dependencies = [ "libc", "zstd-sys", @@ -3790,12 +3531,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "1.4.19+zstd.1.4.8" +version = "1.4.20+zstd.1.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec24a9273d24437afb8e71b16f3d9a5d569193cccdb7896213b59f552f387674" +checksum = "ebd5b733d7cf2d9447e2c3e76a5589b4f5e5ae065c22a2bc0b023cbc331b6c8e" dependencies = [ "cc", - "glob", - "itertools 0.9.0", "libc", ] diff --git a/Cargo.toml b/Cargo.toml index dceec8a4..7005eb7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ percent-encoding = { version = "2", optional = true } rand = "0.8" redis = { version = "0.21", optional = true, default-features = false, features = ["aio", "tokio-comp"] } regex = "1" -reqwest = { version = "0.11", features = ["json", "blocking"], optional = true } +reqwest = { version = "0.11.7", features = ["json", "native-tls"], optional = true } retry = "1" ring = { version = "0.16", optional = true, features = ["std"] } rusoto_core = { version = "0.47", optional = true } @@ -95,15 +95,17 @@ zip = { version = "0.5", default-features = false } zstd = "0.6" structopt = "0.3.25" strum = { version = "0.23.0", features = ["derive"] } +native-tls = "0.2.8" # dist-server only crossbeam-utils = { version = "0.8", optional = true } libmount = { version = "0.1.10", optional = true } nix = { version = "0.19", optional = true } -rouille = { version = "3", optional = true, default-features = false, features = ["ssl"] } syslog = { version = "5", optional = true } void = { version = "1", optional = true } version-compare = { version = "0.0.11", optional = true } +warp = { version = "0.3.2", optional = true, features = ["tls"] } +thiserror = { version = "1.0.30", optional = true } # test only openssl = { version = "0.10", optional = true } @@ -145,7 +147,7 @@ unstable = [] # Enables distributed support in the cachepot client dist-client = ["ar", "flate2", "hyper", "hyperx", "reqwest/stream", "url", "sha2", "tokio/fs"] # Enables the cachepot-dist binary -dist-server = ["chrono", "crossbeam-utils", "jsonwebtoken", "flate2", "hyperx", "libmount", "nix", "reqwest", "rouille", "sha2", "syslog", "void", "version-compare"] +dist-server = ["chrono", "crossbeam-utils", "jsonwebtoken", "flate2", "hyperx", "libmount", "nix", "reqwest", "sha2", "syslog", "void", "version-compare", "warp", "thiserror"] # Enables dist tests with external requirements dist-tests = ["dist-client", "dist-server"] # Run JWK token crypto against openssl ref impl diff --git a/src/bin/cachepot-dist/build.rs b/src/bin/cachepot-dist/build.rs index 3ff221b8..f6322fcd 100644 --- a/src/bin/cachepot-dist/build.rs +++ b/src/bin/cachepot-dist/build.rs @@ -484,7 +484,7 @@ fn docker_diff(cid: &str) -> Result { // Force remove the container fn docker_rm(cid: &str) -> Result<()> { Command::new("docker") - .args(&["rm", "-f", &cid]) + .args(&["rm", "-f", cid]) .check_run() .context("Failed to force delete container") } @@ -611,11 +611,11 @@ impl DockerBuilder { fn clean_container(&self, cid: &str) -> Result<()> { // Clean up any running processes Command::new("docker") - .args(&["exec", &cid, "/busybox", "kill", "-9", "-1"]) + .args(&["exec", cid, "/busybox", "kill", "-9", "-1"]) .check_run() .context("Failed to run kill on all processes in container")?; - let diff = docker_diff(&cid)?; + let diff = docker_diff(cid)?; if !diff.is_empty() { let mut lastpath = None; for line in diff.split(|c| c == '\n') { @@ -650,7 +650,7 @@ impl DockerBuilder { } lastpath = Some(changepath); if let Err(e) = Command::new("docker") - .args(&["exec", &cid, "/busybox", "rm", "-rf", changepath]) + .args(&["exec", cid, "/busybox", "rm", "-rf", changepath]) .check_run() { // We do a final check anyway, so just continue @@ -658,7 +658,7 @@ impl DockerBuilder { } } - let newdiff = docker_diff(&cid)?; + let newdiff = docker_diff(cid)?; // See note about changepath == "/tmp" above if !newdiff.is_empty() && newdiff != "C /tmp" { bail!( @@ -821,7 +821,7 @@ impl DockerBuilder { cmd.arg("-e").arg(env); } let shell_cmd = "cd \"$1\" && shift && exec \"$@\""; - cmd.args(&[cid, "/busybox", "sh", "-c", &shell_cmd]); + cmd.args(&[cid, "/busybox", "sh", "-c", shell_cmd]); cmd.arg(&executable); cmd.arg(cwd); cmd.arg(executable); diff --git a/src/bin/cachepot-dist/main.rs b/src/bin/cachepot-dist/main.rs index 6d3d938a..affc749e 100644 --- a/src/bin/cachepot-dist/main.rs +++ b/src/bin/cachepot-dist/main.rs @@ -6,6 +6,7 @@ extern crate log; extern crate serde_derive; use anyhow::{bail, Context, Error, Result}; +use async_trait::async_trait; use cachepot::config::{ scheduler as scheduler_config, server as server_config, INSECURE_DIST_CLIENT_TOKEN, }; @@ -27,7 +28,7 @@ use std::path::Path; use std::path::PathBuf; use std::str::FromStr; use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::{Mutex, MutexGuard}; +use std::sync::{Arc, Mutex, MutexGuard}; use std::time::{Duration, Instant}; use structopt::StructOpt; use syslog::Facility; @@ -93,6 +94,7 @@ struct GenerateJwtHS256ServerToken { } #[derive(StructOpt)] +#[allow(clippy::enum_variant_names)] enum AuthSubcommand { GenerateSharedToken(GenerateSharedToken), GenerateJwtHS256Key, @@ -101,11 +103,12 @@ enum AuthSubcommand { // Only supported on x86_64 Linux machines #[cfg(all(target_os = "linux", target_arch = "x86_64"))] -fn main() { +#[tokio::main] +async fn main() { init_logging(); std::process::exit({ let cmd = Command::from_args(); - match run(cmd) { + match run(cmd).await { Ok(s) => s, Err(e) => { eprintln!("cachepot-dist: error: {}", e); @@ -152,10 +155,10 @@ fn create_jwt_server_token( key: &[u8], ) -> Result { let key = jwt::EncodingKey::from_secret(key); - jwt::encode(&header, &ServerJwt { server_id }, &key).map_err(Into::into) + jwt::encode(header, &ServerJwt { server_id }, &key).map_err(Into::into) } fn dangerous_insecure_extract_jwt_server_token(server_token: &str) -> Option { - jwt::dangerous_insecure_decode::(&server_token) + jwt::dangerous_insecure_decode::(server_token) .map(|res| res.claims.server_id) .ok() } @@ -170,7 +173,7 @@ fn check_jwt_server_token( .ok() } -fn run(command: Command) -> Result { +async fn run(command: Command) -> Result { match command { Command::Auth(AuthSubcommand::GenerateJwtHS256Key) => { let num_bytes = 256 / 8; @@ -203,9 +206,7 @@ fn run(command: Command) -> Result { bail!("Could not read config"); } } else { - secret_key - .expect("missing secret-key in parsed subcommand") - .to_owned() + secret_key.expect("missing secret-key in parsed subcommand") }; let secret_key = base64::decode_config(&secret_key, base64::URL_SAFE_NO_PAD)?; @@ -251,6 +252,7 @@ fn run(command: Command) -> Result { jwks_url, } => Box::new( token_check::ValidJWTCheck::new(audience, issuer, &jwks_url) + .await .context("Failed to create a checker for valid JWTs")?, ), scheduler_config::ClientAuth::Mozilla { required_groups } => { @@ -265,10 +267,10 @@ fn run(command: Command) -> Result { scheduler_config::ServerAuth::Insecure => { warn!("Scheduler starting with DANGEROUSLY_INSECURE server authentication"); let token = INSECURE_DIST_SERVER_TOKEN; - Box::new(move |server_token| check_server_token(server_token, &token)) + Arc::new(move |server_token| check_server_token(server_token, token)) } scheduler_config::ServerAuth::Token { token } => { - Box::new(move |server_token| check_server_token(server_token, &token)) + Arc::new(move |server_token| check_server_token(server_token, &token)) } scheduler_config::ServerAuth::JwtHS256 { secret_key } => { let secret_key = base64::decode_config(&secret_key, base64::URL_SAFE_NO_PAD) @@ -285,7 +287,7 @@ fn run(command: Command) -> Result { sub: None, algorithms: vec![jwt::Algorithm::HS256], }; - Box::new(move |server_token| { + Arc::new(move |server_token| { check_jwt_server_token(server_token, &secret_key, &validation) }) } @@ -299,7 +301,7 @@ fn run(command: Command) -> Result { check_client_auth, check_server_auth, ); - void::unreachable(http_scheduler.start()?); + void::unreachable(http_scheduler.start().await?); } Command::Server(ServerSubcommand { config, syslog }) => { @@ -337,7 +339,7 @@ fn run(command: Command) -> Result { let scheduler_auth = match scheduler_auth { server_config::SchedulerAuth::Insecure => { warn!("Server starting with DANGEROUSLY_INSECURE scheduler authentication"); - create_server_token(server_id, &INSECURE_DIST_SERVER_TOKEN) + create_server_token(server_id, INSECURE_DIST_SERVER_TOKEN) } server_config::SchedulerAuth::Token { token } => { create_server_token(server_id, &token) @@ -366,7 +368,7 @@ fn run(command: Command) -> Result { server, ) .context("Failed to create cachepot HTTP server instance")?; - void::unreachable(http_server.start()?) + void::unreachable(http_server.start().await?) } } } @@ -464,8 +466,9 @@ impl Scheduler { } } +#[async_trait] impl SchedulerIncoming for Scheduler { - fn handle_alloc_job( + async fn handle_alloc_job( &self, requester: &dyn SchedulerOutgoing, tc: Toolchain, @@ -564,6 +567,7 @@ impl SchedulerIncoming for Scheduler { need_toolchain, } = requester .do_assign_job(server_id, job_id, tc, auth.clone()) + .await .with_context(|| { // LOCKS let mut servers = self.servers.lock().unwrap(); @@ -684,7 +688,7 @@ impl SchedulerIncoming for Scheduler { } Some(ref mut details) if details.server_nonce != server_nonce => { for job_id in details.jobs_assigned.iter() { - if jobs.remove(&job_id).is_none() { + if jobs.remove(job_id).is_none() { warn!( "Unknown job found when replacing server {}: {}", server_id.addr(), @@ -782,7 +786,7 @@ impl SchedulerIncoming for Scheduler { pub struct Server { builder: Box, cache: Mutex, - job_toolchains: Mutex>, + job_toolchains: tokio::sync::Mutex>, } impl Server { @@ -796,18 +800,19 @@ impl Server { Ok(Server { builder, cache: Mutex::new(cache), - job_toolchains: Mutex::new(HashMap::new()), + job_toolchains: tokio::sync::Mutex::new(HashMap::new()), }) } } +#[async_trait] impl ServerIncoming for Server { - fn handle_assign_job(&self, job_id: JobId, tc: Toolchain) -> Result { + async fn handle_assign_job(&self, job_id: JobId, tc: Toolchain) -> Result { let need_toolchain = !self.cache.lock().unwrap().contains_toolchain(&tc); assert!(self .job_toolchains .lock() - .unwrap() + .await .insert(job_id, tc) .is_none()); let state = if need_toolchain { @@ -821,18 +826,19 @@ impl ServerIncoming for Server { need_toolchain, }) } - fn handle_submit_toolchain( + async fn handle_submit_toolchain( &self, requester: &dyn ServerOutgoing, job_id: JobId, - tc_rdr: ToolchainReader, + tc_rdr: ToolchainReader<'_>, ) -> Result { requester .do_update_job_state(job_id, JobState::Ready) + .await .context("Updating job state failed")?; // TODO: need to lock the toolchain until the container has started // TODO: can start prepping container - let tc = match self.job_toolchains.lock().unwrap().get(&job_id).cloned() { + let tc = match self.job_toolchains.lock().await.get(&job_id).cloned() { Some(tc) => tc, None => return Ok(SubmitToolchainResult::JobNotFound), }; @@ -848,18 +854,19 @@ impl ServerIncoming for Server { .map(|_| SubmitToolchainResult::Success) .unwrap_or(SubmitToolchainResult::CannotCache)) } - fn handle_run_job( + async fn handle_run_job( &self, requester: &dyn ServerOutgoing, job_id: JobId, command: CompileCommand, outputs: Vec, - inputs_rdr: InputsReader, + inputs_rdr: InputsReader<'_>, ) -> Result { requester .do_update_job_state(job_id, JobState::Started) + .await .context("Updating job state failed")?; - let tc = self.job_toolchains.lock().unwrap().remove(&job_id); + let tc = self.job_toolchains.lock().await.remove(&job_id); let res = match tc { None => Ok(RunJobResult::JobNotFound), Some(tc) => { @@ -877,6 +884,7 @@ impl ServerIncoming for Server { }; requester .do_update_job_state(job_id, JobState::Complete) + .await .context("Updating job state failed")?; res } diff --git a/src/bin/cachepot-dist/token_check.rs b/src/bin/cachepot-dist/token_check.rs index 672bc7f2..9d148462 100644 --- a/src/bin/cachepot-dist/token_check.rs +++ b/src/bin/cachepot-dist/token_check.rs @@ -1,5 +1,6 @@ use crate::jwt; use anyhow::{bail, Context, Result}; +use async_trait::async_trait; use cachepot::dist::http::{ClientAuthCheck, ClientVisibleMsg}; use cachepot::util::RequestExt; use std::collections::HashMap; @@ -51,8 +52,9 @@ pub struct EqCheck { s: String, } +#[async_trait] impl ClientAuthCheck for EqCheck { - fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { + async fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { if self.s == token { Ok(()) } else { @@ -76,14 +78,15 @@ const MOZ_USERINFO_ENDPOINT: &str = "https://auth.mozilla.auth0.com/userinfo"; // Mozilla-specific check by forwarding the token onto the auth0 userinfo endpoint pub struct MozillaCheck { - auth_cache: Mutex>, // token, token_expiry - client: reqwest::blocking::Client, + auth_cache: tokio::sync::Mutex>, // token, token_expiry + client: reqwest::Client, required_groups: Vec, } +#[async_trait] impl ClientAuthCheck for MozillaCheck { - fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { - self.check_mozilla(token).map_err(|e| { + async fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { + self.check_mozilla(token).await.map_err(|e| { warn!("Mozilla token validation failed: {}", e); ClientVisibleMsg::from_nonsensitive( "Failed to validate Mozilla OAuth token, run cachepot --dist-auth".to_owned(), @@ -95,13 +98,13 @@ impl ClientAuthCheck for MozillaCheck { impl MozillaCheck { pub fn new(required_groups: Vec) -> Self { Self { - auth_cache: Mutex::new(HashMap::new()), - client: reqwest::blocking::Client::new(), + auth_cache: tokio::sync::Mutex::new(HashMap::new()), + client: reqwest::Client::new(), required_groups, } } - fn check_mozilla(&self, token: &str) -> Result<()> { + async fn check_mozilla(&self, token: &str) -> Result<()> { // azp == client_id // { // "iss": "https://auth.mozilla.auth0.com/", @@ -129,7 +132,7 @@ impl MozillaCheck { bail!("JWT expired") } // If the token is cached and not expired, return it - let mut auth_cache = self.auth_cache.lock().unwrap(); + let mut auth_cache = self.auth_cache.lock().await; if let Some(cached_at) = auth_cache.get(token) { if cached_at.elapsed() < MOZ_SESSION_TIMEOUT { return Ok(()); @@ -150,10 +153,12 @@ impl MozillaCheck { .get(url.clone()) .set_header(header) .send() + .await .context("Failed to make request to mozilla userinfo")?; let status = res.status(); let res_text = res .text() + .await .context("Failed to interpret response from mozilla userinfo as string")?; if !status.is_success() { bail!("JWT forwarded to {} returned {}: {}", url, status, res_text) @@ -237,14 +242,15 @@ fn test_auth_verify_check_mozilla_profile() { // Don't check a token is valid (it may not even be a JWT) just forward it to // an API and check for success pub struct ProxyTokenCheck { - client: reqwest::blocking::Client, + client: reqwest::Client, maybe_auth_cache: Option, Duration)>>, url: String, } +#[async_trait] impl ClientAuthCheck for ProxyTokenCheck { - fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { - match self.check_token_with_forwarding(token) { + async fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { + match self.check_token_with_forwarding(token).await { Ok(()) => Ok(()), Err(e) => { warn!("Proxying token validation failed: {}", e); @@ -261,13 +267,13 @@ impl ProxyTokenCheck { let maybe_auth_cache: Option, Duration)>> = cache_secs.map(|secs| Mutex::new((HashMap::new(), Duration::from_secs(secs)))); Self { - client: reqwest::blocking::Client::new(), + client: reqwest::Client::new(), maybe_auth_cache, url, } } - fn check_token_with_forwarding(&self, token: &str) -> Result<()> { + async fn check_token_with_forwarding(&self, token: &str) -> Result<()> { trace!("Validating token by forwarding to {}", self.url); // If the token is cached and not cache has not expired, return it if let Some(ref auth_cache) = self.maybe_auth_cache { @@ -289,6 +295,7 @@ impl ProxyTokenCheck { .get(&self.url) .set_header(header) .send() + .await .context("Failed to make request to proxying url")?; if !res.status().is_success() { bail!("Token forwarded to {} returned {}", self.url, res.status()); @@ -310,8 +317,9 @@ pub struct ValidJWTCheck { kid_to_pkcs1: HashMap>, } +#[async_trait] impl ClientAuthCheck for ValidJWTCheck { - fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { + async fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg> { match self.check_jwt_validity(token) { Ok(()) => Ok(()), Err(e) => { @@ -325,12 +333,14 @@ impl ClientAuthCheck for ValidJWTCheck { } impl ValidJWTCheck { - pub fn new(audience: String, issuer: String, jwks_url: &str) -> Result { - let res = reqwest::blocking::get(jwks_url).context("Failed to make request to JWKs url")?; + pub async fn new(audience: String, issuer: String, jwks_url: &str) -> Result { + let res = reqwest::get(jwks_url) + .await + .context("Failed to make request to JWKs url")?; if !res.status().is_success() { bail!("Could not retrieve JWKs, HTTP error: {}", res.status()) } - let jwks: Jwks = res.json().context("Failed to parse JWKs json")?; + let jwks: Jwks = res.json().await.context("Failed to parse JWKs json")?; let kid_to_pkcs1 = jwks .keys .into_iter() diff --git a/src/compiler/args.rs b/src/compiler/args.rs index 41b8685a..e20e4238 100644 --- a/src/compiler/args.rs +++ b/src/compiler/args.rs @@ -300,6 +300,7 @@ macro_rules! ArgData { // PartialEq necessary for tests { pub $( $tok:tt )+ } => { #[derive(Clone, Debug, PartialEq)] + #[allow(clippy::enum_variant_names)] pub enum ArgData { $($tok)+ } @@ -307,6 +308,7 @@ macro_rules! ArgData { }; { $( $tok:tt )+ } => { #[derive(Clone, Debug, PartialEq)] + #[allow(clippy::enum_variant_names)] enum ArgData { $($tok)+ } diff --git a/src/config.rs b/src/config.rs index 6ce44993..34699a98 100644 --- a/src/config.rs +++ b/src/config.rs @@ -744,7 +744,7 @@ pub mod scheduler { } pub fn from_path(conf_path: &Path) -> Result> { - super::try_read_config_file(&conf_path).context("Failed to load scheduler config file") + super::try_read_config_file(conf_path).context("Failed to load scheduler config file") } } @@ -799,7 +799,7 @@ pub mod server { } pub fn from_path(conf_path: &Path) -> Result> { - super::try_read_config_file(&conf_path).context("Failed to load server config file") + super::try_read_config_file(conf_path).context("Failed to load server config file") } } diff --git a/src/dist/client_auth.rs b/src/dist/client_auth.rs index 8c2a0d97..f0302ac2 100644 --- a/src/dist/client_auth.rs +++ b/src/dist/client_auth.rs @@ -228,7 +228,7 @@ mod code_grant_pkce { Ok(response) } - pub fn code_to_token( + pub async fn code_to_token( token_url: &str, client_id: &str, code_verifier: &str, @@ -242,8 +242,8 @@ mod code_grant_pkce { grant_type: GRANT_TYPE_PARAM_VALUE, redirect_uri, }; - let client = reqwest::blocking::Client::new(); - let res = client.post(token_url).json(&token_request).send()?; + let client = reqwest::Client::new(); + let res = client.post(token_url).json(&token_request).send().await?; if !res.status().is_success() { bail!( "Sending code to {} failed, HTTP error: {}", @@ -254,6 +254,7 @@ mod code_grant_pkce { let (token, expires_at) = handle_token_response( res.json() + .await .context("Failed to parse token response as JSON")?, )?; if expires_at - Instant::now() < MIN_TOKEN_VALIDITY { @@ -551,8 +552,12 @@ pub fn get_token_oauth2_code_grant_pkce( let code = code_rx .try_recv() .expect("Hyper shutdown but code not available - internal error"); - code_grant_pkce::code_to_token(token_url, client_id, &verifier, &code, &redirect_uri) - .context("Failed to convert oauth2 code into a token") + + runtime.block_on(async move { + code_grant_pkce::code_to_token(token_url, client_id, &verifier, &code, &redirect_uri) + .await + .context("Failed to convert oauth2 code into a token") + }) } // https://auth0.com/docs/api-auth/tutorials/implicit-grant diff --git a/src/dist/http.rs b/src/dist/http.rs index cabb52df..cbf25e4f 100644 --- a/src/dist/http.rs +++ b/src/dist/http.rs @@ -38,21 +38,6 @@ mod common { fn bytes(self, bytes: Vec) -> Self; fn bearer_auth(self, token: String) -> Self; } - impl ReqwestRequestBuilderExt for reqwest::blocking::RequestBuilder { - fn bincode(self, bincode: &T) -> Result { - let bytes = - bincode::serialize(bincode).context("Failed to serialize body to bincode")?; - Ok(self.bytes(bytes)) - } - fn bytes(self, bytes: Vec) -> Self { - self.set_header(header::ContentType::octet_stream()) - .set_header(header::ContentLength(bytes.len() as u64)) - .body(bytes) - } - fn bearer_auth(self, token: String) -> Self { - self.set_header(header::Authorization(header::Bearer { token })) - } - } impl ReqwestRequestBuilderExt for reqwest::RequestBuilder { fn bincode(self, bincode: &T) -> Result { let bytes = @@ -69,35 +54,11 @@ mod common { } } - #[cfg(feature = "dist-server")] - pub fn bincode_req( - req: reqwest::blocking::RequestBuilder, - ) -> Result { - // Work around tiny_http issue #151 by disabling HTTP pipeline with - // `Connection: close`. - let mut res = req.set_header(header::Connection::close()).send()?; - let status = res.status(); - let mut body = vec![]; - res.copy_to(&mut body) - .context("error reading response body")?; - if !status.is_success() { - Err(anyhow!( - "Error {} (Headers={:?}): {}", - status.as_u16(), - res.headers(), - String::from_utf8_lossy(&body) - )) - } else { - bincode::deserialize(&body).map_err(Into::into) - } - } - #[cfg(feature = "dist-client")] - pub async fn bincode_req_fut( + #[cfg(any(feature = "dist-client", feature = "dist-server"))] + pub async fn bincode_req( req: reqwest::RequestBuilder, ) -> Result { - // Work around tiny_http issue #151 by disabling HTTP pipeline with - // `Connection: close`. - let res = req.set_header(header::Connection::close()).send().await?; + let res = req.send().await?; let status = res.status(); let bytes = res.bytes().await?; @@ -267,16 +228,10 @@ pub mod urls { #[cfg(feature = "dist-server")] mod server { use crate::jwt; - use byteorder::{BigEndian, ReadBytesExt}; - use flate2::read::ZlibDecoder as ZlibReadDecoder; use rand::{rngs::OsRng, RngCore}; - use rouille::accept; use std::collections::HashMap; - use std::io::Read; use std::result::Result as StdResult; - use std::sync::atomic; - use std::sync::Mutex; - use std::thread; + use std::sync::Arc; use std::time::Duration; use void::Void; @@ -286,9 +241,8 @@ mod server { }; use super::urls; use crate::dist::{ - self, AllocJobResult, AssignJobResult, HeartbeatServerResult, InputsReader, JobAuthorizer, - JobId, JobState, RunJobResult, SchedulerStatusResult, ServerId, ServerNonce, - SubmitToolchainResult, Toolchain, ToolchainReader, UpdateJobStateResult, + self, AssignJobResult, HeartbeatServerResult, JobId, JobState, ServerId, ServerNonce, + Toolchain, UpdateJobStateResult, }; use crate::errors::*; @@ -307,6 +261,7 @@ mod server { use picky::{hash::HashAlgorithm, signature::SignatureAlgorithm}; use sha2::Digest; use std::net::{IpAddr, SocketAddr}; + use tokio::sync::Mutex; pub(crate) fn create_https_cert_and_privkey( addr: SocketAddr, @@ -390,10 +345,11 @@ mod server { } } + #[async_trait] pub trait ClientAuthCheck: Send + Sync { - fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg>; + async fn check(&self, token: &str) -> StdResult<(), ClientVisibleMsg>; } - pub type ServerAuthCheck = Box Option + Send + Sync>; + pub type ServerAuthCheck = Arc Option + Send + Sync>; const JWT_KEY_LENGTH: usize = 256 / 8; lazy_static! { @@ -409,65 +365,6 @@ mod server { }; } - // Based on rouille::input::json::json_input - #[derive(Debug)] - pub enum RouilleBincodeError { - BodyAlreadyExtracted, - WrongContentType, - ParseError(bincode::Error), - } - impl From for RouilleBincodeError { - fn from(err: bincode::Error) -> RouilleBincodeError { - RouilleBincodeError::ParseError(err) - } - } - impl std::error::Error for RouilleBincodeError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match *self { - RouilleBincodeError::ParseError(ref e) => Some(e), - _ => None, - } - } - } - impl std::fmt::Display for RouilleBincodeError { - fn fmt( - &self, - fmt: &mut std::fmt::Formatter<'_>, - ) -> std::result::Result<(), std::fmt::Error> { - write!( - fmt, - "{}", - match *self { - RouilleBincodeError::BodyAlreadyExtracted => { - "the body of the request was already extracted" - } - RouilleBincodeError::WrongContentType => { - "the request didn't have a binary content type" - } - RouilleBincodeError::ParseError(_) => "error while parsing the bincode body", - } - ) - } - } - fn bincode_input(request: &rouille::Request) -> std::result::Result - where - O: serde::de::DeserializeOwned, - { - if let Some(header) = request.header("Content-Type") { - if !header.starts_with("application/octet-stream") { - return Err(RouilleBincodeError::WrongContentType); - } - } else { - return Err(RouilleBincodeError::WrongContentType); - } - - if let Some(mut b) = request.data() { - bincode::deserialize_from::<_, O>(&mut b).map_err(From::from) - } else { - Err(RouilleBincodeError::BodyAlreadyExtracted) - } - } - // Based on try_or_400 in rouille, but with logging #[derive(Serialize)] pub struct ErrJson { @@ -488,119 +385,14 @@ mod server { serde_json::to_string(&self).expect("infallible serialization for ErrJson failed") } } - macro_rules! try_or_err_and_log { - ($reqid:expr, $code:expr, $result:expr) => { - match $result { - Ok(r) => r, - Err(err) => { - // TODO: would ideally just use error_chain - #[allow(unused_imports)] - use std::error::Error; - let mut err_msg = err.to_string(); - let mut maybe_cause = err.source(); - while let Some(cause) = maybe_cause { - err_msg.push_str(", caused by: "); - err_msg.push_str(&cause.to_string()); - maybe_cause = cause.source(); - } - - warn!("Res {} error: {}", $reqid, err_msg); - let err: Box = err.into(); - let json = ErrJson::from_err(&*err); - return rouille::Response::json(&json).with_status_code($code); - } - } - }; - } - macro_rules! try_or_400_log { - ($reqid:expr, $result:expr) => { - try_or_err_and_log!($reqid, 400, $result) - }; - } - macro_rules! try_or_500_log { - ($reqid:expr, $result:expr) => { - try_or_err_and_log!($reqid, 500, $result) - }; - } - fn make_401_with_body(short_err: &str, body: ClientVisibleMsg) -> rouille::Response { - rouille::Response { - status_code: 401, - headers: vec![( - "WWW-Authenticate".into(), - format!("Bearer error=\"{}\"", short_err).into(), - )], - data: rouille::ResponseBody::from_data(body.0), - upgrade: None, - } - } - fn make_401(short_err: &str) -> rouille::Response { - make_401_with_body(short_err, ClientVisibleMsg(String::new())) - } - fn bearer_http_auth(request: &rouille::Request) -> Option<&str> { - let header = request.header("Authorization")?; - - let mut split = header.splitn(2, |c| c == ' '); - - let authtype = split.next()?; - if authtype != "Bearer" { - return None; - } - - split.next() - } - - /// Return `content` as a bincode-encoded `Response`. - pub fn bincode_response(content: &T) -> rouille::Response - where - T: serde::Serialize, - { - let data = bincode::serialize(content).context("Failed to serialize response body"); - let data = try_or_500_log!("bincode body serialization", data); - - rouille::Response { - status_code: 200, - headers: vec![("Content-Type".into(), "application/octet-stream".into())], - data: rouille::ResponseBody::from_data(data), - upgrade: None, - } - } - /// Return `content` as either a bincode or json encoded `Response` - /// depending on the Accept header in `request`. - pub fn prepare_response(request: &rouille::Request, content: &T) -> rouille::Response - where - T: serde::Serialize, - { - accept!(request, - "application/octet-stream" => bincode_response(content), - "application/json" => rouille::Response::json(content), - ) - } - - // Verification of job auth in a request - macro_rules! job_auth_or_401 { - ($request:ident, $job_authorizer:expr, $job_id:expr) => {{ - let verify_result = match bearer_http_auth($request) { - Some(token) => $job_authorizer.verify_token($job_id, token), - None => Err(anyhow!("no Authorization header")), - }; - match verify_result { - Ok(()) => (), - Err(err) => { - let err: Box = err.into(); - let json = ErrJson::from_err(&*err); - return make_401_with_body("invalid_jwt", ClientVisibleMsg(json.into_data())); - } - } - }}; - } // Generation and verification of job auth struct JWTJobAuthorizer { server_key: Vec, } impl JWTJobAuthorizer { - fn new(server_key: Vec) -> Box { - Box::new(Self { server_key }) + fn new(server_key: Vec) -> Self { + Self { server_key } } } impl dist::JobAuthorizer for JWTJobAuthorizer { @@ -613,7 +405,7 @@ mod server { fn verify_token(&self, job_id: JobId, token: &str) -> Result<()> { let valid_claims = JobJwt { job_id }; let key = jwt::DecodingKey::from_secret(&self.server_key); - jwt::decode(&token, &key, &JWT_VALIDATION) + jwt::decode(token, &key, &JWT_VALIDATION) .map_err(|e| anyhow!("JWT decode failed: {}", e)) .and_then(|res| { fn identical_t(_: &T, _: &T) {} @@ -629,6 +421,7 @@ mod server { #[test] fn test_job_token_verification() { + use crate::dist::JobAuthorizer; let ja = JWTJobAuthorizer::new(vec![1, 2, 2]); let job_id = JobId(55); @@ -651,80 +444,891 @@ mod server { assert!(ja2.verify_token(job_id2, &token2).is_err()); } - pub struct Scheduler { - public_addr: SocketAddr, - handler: S, - // Is this client permitted to use the scheduler? - check_client_auth: Box, - // Do we believe the server is who they appear to be? - check_server_auth: ServerAuthCheck, - } + mod distserver_api_v1 { + use thiserror::Error; + + pub use filters::api; + + #[derive(Error, Debug)] + pub enum Error { + #[error("failed to assign job")] + AssignJob, + #[error("authorization header is wrong")] + AuthorizationHeaderBroken, + #[error("bearer_auth_failed")] + BearerAuthFailed, + #[error("a bincode error has occured")] + Bincode, + } - impl Scheduler { - pub fn new( - public_addr: SocketAddr, - handler: S, - check_client_auth: Box, - check_server_auth: ServerAuthCheck, - ) -> Self { - Self { - public_addr, - handler, - check_client_auth, - check_server_auth, + impl warp::reject::Reject for Error {} + + pub(super) mod filters { + use std::convert::Infallible; + use std::sync::{atomic, Arc}; + use warp::{ + http::{ + header::{ACCEPT, AUTHORIZATION, WWW_AUTHENTICATE}, + HeaderValue, StatusCode, + }, + reply::{self, Response}, + Filter, Rejection, Reply, + }; + + use super::{handlers, Error}; + use crate::dist::{ + self, + http::server::{ClientVisibleMsg, ErrJson}, + JobAuthorizer, JobId, ServerIncoming, + }; + + fn bearer_http_auth(auth_header: &HeaderValue) -> Result { + let header = auth_header + .to_str() + .map_err(|_| Error::AuthorizationHeaderBroken)?; + + let mut split = header.splitn(2, |c| c == ' '); + + let authtype = split.next().ok_or(Error::AuthorizationHeaderBroken)?; + + if authtype != "Bearer" { + return Err(Error::AuthorizationHeaderBroken); + } + + Ok(split + .next() + .ok_or(Error::AuthorizationHeaderBroken)? + .to_string()) + } + + async fn authorize( + job_id: JobId, + authorizer: Arc, + auth_header: HeaderValue, + ) -> Result { + let token = bearer_http_auth(&auth_header)?; + + authorizer + .verify_token(job_id, &token) + .map_err(|_| Error::BearerAuthFailed)?; + + Ok(job_id) + } + + fn with_job_authorizer( + job_authorizer: Arc, + ) -> impl Filter,), Error = Infallible> + Clone + { + warp::any().map(move || job_authorizer.clone()) + } + + fn with_requester( + requester: Arc, + ) -> impl Filter,), Error = Infallible> + Clone + { + warp::any().map(move || requester.clone()) + } + + fn with_server_incoming_handler( + handler: Arc, + ) -> impl Filter,), Error = Infallible> + Clone + { + warp::any().map(move || handler.clone()) + } + + async fn prepare_response( + content: T, + accept: Option, + ) -> Result + where + T: serde::Serialize, + { + match accept { + Some(accept) if accept == "application/json" => { + Ok(warp::reply::json(&content).into_response()) + } + _ => Ok(warp::http::Response::builder() + .body(hyper::Body::from( + bincode::serialize(&content).map_err(|_| Error::Bincode)?, + )) + .map_err(|_| Error::Bincode)?), + } + } + + // POST /api/v1/distserver/assign_job/{job_id: JobId} + fn assign_job( + request_counter: Arc, + job_authorizer: Arc, + handler: Arc, + ) -> impl Filter + Clone { + let with_request_id = + warp::any().map(move || request_counter.fetch_add(1, atomic::Ordering::SeqCst)); + + warp::path!("api" / "v1" / "distserver" / "assign_job" / JobId) + .and(warp::post()) + .and(with_job_authorizer(job_authorizer)) + .and(warp::header::value(AUTHORIZATION.as_str())) + .and_then(authorize) + .and(toolchain()) + .and(with_server_incoming_handler(handler)) + .and(with_request_id) + .and_then(handlers::assign_job) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + // POST /api/v1/distserver/submit_toolchain/{job_id: JobId} + fn submit_toolchain( + _request_counter: Arc, + job_authorizer: Arc, + handler: Arc, + requester: Arc, + ) -> impl Filter + Clone { + warp::path!("api" / "v1" / "distserver" / "submit_toolchain" / JobId) + .and(warp::post()) + .and(with_job_authorizer(job_authorizer)) + .and(warp::header::value(AUTHORIZATION.as_str())) + .and_then(authorize) + .and(with_server_incoming_handler(handler)) + .and(with_requester(requester)) + .and(warp::body::bytes()) + .and_then(handlers::submit_toolchain) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + // POST /api/v1/distserver/run_job/{job_id: JobId} + fn run_job( + _request_counter: Arc, + job_authorizer: Arc, + handler: Arc, + requester: Arc, + ) -> impl Filter + Clone { + warp::path!("api" / "v1" / "distserver" / "run_job" / JobId) + .and(warp::post()) + .and(with_job_authorizer(job_authorizer)) + .and(warp::header::value(AUTHORIZATION.as_str())) + .and_then(authorize) + .and(with_server_incoming_handler(handler)) + .and(with_requester(requester)) + .and(warp::body::bytes()) + .and_then(handlers::run_job) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + pub fn api( + job_authorizer: Arc, + server_incoming_handler: Arc, + requester: Arc, + ) -> impl Filter + Clone { + let request_count = Arc::new(atomic::AtomicUsize::new(0)); + + assign_job( + request_count.clone(), + job_authorizer.clone(), + server_incoming_handler.clone(), + ) + .or(submit_toolchain( + request_count.clone(), + job_authorizer.clone(), + server_incoming_handler.clone(), + requester.clone(), + )) + .or(run_job( + request_count, + job_authorizer, + server_incoming_handler, + requester, + )) + .recover(handle_rejection) + } + + fn make_401_with_body(short_err: &str, body: Option) -> Response { + let body = reply::with_status( + body.map(|b| b.0).unwrap_or_default(), + StatusCode::UNAUTHORIZED, + ); + + reply::with_header( + body, + WWW_AUTHENTICATE, + format!("Bearer error=\"{}\"", short_err), + ) + .into_response() + } + + fn err_and_log(err: E, status: StatusCode) -> Response { + let mut err_msg = err.to_string(); + let mut maybe_cause = err.source(); + while let Some(cause) = maybe_cause { + err_msg.push_str(", caused by: "); + err_msg.push_str(&cause.to_string()); + maybe_cause = cause.source(); + } + + warn!("Res error: {}", err_msg); + let err: Box = err.into(); + let json = ErrJson::from_err(&*err); + + reply::with_status(warp::reply::json(&json), status).into_response() + } + + async fn handle_rejection(err: Rejection) -> Result { + if err.is_not_found() { + Ok(reply::with_status(warp::reply(), StatusCode::NOT_FOUND).into_response()) + } else if let Some(e) = err.find::() { + if e.name() == AUTHORIZATION.as_str() { + let err: Box = e.into(); + let json = ErrJson::from_err(&*err); + + Ok(make_401_with_body( + "invalid_jwt", + Some(ClientVisibleMsg(json.into_data())), + ) + .into_response()) + } else { + Ok( + warp::reply::with_status(warp::reply(), StatusCode::NOT_FOUND) + .into_response(), + ) + } + } else if let Some(e) = err.find::() { + match e { + Error::AuthorizationHeaderBroken | Error::BearerAuthFailed => { + let err: Box = e.into(); + let json = ErrJson::from_err(&*err); + Ok(make_401_with_body( + "invalid_jwt", + Some(ClientVisibleMsg(json.into_data())), + ) + .into_response()) + } + Error::Bincode => Ok(err_and_log(e, StatusCode::BAD_REQUEST)), + Error::AssignJob => Ok(err_and_log(e, StatusCode::INTERNAL_SERVER_ERROR)), + } + } else { + Ok( + warp::reply::with_status(warp::reply(), StatusCode::NOT_FOUND) + .into_response(), + ) + } + } + + async fn from_bytes(bytes: bytes::Bytes) -> Result + where + O: serde::de::DeserializeOwned, + { + let a = bincode::deserialize_from::<_, O>(bytes.as_ref()) + .map_err(|_| Error::Bincode) + .map_err(warp::reject::custom)?; + + Ok(a) + } + + fn toolchain() -> impl Filter + Clone { + warp::body::bytes().and_then(from_bytes) } } - pub fn start(self) -> Result { - let Self { - public_addr, - handler, - check_client_auth, - check_server_auth, - } = self; - let requester = SchedulerRequester { - client: Mutex::new(reqwest::blocking::Client::new()), + pub(super) mod handlers { + use super::super::JobId; + use super::super::RunJobHttpRequest; + use super::Error; + use crate::dist::{ + AssignJobResult, InputsReader, RunJobResult, SubmitToolchainResult, ToolchainReader, + }; + use crate::dist::{ServerIncoming, ServerOutgoing, Toolchain}; + use byteorder::{BigEndian, ReadBytesExt}; + use flate2::read::ZlibDecoder as ZlibReadDecoder; + use std::sync::Arc; + use warp::reject::Rejection; + + pub async fn assign_job( + job_id: JobId, + toolchain: Toolchain, + handler: Arc, + _req_id: usize, + ) -> Result { + let res = handler + .handle_assign_job(job_id, toolchain) + .await + .map_err(|_| warp::reject::custom(Error::AssignJob))?; + + Ok(res) + } + + pub async fn submit_toolchain( + job_id: JobId, + handler: Arc, + requester: Arc, + body: bytes::Bytes, + ) -> Result { + let toolchain_rdr = ToolchainReader(Box::new(body.as_ref())); + let res = handler + .handle_submit_toolchain(requester.as_ref(), job_id, toolchain_rdr) + .await + .map_err(|_| warp::reject::custom(Error::AssignJob))?; + + Ok(res) + } + + pub async fn run_job( + job_id: JobId, + handler: Arc, + requester: Arc, + body: bytes::Bytes, + ) -> Result { + use std::io::Read; + + let mut body = body.as_ref(); + let bincode_length = body + .read_u32::() + .map_err(|_| warp::reject::custom(Error::AssignJob))? + as u64; + + let mut bincode_reader = body.take(bincode_length); + let runjob = bincode::deserialize_from(&mut bincode_reader) + .map_err(|_| warp::reject::custom(Error::AssignJob))?; + + let RunJobHttpRequest { command, outputs } = runjob; + + let body = bincode_reader.into_inner(); + + let inputs_rdr = InputsReader(Box::new(ZlibReadDecoder::new(body))); + + let outputs = outputs.into_iter().collect(); + + let res = handler + .handle_run_job(requester.as_ref(), job_id, command, outputs, inputs_rdr) + .await + .map_err(|_| warp::reject::custom(Error::AssignJob))?; + + Ok(res) + } + } + } + + mod scheduler_api_v1 { + use thiserror::Error; + + pub use filters::api; + + #[derive(Error, Debug)] + pub enum Error { + #[error("no Authorization header")] + NoAuthorizationHeader, + #[error("authorization header is wrong")] + AuthorizationHeaderBroken, + #[error("bearer_auth_failed")] + BearerAuthFailed, + #[error("bincode error")] + Bincode, + #[error("failed to alloc job")] + AllocJob, + #[error("failed to get status")] + Status, + #[error("bad request")] + BadRequest, + #[error("invalid_bearer_token_mismatched_address")] + InvalidBearerTokenMismatchedAddress, + #[error("invalid_bearer_token")] + InvalidBearerToken, + #[error("update certs")] + UpdateCerts, + #[error("failed to interpret pem as certificate")] + BadCertificate, + #[error("failed to create a HTTP client")] + NoHTTPClient, + #[error("failed to process heartbeat")] + Heartbeat, + #[error("failed to update job state")] + UpdateJobState, + #[error("failed to create a http client")] + ClientBuildFailed, + } + + impl warp::reject::Reject for Error {} + + pub(super) mod filters { + use super::super::{ + ClientAuthCheck, ClientVisibleMsg, ErrJson, SchedulerRequester, ServerAuthCheck, }; + use super::{handlers, Error}; + use crate::dist; + use crate::dist::{JobId, ServerId}; + use bytes::Buf; + use std::collections::HashMap; + use std::convert::Infallible; + use std::net::SocketAddr; + use std::sync::Arc; + use tokio::sync::Mutex; + use warp::http::header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE, WWW_AUTHENTICATE}; + use warp::{ + http::{ + header::{HeaderMap, HeaderValue}, + StatusCode, + }, + reply::{self, Response}, + Filter, Rejection, Reply, + }; + + fn make_401_with_body(short_err: &str, body: ClientVisibleMsg) -> Response { + let body = reply::with_status(body.0, StatusCode::UNAUTHORIZED); + reply::with_header( + body, + WWW_AUTHENTICATE, + format!("Bearer error=\"{}\"", short_err), + ) + .into_response() + } + + fn err_and_log(err: E, status: StatusCode) -> Response { + let mut err_msg = err.to_string(); + let mut maybe_cause = err.source(); + while let Some(cause) = maybe_cause { + err_msg.push_str(", caused by: "); + err_msg.push_str(&cause.to_string()); + maybe_cause = cause.source(); + } + + warn!("Res error: {}", err_msg); + let err: Box = err.into(); + let json = ErrJson::from_err(&*err); + + reply::with_status(warp::reply::json(&json), status).into_response() + } + + async fn handle_rejection( + err: Rejection, + ) -> Result { + if err.is_not_found() { + Ok(reply::with_status(warp::reply(), StatusCode::NOT_FOUND).into_response()) + } else if let Some(e) = err.find::() { + if e.name() == AUTHORIZATION.as_str() { + let err: Box = e.into(); + let json = ErrJson::from_err(&*err); + + Ok( + make_401_with_body("invalid_jwt", ClientVisibleMsg(json.into_data())) + .into_response(), + ) + } else { + Ok( + warp::reply::with_status(warp::reply(), StatusCode::NOT_FOUND) + .into_response(), + ) + } + } else if let Some(e) = err.find::() { + match e { + Error::NoAuthorizationHeader + | Error::BearerAuthFailed + | Error::AuthorizationHeaderBroken + | Error::InvalidBearerTokenMismatchedAddress + | Error::InvalidBearerToken => { + let err: Box = e.into(); + let json = ErrJson::from_err(&*err); + Ok(make_401_with_body( + "invalid_jwt", + ClientVisibleMsg(json.into_data()), + ) + .into_response()) + } + Error::Bincode + | Error::UpdateCerts + | Error::BadRequest + | Error::BadCertificate => Ok(err_and_log(e, StatusCode::BAD_REQUEST)), + Error::AllocJob + | Error::Heartbeat + | Error::UpdateJobState + | Error::Status + | Error::NoHTTPClient + | Error::ClientBuildFailed => { + Ok(err_and_log(e, StatusCode::INTERNAL_SERVER_ERROR)) + } + } + } else { + Ok(reply::with_status(warp::reply(), StatusCode::NOT_FOUND).into_response()) + } + } + + pub fn api( + requester: Arc, + auth: Arc, + s: Arc, + certificates: Arc, Vec)>>>, + check_server_auth: ServerAuthCheck, + ) -> impl Filter + Clone { + alloc_job( + requester.clone(), + auth.clone(), + s.clone(), + certificates.clone(), + ) + .or(server_certificate(certificates.clone())) + .or(heartbeat_server( + check_server_auth.clone(), + s.clone(), + certificates, + requester, + )) + .or(job_state(check_server_auth, s.clone())) + .or(status(s)) + .recover(handle_rejection) + } + + // POST /api/v1/scheduler/alloc_job + fn alloc_job( + requester: Arc, + auth: Arc, + s: Arc, + certificates: Arc, Vec)>>>, + ) -> impl Filter + Clone { + warp::path!("api" / "v1" / "scheduler" / "alloc_job") + .and(warp::post()) + .and(with_client_authorizer(auth)) + .and(warp::header::value(AUTHORIZATION.as_str())) + .and_then(authorize) + .untuple_one() + .and(with_handler(s)) + .and(toolchain()) + .and(with_requester(requester)) + .and(with_certificates(certificates)) + .and_then(handlers::alloc_job) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + // GET /api/v1/scheduler/server_certificate/{server_id: ServerId}) + fn server_certificate( + certificates: Arc, Vec)>>>, + ) -> impl Filter + Clone { + warp::path!("api" / "v1" / "scheduler" / "server_certificate" / ServerId) + .and(warp::get()) + .and(with_certificates(certificates)) + .and_then(handlers::server_certificate) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + // POST /api/v1/scheduler/heartbeat_server + fn heartbeat_server( + check_server_auth: ServerAuthCheck, + s: Arc, + certificates: Arc, Vec)>>>, + requester: Arc, + ) -> impl Filter + Clone { + warp::path!("api" / "v1" / "scheduler" / "heartbeat_server") + .and(warp::post()) + .and(with_server_auth(check_server_auth)) + .and(warp::header::headers_cloned()) + .and(warp::addr::remote()) + .and_then(auth_server) + .and(with_handler(s)) + .and(bincode_input()) + .and(with_certificates(certificates)) + .and(with_requester(requester)) + .and_then(handlers::heartbeat_server) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + // POST /api/v1/scheduler/job_state/{job_id: JobId} + fn job_state( + check_server_auth: ServerAuthCheck, + s: Arc, + ) -> impl Filter + Clone { + warp::path!("api" / "v1" / "scheduler" / "job_state" / JobId) + .and(warp::post()) + .and( + with_server_auth(check_server_auth) + .and(warp::header::headers_cloned()) + .and(warp::addr::remote()) + .and_then(auth_server), + ) + .and(with_handler(s)) + .and(bincode_input()) + .and_then(handlers::job_state) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + // GET /api/v1/scheduler/status + fn status( + s: Arc, + ) -> impl Filter + Clone + { + warp::path!("api" / "v1" / "scheduler" / "status") + .and(warp::get()) + .and(with_handler(s)) + .and_then(handlers::status) + .and(warp::filters::header::optional::(ACCEPT.as_str())) + .and_then(prepare_response) + } + + fn bincode_input() -> impl Filter + Clone + where + T: serde::de::DeserializeOwned + std::marker::Send, + { + warp::header::exact_ignore_case(CONTENT_TYPE.as_str(), "application/octet-stream") + .and( + warp::body::bytes().and_then(|body: bytes::Bytes| async move { + let mut reader = body.reader(); + bincode::deserialize_from::<_, T>(&mut reader) + .map_err(|_| warp::reject::custom(Error::Bincode)) + }), + ) + } + + async fn prepare_response( + content: T, + accept: Option, + ) -> Result + where + T: serde::Serialize, + { + match accept { + Some(accept) if accept == "application/json" => { + Ok(warp::reply::json(&content).into_response()) + } + _ => Ok(warp::http::Response::builder() + .header(CONTENT_TYPE, "application/octet-stream") + .body(hyper::Body::from( + bincode::serialize(&content).map_err(|_| Error::Bincode)?, + )) + .map_err(|_| Error::Bincode)?), + } + } + + fn with_handler( + handler: Arc, + ) -> impl Filter,), Error = Infallible> + Clone + { + warp::any().map(move || handler.clone()) + } + + fn with_requester( + requester: Arc, + ) -> impl Filter,), Error = Infallible> + Clone + { + warp::any().map(move || requester.clone()) + } + + fn with_certificates( + certificates: Arc, Vec)>>>, + ) -> impl Filter< + Extract = (Arc, Vec)>>>,), + Error = Infallible, + > + Clone { + warp::any().map(move || certificates.clone()) + } + + fn with_server_auth( + check_server_auth: ServerAuthCheck, + ) -> impl Filter + Clone { + warp::any().map(move || check_server_auth.clone()) + } + + fn with_client_authorizer( + client_authorizer: Arc, + ) -> impl Filter,), Error = Infallible> + Clone + { + warp::any().map(move || client_authorizer.clone()) + } + + fn bearer_http_auth(auth_header: &HeaderValue) -> Result { + let header = auth_header + .to_str() + .map_err(|_| Error::AuthorizationHeaderBroken)?; + + let mut split = header.splitn(2, |c| c == ' '); + + let authtype = split.next().ok_or(Error::AuthorizationHeaderBroken)?; + + if authtype != "Bearer" { + return Err(Error::AuthorizationHeaderBroken); + } + + Ok(split + .next() + .ok_or(Error::AuthorizationHeaderBroken)? + .to_string()) + } + + async fn authorize( + check_client_auth: Arc, + auth_header: HeaderValue, + ) -> Result<(), Rejection> { + let bearer_auth = bearer_http_auth(&auth_header)?; - macro_rules! check_server_auth_or_err { - ($request:ident) => {{ - match bearer_http_auth($request).and_then(&*check_server_auth) { - Some(server_id) => { - let origin_ip = if let Some(header_val) = $request.header("X-Real-IP") { - trace!("X-Real-IP: {:?}", header_val); - match header_val.parse() { - Ok(ip) => ip, - Err(err) => { - warn!( - "X-Real-IP value {:?} could not be parsed: {:?}", - header_val, err - ); - return rouille::Response::empty_400(); - } + check_client_auth + .check(&bearer_auth) + .await + .map_err(|_| Error::BearerAuthFailed)?; + + Ok(()) + } + + async fn auth_server( + check_server_auth: ServerAuthCheck, + headers: HeaderMap, + remote: Option, + ) -> Result { + let auth_header = headers + .get(AUTHORIZATION.as_str()) + .ok_or(Error::NoAuthorizationHeader)?; + + match check_server_auth(&bearer_http_auth(auth_header)?) { + Some(server_id) => { + let origin_ip = if let Some(header_val) = headers.get("X-Real-IP") { + trace!("X-Real-IP: {:?}", header_val); + match header_val.to_str().unwrap().parse() { + Ok(ip) => ip, + Err(err) => { + warn!( + "X-Real-IP value {:?} could not be parsed: {:?}", + header_val, err + ); + return Err(warp::reject::custom(Error::BadRequest)); } - } else { - $request.remote_addr().ip() - }; - if server_id.addr().ip() != origin_ip { - trace!("server ip: {:?}", server_id.addr().ip()); - trace!("request ip: {:?}", $request.remote_addr().ip()); - return make_401("invalid_bearer_token_mismatched_address"); - } else { - server_id } + } else { + remote.unwrap().ip() + }; + + if server_id.addr().ip() != origin_ip { + trace!("server ip: {:?}", server_id.addr().ip()); + trace!("request ip: {:?}", remote.unwrap().ip()); + Err(warp::reject::custom( + Error::InvalidBearerTokenMismatchedAddress, + )) + } else { + Ok(server_id) } - None => return make_401("invalid_bearer_token"), } - }}; + None => Err(warp::reject::custom(Error::InvalidBearerToken)), + } + } + + async fn from_bytes(bytes: bytes::Bytes) -> Result + where + O: serde::de::DeserializeOwned, + { + let a = bincode::deserialize_from::<_, O>(bytes.as_ref()) + .map_err(|_| Error::Bincode) + .map_err(warp::reject::custom)?; + + Ok(a) + } + + fn toolchain() -> impl Filter + Clone { + warp::body::bytes().and_then(from_bytes) + } + } + + pub(super) mod handlers { + use super::super::AllocJobHttpResponse; + use super::super::{HeartbeatServerHttpRequest, ServerCertificateHttpResponse}; + use super::super::{JWTJobAuthorizer, JobId, SchedulerRequester}; + use super::Error; + use crate::dist::{self, ServerId}; + use crate::dist::{ + HeartbeatServerResult, JobState, SchedulerStatusResult, UpdateJobStateResult, + }; + use std::collections::HashMap; + use std::sync::Arc; + use tokio::sync::Mutex; + use warp::reject::{self, Rejection}; + + pub async fn alloc_job( + handler: Arc, + toolchain: dist::Toolchain, + requester: Arc, + certs: Arc, Vec)>>>, + ) -> Result { + let alloc_job_res = handler + .handle_alloc_job(requester.as_ref(), toolchain) + .await + .map_err(|_| reject::custom(Error::AllocJob))?; + + let certs = certs.lock().await; + let res = AllocJobHttpResponse::from_alloc_job_result(alloc_job_res, &certs); + + Ok(res) + } + + pub async fn server_certificate( + server_id: ServerId, + certificates: Arc, Vec)>>>, + ) -> Result { + let certs = certificates.lock().await; + + let (cert_digest, cert_pem) = certs.get(&server_id).cloned().unwrap(); + let res = ServerCertificateHttpResponse { + cert_digest, + cert_pem, + }; + + Ok(res) } - fn maybe_update_certs( - client: &mut reqwest::blocking::Client, + pub async fn heartbeat_server( + server_id: ServerId, + handler: Arc, + heartbeat_server: HeartbeatServerHttpRequest, + server_certificates: Arc, Vec)>>>, + requester: Arc, + ) -> Result { + let HeartbeatServerHttpRequest { + num_cpus, + jwt_key, + server_nonce, + cert_digest, + cert_pem, + } = heartbeat_server; + + let mut client = requester.client.lock().await; + let mut certs = server_certificates.lock().await; + maybe_update_certs(&mut *client, &mut certs, server_id, cert_digest, cert_pem) + .await + .map_err(|_| Error::UpdateCerts)?; + + let job_authorizer = Box::new(JWTJobAuthorizer::new(jwt_key)); + let res: HeartbeatServerResult = handler + .handle_heartbeat_server(server_id, server_nonce, num_cpus, job_authorizer) + .map_err(|_| Error::Heartbeat)?; + + Ok(res) + } + + pub async fn job_state( + job_id: JobId, + server_id: ServerId, + handler: Arc, + job_state: JobState, + ) -> Result { + let res = handler + .handle_update_job_state(job_id, server_id, job_state) + .map_err(|_| Error::UpdateJobState)?; + + Ok(res) + } + + pub async fn status( + handler: Arc, + ) -> Result { + let res: SchedulerStatusResult = + handler.handle_status().map_err(|_| Error::Status)?; + Ok(res) + } + + async fn maybe_update_certs( + client: &mut reqwest::Client, certs: &mut HashMap, Vec)>, server_id: ServerId, cert_digest: Vec, cert_pem: Vec, - ) -> Result<()> { + ) -> Result<(), Error> { if let Some((saved_cert_digest, _)) = certs.get(&server_id) { if saved_cert_digest == &cert_digest { return Ok(()); @@ -734,125 +1338,89 @@ mod server { "Adding new certificate for {} to scheduler", server_id.addr() ); - let mut client_builder = reqwest::blocking::ClientBuilder::new(); + + let _ = native_tls::Certificate::from_pem(&cert_pem) + .map_err(|_| Error::BadCertificate)?; // Add all the certificates we know about - client_builder = client_builder.add_root_certificate( - reqwest::Certificate::from_pem(&cert_pem) - .context("failed to interpret pem as certificate")?, - ); - for (_, cert_pem) in certs.values() { - client_builder = client_builder.add_root_certificate( - reqwest::Certificate::from_pem(cert_pem).expect("previously valid cert"), - ); - } + let root_certs = + std::iter::once(&cert_pem).chain(certs.values().map(|(_, cert_pem)| cert_pem)); + let client_builder = crate::util::native_tls_no_sni_client_builder(root_certs) + .map_err(|_| Error::ClientBuildFailed)?; + // Finish the clients - let new_client = client_builder - .build() - .context("failed to create a HTTP client")?; + let new_client = client_builder.build().map_err(|_| Error::NoHTTPClient)?; // Use the updated certificates *client = new_client; certs.insert(server_id, (cert_digest, cert_pem)); Ok(()) } + } + } + + pub struct Scheduler { + public_addr: SocketAddr, + handler: S, + // Is this client permitted to use the scheduler? + check_client_auth: Box, + // Do we believe the server is who they appear to be? + check_server_auth: ServerAuthCheck, + } + + impl Scheduler { + pub fn new( + public_addr: SocketAddr, + handler: S, + check_client_auth: Box, + check_server_auth: ServerAuthCheck, + ) -> Self { + Self { + public_addr, + handler, + check_client_auth, + check_server_auth, + } + } + pub async fn start(self) -> Result { + let Self { + public_addr, + handler, + check_client_auth, + check_server_auth, + } = self; + + let client = + crate::util::native_tls_no_sni_client_builder(std::iter::empty::>()) + .unwrap() + .build() + .unwrap(); + let requester = Arc::new(SchedulerRequester { + client: Mutex::new(client), + }); + + let check_client_auth = Arc::from(check_client_auth); + let handler = Arc::from(handler); + let server_certificates = Arc::new(Mutex::new(HashMap::new())); + let api = scheduler_api_v1::api( + requester, + check_client_auth, + handler, + server_certificates, + check_server_auth, + ); info!("Scheduler listening for clients on {}", public_addr); - let request_count = atomic::AtomicUsize::new(0); - // From server_id -> cert_digest, cert_pem - let server_certificates: Mutex, Vec)>> = - Default::default(); - - let server = rouille::Server::new(public_addr, move |request| { - let req_id = request_count.fetch_add(1, atomic::Ordering::SeqCst); - trace!("Req {} ({}): {:?}", req_id, request.remote_addr(), request); - let response = (|| router!(request, - (POST) (/api/v1/scheduler/alloc_job) => { - let bearer_auth = match bearer_http_auth(request) { - Some(s) => s, - None => return make_401("no_bearer_auth"), - }; - match check_client_auth.check(bearer_auth) { - Ok(()) => (), - Err(client_msg) => { - warn!("Bearer auth failed: {:?}", client_msg); - return make_401_with_body("bearer_auth_failed", client_msg) - }, - } - let toolchain = try_or_400_log!(req_id, bincode_input(request)); - trace!("Req {}: alloc_job: {:?}", req_id, toolchain); - - let alloc_job_res: AllocJobResult = try_or_500_log!(req_id, handler.handle_alloc_job(&requester, toolchain)); - let certs = server_certificates.lock().unwrap(); - let res = AllocJobHttpResponse::from_alloc_job_result(alloc_job_res, &certs); - prepare_response(&request, &res) - }, - (GET) (/api/v1/scheduler/server_certificate/{server_id: ServerId}) => { - let certs = server_certificates.lock().unwrap(); - let (cert_digest, cert_pem) = try_or_500_log!(req_id, certs.get(&server_id) - .context("server cert not available")); - let res = ServerCertificateHttpResponse { - cert_digest: cert_digest.clone(), - cert_pem: cert_pem.clone(), - }; - prepare_response(&request, &res) - }, - (POST) (/api/v1/scheduler/heartbeat_server) => { - let server_id = check_server_auth_or_err!(request); - let heartbeat_server = try_or_400_log!(req_id, bincode_input(request)); - trace!("Req {}: heartbeat_server: {:?}", req_id, heartbeat_server); - - let HeartbeatServerHttpRequest { num_cpus, jwt_key, server_nonce, cert_digest, cert_pem } = heartbeat_server; - try_or_500_log!(req_id, maybe_update_certs( - &mut requester.client.lock().unwrap(), - &mut server_certificates.lock().unwrap(), - server_id, cert_digest, cert_pem - )); - let job_authorizer = JWTJobAuthorizer::new(jwt_key); - let res: HeartbeatServerResult = try_or_500_log!(req_id, handler.handle_heartbeat_server( - server_id, server_nonce, - num_cpus, - job_authorizer - )); - prepare_response(&request, &res) - }, - (POST) (/api/v1/scheduler/job_state/{job_id: JobId}) => { - let server_id = check_server_auth_or_err!(request); - let job_state = try_or_400_log!(req_id, bincode_input(request)); - trace!("Req {}: job state: {:?}", req_id, job_state); - - let res: UpdateJobStateResult = try_or_500_log!(req_id, handler.handle_update_job_state( - job_id, server_id, job_state - )); - prepare_response(&request, &res) - }, - (GET) (/api/v1/scheduler/status) => { - let res: SchedulerStatusResult = try_or_500_log!(req_id, handler.handle_status()); - prepare_response(&request, &res) - }, - _ => { - warn!("Unknown request {:?}", request); - rouille::Response::empty_404() - }, - ))(); - trace!("Res {}: {:?}", req_id, response); - response - }).map_err(|e| anyhow!(format!("Failed to start http server for cachepot scheduler: {}", e)))?; - - // This limit is rouille's default for `start_server_with_pool`, which - // we would use, except that interface doesn't permit any sort of - // error handling to be done. - let server = server.pool_size(num_cpus::get() * 8); - server.run(); - - panic!("Rouille server terminated") + warp::serve(api).run(public_addr).await; + + panic!("Warp server terminated") } } - - struct SchedulerRequester { - client: Mutex, + pub struct SchedulerRequester { + client: tokio::sync::Mutex, } + #[async_trait] impl dist::SchedulerOutgoing for SchedulerRequester { - fn do_assign_job( + async fn do_assign_job( &self, server_id: ServerId, job_id: JobId, @@ -860,8 +1428,9 @@ mod server { auth: String, ) -> Result { let url = urls::server_assign_job(server_id, job_id); - let req = self.client.lock().unwrap().post(url); + let req = self.client.lock().await.post(url); bincode_req(req.bearer_auth(auth).bincode(&tc)?) + .await .context("POST to scheduler assign_job failed") } } @@ -908,7 +1477,7 @@ mod server { }) } - pub fn start(self) -> Result { + pub async fn start(self) -> Result { let Self { public_addr, scheduler_url, @@ -920,6 +1489,9 @@ mod server { server_nonce, handler, } = self; + + let handler = Arc::new(handler); + let heartbeat_req = HeartbeatServerHttpRequest { num_cpus: num_cpus::get(), jwt_key: jwt_key.clone(), @@ -927,109 +1499,64 @@ mod server { cert_digest, cert_pem: cert_pem.clone(), }; - let job_authorizer = JWTJobAuthorizer::new(jwt_key); + let job_authorizer = Arc::new(JWTJobAuthorizer::new(jwt_key)); let heartbeat_url = urls::scheduler_heartbeat_server(&scheduler_url); - let requester = ServerRequester { - client: reqwest::blocking::Client::new(), + let requester = Arc::new(ServerRequester { + client: reqwest::Client::new(), scheduler_url, scheduler_auth: scheduler_auth.clone(), - }; + }); + + let api = distserver_api_v1::api(job_authorizer, handler, requester); - // TODO: detect if this panics - thread::spawn(move || { - let client = reqwest::blocking::Client::new(); + tokio::spawn(async move { + use tokio::time; + + let client = reqwest::Client::new(); loop { - trace!("Performing heartbeat"); + trace!("Performing hearbeat"); match bincode_req( client .post(heartbeat_url.clone()) .bearer_auth(scheduler_auth.clone()) .bincode(&heartbeat_req) - .expect("failed to serialize heartbeat"), - ) { + .expect("failed to serialize a heartbeat"), + ) + .await + { Ok(HeartbeatServerResult { is_new }) => { trace!("Heartbeat success is_new={}", is_new); // TODO: if is_new, terminate all running jobs - thread::sleep(HEARTBEAT_INTERVAL) + time::sleep(HEARTBEAT_INTERVAL).await; } Err(e) => { error!("Failed to send heartbeat to server: {}", e); - thread::sleep(HEARTBEAT_ERROR_INTERVAL) + time::sleep(HEARTBEAT_ERROR_INTERVAL).await; } } } }); - info!("Server listening for clients on {}", public_addr); - let request_count = atomic::AtomicUsize::new(0); - - let server = rouille::Server::new_ssl(public_addr, move |request| { - let req_id = request_count.fetch_add(1, atomic::Ordering::SeqCst); - trace!("Req {} ({}): {:?}", req_id, request.remote_addr(), request); - let response = (|| router!(request, - (POST) (/api/v1/distserver/assign_job/{job_id: JobId}) => { - job_auth_or_401!(request, &job_authorizer, job_id); - let toolchain = try_or_400_log!(req_id, bincode_input(request)); - trace!("Req {}: assign_job({}): {:?}", req_id, job_id, toolchain); - - let res: AssignJobResult = try_or_500_log!(req_id, handler.handle_assign_job(job_id, toolchain)); - prepare_response(&request, &res) - }, - (POST) (/api/v1/distserver/submit_toolchain/{job_id: JobId}) => { - job_auth_or_401!(request, &job_authorizer, job_id); - trace!("Req {}: submit_toolchain({})", req_id, job_id); - - let body = request.data().expect("body was already read in submit_toolchain"); - let toolchain_rdr = ToolchainReader(Box::new(body)); - let res: SubmitToolchainResult = try_or_500_log!(req_id, handler.handle_submit_toolchain(&requester, job_id, toolchain_rdr)); - prepare_response(&request, &res) - }, - (POST) (/api/v1/distserver/run_job/{job_id: JobId}) => { - job_auth_or_401!(request, &job_authorizer, job_id); - - let mut body = request.data().expect("body was already read in run_job"); - let bincode_length = try_or_500_log!(req_id, body.read_u32::() - .context("failed to read run job input length")) as u64; - - let mut bincode_reader = body.take(bincode_length); - let runjob = try_or_500_log!(req_id, bincode::deserialize_from(&mut bincode_reader) - .context("failed to deserialize run job request")); - trace!("Req {}: run_job({}): {:?}", req_id, job_id, runjob); - let RunJobHttpRequest { command, outputs } = runjob; - let body = bincode_reader.into_inner(); - let inputs_rdr = InputsReader(Box::new(ZlibReadDecoder::new(body))); - let outputs = outputs.into_iter().collect(); - - let res: RunJobResult = try_or_500_log!(req_id, handler.handle_run_job(&requester, job_id, command, outputs, inputs_rdr)); - prepare_response(&request, &res) - }, - _ => { - warn!("Unknown request {:?}", request); - rouille::Response::empty_404() - }, - ))(); - trace!("Res {}: {:?}", req_id, response); - response - }, cert_pem, privkey_pem).map_err(|e| anyhow!(format!("Failed to start http server for cachepot server: {}", e)))?; - - // This limit is rouille's default for `start_server_with_pool`, which - // we would use, except that interface doesn't permit any sort of - // error handling to be done. - let server = server.pool_size(num_cpus::get() * 8); - server.run(); - - panic!("Rouille server terminated") + warp::serve(api) + .tls() + .cert(cert_pem) + .key(privkey_pem) + .run(public_addr) + .await; + + panic!("Warp server terminated") } } struct ServerRequester { - client: reqwest::blocking::Client, + client: reqwest::Client, scheduler_url: reqwest::Url, scheduler_auth: String, } + #[async_trait] impl dist::ServerOutgoing for ServerRequester { - fn do_update_job_state( + async fn do_update_job_state( &self, job_id: JobId, state: JobState, @@ -1041,6 +1568,7 @@ mod server { .bearer_auth(self.scheduler_auth.clone()) .bincode(&state)?, ) + .await .context("POST to scheduler job_state failed") } } @@ -1062,11 +1590,12 @@ mod client { use std::collections::HashMap; use std::io::Write; use std::path::{Path, PathBuf}; - use std::sync::{Arc, Mutex}; + use std::sync::Arc; use std::time::Duration; + use tokio::sync::Mutex; use super::common::{ - bincode_req_fut, AllocJobHttpResponse, ReqwestRequestBuilderExt, RunJobHttpRequest, + bincode_req, AllocJobHttpResponse, ReqwestRequestBuilderExt, RunJobHttpRequest, ServerCertificateHttpResponse, }; use super::urls; @@ -1098,7 +1627,12 @@ mod client { ) -> Result { let timeout = Duration::new(REQUEST_TIMEOUT_SECS, 0); let connect_timeout = Duration::new(CONNECT_TIMEOUT_SECS, 0); - let client_async = reqwest::ClientBuilder::new() + + let builder = + crate::util::native_tls_no_sni_client_builder(std::iter::empty::>()) + .context("failed to create an async HTTP client")?; + + let client_async = builder .timeout(timeout) .connect_timeout(connect_timeout) .build() @@ -1123,17 +1657,11 @@ mod client { cert_digest: Vec, cert_pem: Vec, ) -> Result<()> { - let mut client_async_builder = reqwest::ClientBuilder::new(); // Add all the certificates we know about - client_async_builder = client_async_builder.add_root_certificate( - reqwest::Certificate::from_pem(&cert_pem) - .context("failed to interpret pem as certificate")?, - ); - for cert_pem in certs.values() { - client_async_builder = client_async_builder.add_root_certificate( - reqwest::Certificate::from_pem(cert_pem).expect("previously valid cert"), - ); - } + let root_certs = std::iter::once(&cert_pem).chain(certs.values()); + let client_async_builder = crate::util::native_tls_no_sni_client_builder(root_certs) + .context("failed to create an async HTTP client")?; + // Finish the clients let timeout = Duration::new(REQUEST_TIMEOUT_SECS, 0); let new_client_async = client_async_builder @@ -1152,13 +1680,13 @@ mod client { async fn do_alloc_job(&self, tc: Toolchain) -> Result { let scheduler_url = self.scheduler_url.clone(); let url = urls::scheduler_alloc_job(&scheduler_url); - let mut req = self.client_async.lock().unwrap().post(url); + let mut req = self.client_async.lock().await.post(url); req = req.bearer_auth(self.auth_token.clone()).bincode(&tc)?; let client_async = self.client_async.clone(); let server_certs = self.server_certs.clone(); - match bincode_req_fut(req).await? { + match bincode_req(req).await? { AllocJobHttpResponse::Success { job_alloc, need_toolchain, @@ -1169,7 +1697,7 @@ mod client { job_alloc, need_toolchain, }); - if server_certs.lock().unwrap().contains_key(&cert_digest) { + if server_certs.lock().await.contains_key(&cert_digest) { return alloc_job_res; } info!( @@ -1177,14 +1705,14 @@ mod client { server_id.addr() ); let url = urls::scheduler_server_certificate(&scheduler_url, server_id); - let req = client_async.lock().unwrap().get(url); - let res: ServerCertificateHttpResponse = bincode_req_fut(req) + let req = client_async.lock().await.get(url); + let res: ServerCertificateHttpResponse = bincode_req(req) .await .context("GET to scheduler server_certificate failed")?; Self::update_certs( - &mut client_async.lock().unwrap(), - &mut server_certs.lock().unwrap(), + &mut *client_async.lock().await, + &mut *server_certs.lock().await, res.cert_digest, res.cert_pem, ) @@ -1199,9 +1727,9 @@ mod client { async fn do_get_status(&self) -> Result { let scheduler_url = self.scheduler_url.clone(); let url = urls::scheduler_status(&scheduler_url); - let req = self.client_async.lock().unwrap().get(url); + let req = self.client_async.lock().await.get(url); - bincode_req_fut(req).await + bincode_req(req).await } async fn do_submit_toolchain( @@ -1212,7 +1740,7 @@ mod client { match self.tc_cache.get_toolchain(&tc) { Ok(Some(toolchain_file)) => { let url = urls::server_submit_toolchain(job_alloc.server_id, job_alloc.job_id); - let req = self.client_async.lock().unwrap().post(url); + let req = self.client_async.lock().await.post(url); let _toolchain_file_exists = toolchain_file.metadata()?; @@ -1224,7 +1752,7 @@ mod client { let body = reqwest::Body::wrap_stream(stream); let req = req.bearer_auth(job_alloc.auth).body(body); - bincode_req_fut(req).await + bincode_req(req).await } Ok(None) => Err(anyhow!("couldn't find toolchain locally")), Err(e) => Err(e), @@ -1239,7 +1767,7 @@ mod client { inputs_packager: Box, ) -> Result<(RunJobResult, PathTransformer)> { let url = urls::server_run_job(job_alloc.server_id, job_alloc.job_id); - let req = self.client_async.lock().unwrap().post(url); + let req = self.client_async.lock().await.post(url); let (path_transformer, compressed_body) = self .pool @@ -1275,7 +1803,7 @@ mod client { let req = req .bearer_auth(job_alloc.auth.clone()) .bytes(compressed_body); - let res = bincode_req_fut(req).await?; + let res = bincode_req(req).await?; Ok((res, path_transformer)) } diff --git a/src/dist/mod.rs b/src/dist/mod.rs index 6d2d3fd7..38e9b336 100644 --- a/src/dist/mod.rs +++ b/src/dist/mod.rs @@ -605,7 +605,7 @@ pub struct BuildResult { // http implementation) they need to be public, which has knock-on effects for private // structs -pub struct ToolchainReader<'a>(Box); +pub struct ToolchainReader<'a>(Box); impl<'a> Read for ToolchainReader<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.0.read(buf) @@ -623,9 +623,10 @@ impl<'a> Read for InputsReader<'a> { type ExtResult = ::std::result::Result; #[cfg(feature = "dist-server")] -pub trait SchedulerOutgoing { +#[async_trait] +pub trait SchedulerOutgoing: Send + Sync { // To Server - fn do_assign_job( + async fn do_assign_job( &self, server_id: ServerId, job_id: JobId, @@ -635,22 +636,28 @@ pub trait SchedulerOutgoing { } #[cfg(feature = "dist-server")] -pub trait ServerOutgoing { +#[async_trait] +pub trait ServerOutgoing: Send + Sync { // To Scheduler - fn do_update_job_state(&self, job_id: JobId, state: JobState) -> Result; + async fn do_update_job_state( + &self, + job_id: JobId, + state: JobState, + ) -> Result; } // Trait to handle the creation and verification of job authorization tokens #[cfg(feature = "dist-server")] -pub trait JobAuthorizer: Send { +pub trait JobAuthorizer: Send + Sync { fn generate_token(&self, job_id: JobId) -> Result; fn verify_token(&self, job_id: JobId, token: &str) -> Result<()>; } #[cfg(feature = "dist-server")] +#[async_trait] pub trait SchedulerIncoming: Send + Sync { // From Client - fn handle_alloc_job( + async fn handle_alloc_job( &self, requester: &dyn SchedulerOutgoing, tc: Toolchain, @@ -675,18 +682,23 @@ pub trait SchedulerIncoming: Send + Sync { } #[cfg(feature = "dist-server")] +#[async_trait] pub trait ServerIncoming: Send + Sync { // From Scheduler - fn handle_assign_job(&self, job_id: JobId, tc: Toolchain) -> ExtResult; + async fn handle_assign_job( + &self, + job_id: JobId, + tc: Toolchain, + ) -> ExtResult; // From Client - fn handle_submit_toolchain( + async fn handle_submit_toolchain( &self, requester: &dyn ServerOutgoing, job_id: JobId, tc_rdr: ToolchainReader<'_>, ) -> ExtResult; // From Client - fn handle_run_job( + async fn handle_run_job( &self, requester: &dyn ServerOutgoing, job_id: JobId, diff --git a/src/lib.rs b/src/lib.rs index 638a77a6..edd0fb75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,9 +32,6 @@ use jsonwebtoken as jwt; extern crate lazy_static; #[macro_use] extern crate log; -#[cfg(feature = "rouille")] -#[macro_use(router)] -extern crate rouille; #[macro_use] extern crate serde_derive; diff --git a/src/util.rs b/src/util.rs index 1901948d..7cd16a27 100644 --- a/src/util.rs +++ b/src/util.rs @@ -441,19 +441,6 @@ mod http_extension { ) } } - - #[cfg(feature = "reqwest")] - impl RequestExt for ::reqwest::blocking::RequestBuilder { - fn set_header(self, header: H) -> Self - where - H: hyperx::header::Header + fmt::Display, - { - self.header( - H::header_name(), - HeaderValue::from_maybe_shared(header.to_string()).unwrap(), - ) - } - } } /// Pipe `cmd`'s stdio to `/dev/null`, unless a specific env var is set. @@ -544,6 +531,42 @@ pub fn daemonize() -> Result<()> { Ok(()) } +// This function builds a custom `native-tls`-based `reqwest` client. +// +// It main goal is to dodge the currently existing issue that `request` +// is not able to connect to tls hosts by their IP addrs since it tries +// to put these addrs into the SNI extentions. As of this day falling back +// to a `native-tls` backend seems to be the only way to disable the `SNI` feature +// in `request`. Also all the intended root certificates have to be passed +// to the `native-tls` builder; using the higher-level `request` bulider API will +// not work. +// +// More context: +// https://github.com/seanmonstar/reqwest/issues/1328 +// https://github.com/briansmith/webpki/issues/54 +#[cfg(any(feature = "dist-client", feature = "dist-server"))] +pub fn native_tls_no_sni_client_builder<'a, I, T>(root_certs: I) -> Result +where + I: Iterator, + T: AsRef<[u8]>, +{ + let mut tls_builder = native_tls::TlsConnector::builder(); + + for root_cert in root_certs { + tls_builder.add_root_certificate(native_tls::Certificate::from_pem(root_cert.as_ref())?); + } + + tls_builder.use_sni(false); + + let tls = tls_builder.build()?; + + let client_builder = reqwest::ClientBuilder::new() + .use_native_tls() + .use_preconfigured_tls(tls); + + Ok(client_builder) +} + #[cfg(test)] mod tests { use super::OsStrExt; diff --git a/tests/dist.rs b/tests/dist.rs index d1440f94..5ce67c39 100644 --- a/tests/dist.rs +++ b/tests/dist.rs @@ -10,7 +10,7 @@ use crate::harness::{ cachepot_command, get_stats, start_local_daemon, stop_local_daemon, write_json_cfg, write_source, }; -use assert_cmd::prelude::*; +use async_trait::async_trait; use cachepot::config::HTTPUrl; use cachepot::dist::{ AssignJobResult, CompileCommand, InputsReader, JobId, JobState, RunJobResult, ServerIncoming, @@ -24,7 +24,7 @@ use cachepot::errors::*; mod harness; -fn basic_compile(tmpdir: &Path, cachepot_cfg_path: &Path, cachepot_cached_cfg_path: &Path) { +async fn basic_compile(tmpdir: &Path, cachepot_cfg_path: &Path, cachepot_cached_cfg_path: &Path) { let envs: Vec<(_, &OsStr)> = vec![ ("RUST_BACKTRACE", "1".as_ref()), ("RUST_LOG", "cachepot=trace".as_ref()), @@ -34,15 +34,19 @@ fn basic_compile(tmpdir: &Path, cachepot_cfg_path: &Path, cachepot_cached_cfg_pa let source_file = "x.c"; let obj_file = "x.o"; write_source(tmpdir, source_file, "#if !defined(CACHEPOT_TEST_DEFINE)\n#error CACHEPOT_TEST_DEFINE is not defined\n#endif\nint x() { return 5; }"); - cachepot_command() + let mut command: tokio::process::Command = cachepot_command().into(); + + assert!(command .arg(std::env::var("CC").unwrap_or_else(|_| "gcc".to_string())) .args(&["-c", "-DCACHEPOT_TEST_DEFINE"]) .arg(tmpdir.join(source_file)) .arg("-o") .arg(tmpdir.join(obj_file)) .envs(envs) - .assert() - .success(); + .status() + .await + .unwrap() + .success()) } pub fn dist_test_cachepot_client_cfg( @@ -55,10 +59,10 @@ pub fn dist_test_cachepot_client_cfg( cachepot_cfg } -#[test] +#[tokio::test] #[cfg_attr(not(feature = "dist-tests"), ignore)] #[serial] -fn test_dist_basic() { +async fn test_dist_basic() { let tmpdir = tempfile::Builder::new() .prefix("cachepot_dist_test") .tempdir() @@ -67,8 +71,8 @@ fn test_dist_basic() { let cachepot_dist = harness::cachepot_dist_path(); let mut system = harness::DistSystem::new(&cachepot_dist, tmpdir); - system.add_scheduler(); - system.add_server(); + system.add_scheduler().await; + system.add_server().await; let cachepot_cfg = dist_test_cachepot_client_cfg(tmpdir, system.scheduler_url()); let cachepot_cfg_path = tmpdir.join("cachepot-cfg.json"); @@ -77,7 +81,7 @@ fn test_dist_basic() { stop_local_daemon(); start_local_daemon(&cachepot_cfg_path, &cachepot_cached_cfg_path); - basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path); + basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path).await; get_stats(|info| { assert_eq!(1, info.stats.dist_compiles.values().sum::()); @@ -89,10 +93,10 @@ fn test_dist_basic() { }); } -#[test] +#[tokio::test] #[cfg_attr(not(feature = "dist-tests"), ignore)] #[serial] -fn test_dist_restartedserver() { +async fn test_dist_restartedserver() { let tmpdir = tempfile::Builder::new() .prefix("cachepot_dist_test") .tempdir() @@ -101,8 +105,8 @@ fn test_dist_restartedserver() { let cachepot_dist = harness::cachepot_dist_path(); let mut system = harness::DistSystem::new(&cachepot_dist, tmpdir); - system.add_scheduler(); - let server_handle = system.add_server(); + system.add_scheduler().await; + let server_handle = system.add_server().await; let cachepot_cfg = dist_test_cachepot_client_cfg(tmpdir, system.scheduler_url()); let cachepot_cfg_path = tmpdir.join("cachepot-cfg.json"); @@ -111,10 +115,10 @@ fn test_dist_restartedserver() { stop_local_daemon(); start_local_daemon(&cachepot_cfg_path, &cachepot_cached_cfg_path); - basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path); + basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path).await; - system.restart_server(&server_handle); - basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path); + system.restart_server(&server_handle).await; + basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path).await; get_stats(|info| { assert_eq!(2, info.stats.dist_compiles.values().sum::()); @@ -126,10 +130,10 @@ fn test_dist_restartedserver() { }); } -#[test] +#[tokio::test] #[cfg_attr(not(feature = "dist-tests"), ignore)] #[serial] -fn test_dist_nobuilder() { +async fn test_dist_nobuilder() { let tmpdir = tempfile::Builder::new() .prefix("cachepot_dist_test") .tempdir() @@ -138,7 +142,7 @@ fn test_dist_nobuilder() { let cachepot_dist = harness::cachepot_dist_path(); let mut system = harness::DistSystem::new(&cachepot_dist, tmpdir); - system.add_scheduler(); + system.add_scheduler().await; let cachepot_cfg = dist_test_cachepot_client_cfg(tmpdir, system.scheduler_url()); let cachepot_cfg_path = tmpdir.join("cachepot-cfg.json"); @@ -147,7 +151,7 @@ fn test_dist_nobuilder() { stop_local_daemon(); start_local_daemon(&cachepot_cfg_path, &cachepot_cached_cfg_path); - basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path); + basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path).await; get_stats(|info| { assert_eq!(0, info.stats.dist_compiles.values().sum::()); @@ -160,8 +164,9 @@ fn test_dist_nobuilder() { } struct FailingServer; +#[async_trait] impl ServerIncoming for FailingServer { - fn handle_assign_job(&self, _job_id: JobId, _tc: Toolchain) -> Result { + async fn handle_assign_job(&self, _job_id: JobId, _tc: Toolchain) -> Result { let need_toolchain = false; let state = JobState::Ready; Ok(AssignJobResult { @@ -169,33 +174,34 @@ impl ServerIncoming for FailingServer { state, }) } - fn handle_submit_toolchain( + async fn handle_submit_toolchain( &self, _requester: &dyn ServerOutgoing, _job_id: JobId, - _tc_rdr: ToolchainReader, + _tc_rdr: ToolchainReader<'_>, ) -> Result { panic!("should not have submitted toolchain") } - fn handle_run_job( + async fn handle_run_job( &self, requester: &dyn ServerOutgoing, job_id: JobId, _command: CompileCommand, _outputs: Vec, - _inputs_rdr: InputsReader, + _inputs_rdr: InputsReader<'_>, ) -> Result { requester .do_update_job_state(job_id, JobState::Started) + .await .context("Updating job state failed")?; bail!("internal build failure") } } -#[test] +#[tokio::test] #[cfg_attr(not(feature = "dist-tests"), ignore)] #[serial] -fn test_dist_failingserver() { +async fn test_dist_failingserver() { let tmpdir = tempfile::Builder::new() .prefix("cachepot_dist_test") .tempdir() @@ -204,8 +210,8 @@ fn test_dist_failingserver() { let cachepot_dist = harness::cachepot_dist_path(); let mut system = harness::DistSystem::new(&cachepot_dist, tmpdir); - system.add_scheduler(); - system.add_custom_server(FailingServer); + system.add_scheduler().await; + let handle = system.add_custom_server(FailingServer).await; let cachepot_cfg = dist_test_cachepot_client_cfg(tmpdir, system.scheduler_url()); let cachepot_cfg_path = tmpdir.join("cachepot-cfg.json"); @@ -214,7 +220,7 @@ fn test_dist_failingserver() { stop_local_daemon(); start_local_daemon(&cachepot_cfg_path, &cachepot_cached_cfg_path); - basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path); + basic_compile(tmpdir, &cachepot_cfg_path, &cachepot_cached_cfg_path).await; get_stats(|info| { assert_eq!(0, info.stats.dist_compiles.values().sum::()); @@ -224,4 +230,9 @@ fn test_dist_failingserver() { assert_eq!(0, info.stats.cache_hits.all()); assert_eq!(1, info.stats.cache_misses.all()); }); + stop_local_daemon(); + if let harness::ServerHandle::AsyncTask { handle, url: _ } = handle { + handle.abort(); + let _ = handle.await; + } } diff --git a/tests/harness/mod.rs b/tests/harness/mod.rs index d5a36a9b..dc6422ca 100644 --- a/tests/harness/mod.rs +++ b/tests/harness/mod.rs @@ -5,24 +5,18 @@ use cachepot::server::ServerInfo; use cachepot::util::fs; use std::env; use std::io::Write; -use std::net::{self, IpAddr, SocketAddr}; +use std::net::{IpAddr, SocketAddr}; use std::path::{Path, PathBuf}; use std::process::{Command, Output, Stdio}; use std::str; use std::thread; -use std::time::{Duration, Instant}; +use std::time::Duration; use assert_cmd::prelude::*; -#[cfg(feature = "dist-server")] -use nix::{ - sys::{ - signal::Signal, - wait::{WaitPidFlag, WaitStatus}, - }, - unistd::{ForkResult, Pid}, -}; use predicates::prelude::*; use serde::Serialize; +#[cfg(feature = "dist-server")] +use tokio::task::JoinHandle; use uuid::Uuid; const CONTAINER_NAME_PREFIX: &str = "cachepot_dist_test"; @@ -44,7 +38,7 @@ pub fn start_local_daemon(cfg_path: &Path, cached_cfg_path: &Path) { // Don't run this with run() because on Windows `wait_with_output` // will hang because the internal server process is not detached. trace!("cachepot --start-server"); - cachepot_command() + let _status = cachepot_command() .arg("--start-server") .env("CACHEPOT_CONF", cfg_path) .env("CACHEPOT_CACHED_CONF", cached_cfg_path) @@ -189,8 +183,14 @@ fn create_server_token(server_id: ServerId, auth_token: &str) -> String { #[cfg(feature = "dist-server")] pub enum ServerHandle { - Container { cid: String, url: HTTPUrl }, - Process { pid: Pid, url: HTTPUrl }, + Container { + cid: String, + url: HTTPUrl, + }, + AsyncTask { + handle: JoinHandle<()>, + url: HTTPUrl, + }, } #[cfg(feature = "dist-server")] @@ -200,7 +200,8 @@ pub struct DistSystem { scheduler_name: Option, server_names: Vec, - server_pids: Vec, + server_handles: Vec>, + client: reqwest::Client, } #[cfg(feature = "dist-server")] @@ -226,17 +227,20 @@ impl DistSystem { let tmpdir = tmpdir.join("distsystem"); fs::create_dir(&tmpdir).unwrap(); + let client = native_tls_no_sni_client_builder_danger().build().unwrap(); + Self { cachepot_dist: cachepot_dist.to_owned(), tmpdir, scheduler_name: None, server_names: vec![], - server_pids: vec![], + server_handles: vec![], + client, } } - pub fn add_scheduler(&mut self) { + pub async fn add_scheduler(&mut self) { let scheduler_cfg_relpath = "scheduler-cfg.json"; let scheduler_cfg_path = self.tmpdir.join(scheduler_cfg_relpath); let scheduler_cfg_container_path = @@ -287,29 +291,42 @@ impl DistSystem { check_output(&output); let scheduler_url = self.scheduler_url(); - wait_for_http(scheduler_url, Duration::from_millis(100), MAX_STARTUP_WAIT); - wait_for( - || { + + wait_for_http( + &self.client, + scheduler_url, + Duration::from_millis(100), + MAX_STARTUP_WAIT, + ) + .await; + + let status_fut = async move { + loop { let status = self.scheduler_status(); - if matches!( - status, - SchedulerStatusResult { - num_servers: 0, - num_cpus: _, - in_progress: 0 + + tokio::select! { + s = status => { + if matches!( + s, + SchedulerStatusResult { + num_servers: 0, + num_cpus: _, + in_progress: 0 + } + ) { + break Ok(()); + } else { + } } - ) { - Ok(()) - } else { - Err(format!("{:?}", status)) + _ = tokio::time::sleep(Duration::from_millis(100)) => {} } - }, - Duration::from_millis(100), - MAX_STARTUP_WAIT, - ); + } + }; + + wait_for(status_fut, MAX_STARTUP_WAIT).await; } - pub fn add_server(&mut self) -> ServerHandle { + pub async fn add_server(&mut self) -> ServerHandle { let server_cfg_relpath = format!("server-cfg-{}.json", self.server_names.len()); let server_cfg_path = self.tmpdir.join(&server_cfg_relpath); let server_cfg_container_path = Path::new(CONFIGS_CONTAINER_PATH).join(server_cfg_relpath); @@ -368,43 +385,36 @@ impl DistSystem { cid: server_name, url, }; - self.wait_server_ready(&handle); + self.wait_server_ready(&handle).await; handle } - pub fn add_custom_server( + pub async fn add_custom_server( &mut self, handler: S, ) -> ServerHandle { let server_addr = { let ip = self.host_interface_ip(); - let listener = net::TcpListener::bind(SocketAddr::from((ip, 0))).unwrap(); + let listener = tokio::net::TcpListener::bind(SocketAddr::from((ip, 0))) + .await + .unwrap(); listener.local_addr().unwrap() }; let token = create_server_token(ServerId::new(server_addr), DIST_SERVER_TOKEN); let server = dist::http::Server::new(server_addr, self.scheduler_url().to_url(), token, handler) .unwrap(); - let pid = match unsafe { nix::unistd::fork() }.unwrap() { - ForkResult::Parent { child } => { - self.server_pids.push(child); - child - } - ForkResult::Child => { - env::set_var("RUST_LOG", "cachepot=trace"); - env_logger::try_init().unwrap(); - void::unreachable(server.start().unwrap()) - } - }; + let handle = tokio::spawn(async move { void::unreachable(server.start().await.unwrap()) }); + //self.server_handles.push(handle); let url = HTTPUrl::from_url(reqwest::Url::parse(&format!("https://{}", server_addr)).unwrap()); - let handle = ServerHandle::Process { pid, url }; - self.wait_server_ready(&handle); + let handle = ServerHandle::AsyncTask { handle, url }; + self.wait_server_ready(&handle).await; handle } - pub fn restart_server(&mut self, handle: &ServerHandle) { + pub async fn restart_server(&mut self, handle: &ServerHandle) { match handle { ServerHandle::Container { cid, url: _ } => { let output = Command::new("docker") @@ -413,40 +423,50 @@ impl DistSystem { .unwrap(); check_output(&output); } - ServerHandle::Process { pid: _, url: _ } => { + ServerHandle::AsyncTask { handle: _, url: _ } => { // TODO: pretty easy, just no need yet panic!("restart not yet implemented for pids") } } - self.wait_server_ready(handle) + self.wait_server_ready(handle).await } - pub fn wait_server_ready(&mut self, handle: &ServerHandle) { + pub async fn wait_server_ready(&mut self, handle: &ServerHandle) { let url = match handle { - ServerHandle::Container { cid: _, url } | ServerHandle::Process { pid: _, url } => { - url.clone() - } + ServerHandle::Container { cid: _, url } + | ServerHandle::AsyncTask { handle: _, url } => url.clone(), }; - wait_for_http(url, Duration::from_millis(100), MAX_STARTUP_WAIT); - wait_for( - || { + wait_for_http( + &self.client, + url, + Duration::from_millis(100), + MAX_STARTUP_WAIT, + ) + .await; + let status_fut = async move { + loop { let status = self.scheduler_status(); - if matches!( - status, - SchedulerStatusResult { - num_servers: 1, - num_cpus: _, - in_progress: 0 + + tokio::select! { + s = status => { + if matches!( + s, + SchedulerStatusResult { + num_servers: 1, + num_cpus: _, + in_progress: 0 + } + ) { + break Ok(()); + } else { + } } - ) { - Ok(()) - } else { - Err(format!("{:?}", status)) + _ = tokio::time::sleep(Duration::from_millis(100)) => {} } - }, - Duration::from_millis(100), - MAX_STARTUP_WAIT, - ); + } + }; + + wait_for(status_fut, MAX_STARTUP_WAIT).await; } pub fn scheduler_url(&self) -> HTTPUrl { @@ -455,13 +475,13 @@ impl DistSystem { HTTPUrl::from_url(reqwest::Url::parse(&url).unwrap()) } - fn scheduler_status(&self) -> SchedulerStatusResult { - let res = reqwest::blocking::get(dist::http::urls::scheduler_status( - &self.scheduler_url().to_url(), - )) - .unwrap(); + async fn scheduler_status(&self) -> SchedulerStatusResult { + let url = dist::http::urls::scheduler_status(&self.scheduler_url().to_url()); + let res = self.client.get(url).send().await.unwrap(); assert!(res.status().is_success()); - bincode::deserialize_from(res).unwrap() + let bytes = res.bytes().await.unwrap(); + + bincode::deserialize_from(bytes.as_ref()).unwrap() } fn container_ip(&self, name: &str) -> IpAddr { @@ -519,7 +539,6 @@ impl Drop for DistSystem { let mut logs = vec![]; let mut outputs = vec![]; - let mut exits = vec![]; if let Some(scheduler_name) = self.scheduler_name.as_ref() { droperr!(Command::new("docker") @@ -549,31 +568,9 @@ impl Drop for DistSystem { .output() .map(|o| outputs.push((server_name, o)))); } - for &pid in self.server_pids.iter() { - droperr!(nix::sys::signal::kill(pid, Signal::SIGINT)); - thread::sleep(Duration::from_millis(100)); - let mut killagain = true; // Default to trying to kill again, e.g. if there was an error waiting on the pid - droperr!( - nix::sys::wait::waitpid(pid, Some(WaitPidFlag::WNOHANG)).map(|ws| { - if ws != WaitStatus::StillAlive { - killagain = false; - exits.push(ws) - } - }) - ); - if killagain { - eprintln!("SIGINT didn't kill process, trying SIGKILL"); - droperr!(nix::sys::signal::kill(pid, Signal::SIGKILL)); - droperr!(nix::sys::wait::waitpid(pid, Some(WaitPidFlag::WNOHANG)) - .map_err(|e| e.to_string()) - .and_then(|ws| if ws == WaitStatus::StillAlive { - Err("process alive after sigkill".to_owned()) - } else { - exits.push(ws); - Ok(()) - })); - } - } + // TODO: they will die with the runtime, but correctly waiting for them + // may be only possible when we have async Drop. + for _handle in self.server_handles.iter() {} for ( container, @@ -609,9 +606,6 @@ impl Drop for DistSystem { String::from_utf8_lossy(&stderr) ); } - for exit in exits { - println!("EXIT: {:?}", exit) - } if did_err && !thread::panicking() { panic!("Encountered failures during dist system teardown") @@ -637,34 +631,47 @@ fn check_output(output: &Output) { } #[cfg(feature = "dist-server")] -fn wait_for_http(url: HTTPUrl, interval: Duration, max_wait: Duration) { - // TODO: after upgrading to reqwest >= 0.9, use 'danger_accept_invalid_certs' and stick with that rather than tcp - wait_for( - || { - let url = url.to_url(); - let url = url.socket_addrs(|| None).unwrap(); - match net::TcpStream::connect(url.as_slice()) { - Ok(_) => Ok(()), - Err(e) => Err(e.to_string()), - } - }, - interval, - max_wait, - ) +fn native_tls_no_sni_client_builder_danger() -> reqwest::ClientBuilder { + let tls = native_tls::TlsConnector::builder() + .danger_accept_invalid_certs(true) + .danger_accept_invalid_hostnames(true) + .use_sni(false) + .build() + .unwrap(); + + reqwest::ClientBuilder::new() + .use_native_tls() + .use_preconfigured_tls(tls) } -fn wait_for Result<(), String>>(f: F, interval: Duration, max_wait: Duration) { - let start = Instant::now(); - let mut lasterr; - loop { - match f() { - Ok(()) => return, - Err(e) => lasterr = e, - } - if start.elapsed() > max_wait { - break; +#[cfg(feature = "dist-server")] +async fn wait_for_http( + client: &reqwest::Client, + url: HTTPUrl, + interval: Duration, + max_wait: Duration, +) { + let try_connect = async move { + let url = url.to_url(); + + loop { + match tokio::time::timeout(interval, client.get(url.clone()).send()).await { + Ok(Ok(_)) => { + break; + } + _ => {} + }; } - thread::sleep(interval) + }; + + if let Err(e) = tokio::time::timeout(max_wait, try_connect).await { + panic!("wait timed out, last error result: {}", e) } - panic!("wait timed out, last error result: {}", lasterr) +} + +async fn wait_for>>(f: F, max_wait: Duration) { + tokio::time::timeout(max_wait, f) + .await + .unwrap() + .expect("wait timed out") }