summaryrefslogtreecommitdiff
path: root/vendor/hyper-rustls
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-10 13:11:11 -0600
committermo khan <mo@mokhan.ca>2025-07-10 13:11:11 -0600
commit01959b16a21b22b5df5f16569c2a8e8f92beecef (patch)
tree32afa5d747c5466345c59ec52161a7cba3d6d755 /vendor/hyper-rustls
parentff30574117a996df332e23d1fb6f65259b316b5b (diff)
chore: vendor dependencies
Diffstat (limited to 'vendor/hyper-rustls')
-rw-r--r--vendor/hyper-rustls/.cargo-checksum.json1
-rw-r--r--vendor/hyper-rustls/Cargo.lock1323
-rw-r--r--vendor/hyper-rustls/Cargo.toml171
-rw-r--r--vendor/hyper-rustls/LICENSE10
-rw-r--r--vendor/hyper-rustls/LICENSE-APACHE201
-rw-r--r--vendor/hyper-rustls/LICENSE-ISC15
-rw-r--r--vendor/hyper-rustls/LICENSE-MIT25
-rw-r--r--vendor/hyper-rustls/README.md64
-rw-r--r--vendor/hyper-rustls/RELEASING.md26
-rw-r--r--vendor/hyper-rustls/examples/client.rs105
-rw-r--r--vendor/hyper-rustls/examples/openssl.cnf25
-rwxr-xr-xvendor/hyper-rustls/examples/refresh-certificates.sh56
-rw-r--r--vendor/hyper-rustls/examples/sample.pem79
-rw-r--r--vendor/hyper-rustls/examples/sample.rsa27
-rw-r--r--vendor/hyper-rustls/examples/server.rs138
-rw-r--r--vendor/hyper-rustls/src/config.rs136
-rw-r--r--vendor/hyper-rustls/src/connector.rs296
-rw-r--r--vendor/hyper-rustls/src/connector/builder.rs500
-rw-r--r--vendor/hyper-rustls/src/lib.rs76
-rw-r--r--vendor/hyper-rustls/src/stream.rs121
-rw-r--r--vendor/hyper-rustls/tests/tests.rs102
21 files changed, 3497 insertions, 0 deletions
diff --git a/vendor/hyper-rustls/.cargo-checksum.json b/vendor/hyper-rustls/.cargo-checksum.json
new file mode 100644
index 00000000..ad41ccc2
--- /dev/null
+++ b/vendor/hyper-rustls/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"38200193af24441e4dc8ed8dabbc8c3adbb4f0a49588ac178d5f5072663654a6","Cargo.toml":"d835791214e048ded7c6deddc663b628e7e077daa67ce24fc9843e7999938fd0","LICENSE":"d1ef92123fc699442e1e8d971fe84921947efc8d9a1249ab037f1e661a972a6d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-ISC":"7cfafc877eccc46c0e346ccbaa5c51bb6b894d2b818e617d970211e232785ad4","LICENSE-MIT":"709e3175b4212f7b13aa93971c9f62ff8c69ec45ad8c6532a7e0c41d7a7d6f8c","README.md":"9124a22136f3b0fa82f22896a25989b120bf05be197e0f110cdf408f63aaf5fd","RELEASING.md":"01733c2c7ba9966525a0df69ba0c634d5accdeb3aaca466410134fbd6a8e6c03","examples/client.rs":"79e10c996aac0483109d9495d338570c64e60097c22a73778db0476fea3edd7c","examples/openssl.cnf":"cfa19da355f64e20f0ed90deae3a4cea3fc644bab79955e555b6801d028a81b9","examples/refresh-certificates.sh":"00a421b85e88f794926ce8faf645b1ceeae65029675cf039b3c21d6735dd37ee","examples/sample.pem":"61696c7bd7f3f700d4befb40f5d335adff3f98d8bcf07b76a06387de4faa51e9","examples/sample.rsa":"bca5b33775fffe53d6e4bcdc3d8b33fcfb9cd4cc40bb6e38a0c2761a84c64fcf","examples/server.rs":"024556b773fb46dc084b9aa6c739f2725c5fdacfcf8b94fbb6549b164c9711b6","src/config.rs":"b249782e789e18928fe454f0ac08180256d24adbb3ca40a0cf469ed8ed404df8","src/connector.rs":"d796974eecf557428a0f0dbceaea28b437d91bbfda2d3bf6c89f77157dfc50af","src/connector/builder.rs":"1b5c3424dee4a0fe8d5ae0a1c882b732c209df4892e6756191a06d825e2647c7","src/lib.rs":"4f55e7914274119123eb563033cc7a8bfc2536d9191f8ddd20943e3c44bf90e2","src/stream.rs":"49039649158136eec6e0dec37bb4ab6459fd58cfe821f65b4a578da3e9f4e39a","tests/tests.rs":"f2421455609c402123a040f1699c168e855a3e55ac3c214dd400b00cf824350a"},"package":"e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"} \ No newline at end of file
diff --git a/vendor/hyper-rustls/Cargo.lock b/vendor/hyper-rustls/Cargo.lock
new file mode 100644
index 00000000..abf3cb01
--- /dev/null
+++ b/vendor/hyper-rustls/Cargo.lock
@@ -0,0 +1,1323 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler2"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+[[package]]
+name = "aws-lc-fips-sys"
+version = "0.13.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e99d74bb793a19f542ae870a6edafbc5ecf0bc0ba01d4636b7f7e0aba9ee9bd3"
+dependencies = [
+ "bindgen",
+ "cc",
+ "cmake",
+ "dunce",
+ "fs_extra",
+ "regex",
+]
+
+[[package]]
+name = "aws-lc-rs"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fcc8f365936c834db5514fc45aee5b1202d677e6b40e48468aaaa8183ca8c7"
+dependencies = [
+ "aws-lc-fips-sys",
+ "aws-lc-sys",
+ "zeroize",
+]
+
+[[package]]
+name = "aws-lc-sys"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61b1d86e7705efe1be1b569bab41d4fa1e14e220b60a160f78de2db687add079"
+dependencies = [
+ "bindgen",
+ "cc",
+ "cmake",
+ "dunce",
+ "fs_extra",
+]
+
+[[package]]
+name = "backtrace"
+version = "0.3.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
+dependencies = [
+ "addr2line",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "bindgen"
+version = "0.69.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "itertools",
+ "lazy_static",
+ "lazycell",
+ "log",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "syn",
+ "which",
+]
+
+[[package]]
+name = "bitflags"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+
+[[package]]
+name = "bytes"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+
+[[package]]
+name = "cc"
+version = "1.2.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951"
+dependencies = [
+ "jobserver",
+ "libc",
+ "shlex",
+]
+
+[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clang-sys"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "cmake"
+version = "0.1.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "combine"
+version = "4.6.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
+dependencies = [
+ "bytes",
+ "memchr",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "dunce"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
+
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "errno"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
+dependencies = [
+ "libc",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "fs_extra"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
+]
+
+[[package]]
+name = "gimli"
+version = "0.31.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
+
+[[package]]
+name = "glob"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
+
+[[package]]
+name = "h2"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
+
+[[package]]
+name = "home"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "http"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "smallvec",
+ "tokio",
+ "want",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.27.7"
+dependencies = [
+ "cfg-if",
+ "http",
+ "http-body-util",
+ "hyper",
+ "hyper-util",
+ "log",
+ "rustls",
+ "rustls-native-certs",
+ "rustls-pemfile",
+ "rustls-pki-types",
+ "rustls-platform-verifier",
+ "tokio",
+ "tokio-rustls",
+ "tower-service",
+ "webpki-roots",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "libc",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "itertools"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "jni"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
+dependencies = [
+ "cesu8",
+ "cfg-if",
+ "combine",
+ "jni-sys",
+ "log",
+ "thiserror",
+ "walkdir",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "jni-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
+
+[[package]]
+name = "jobserver"
+version = "0.1.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
+dependencies = [
+ "getrandom 0.3.3",
+ "libc",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "lazycell"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+
+[[package]]
+name = "libc"
+version = "0.2.172"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
+
+[[package]]
+name = "libloading"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
+dependencies = [
+ "cfg-if",
+ "windows-targets 0.53.0",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+
+[[package]]
+name = "log"
+version = "0.4.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
+dependencies = [
+ "adler2",
+]
+
+[[package]]
+name = "mio"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
+dependencies = [
+ "libc",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "object"
+version = "0.36.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "prettyplease"
+version = "0.2.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "5.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[package]]
+name = "ring"
+version = "0.17.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "getrandom 0.2.16",
+ "libc",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustix"
+version = "0.38.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "rustls"
+version = "0.23.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
+dependencies = [
+ "aws-lc-rs",
+ "log",
+ "once_cell",
+ "ring",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3"
+dependencies = [
+ "openssl-probe",
+ "rustls-pki-types",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-platform-verifier"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eda84358ed17f1f354cf4b1909ad346e6c7bc2513e8c40eb08e0157aa13a9070"
+dependencies = [
+ "core-foundation",
+ "core-foundation-sys",
+ "jni",
+ "log",
+ "once_cell",
+ "rustls",
+ "rustls-native-certs",
+ "rustls-platform-verifier-android",
+ "rustls-webpki",
+ "security-framework",
+ "security-framework-sys",
+ "webpki-root-certs",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "rustls-platform-verifier-android"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
+
+[[package]]
+name = "rustls-webpki"
+version = "0.103.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
+dependencies = [
+ "aws-lc-rs",
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
+]
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "schannel"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "security-framework"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
+
+[[package]]
+name = "socket2"
+version = "0.5.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "syn"
+version = "2.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio"
+version = "1.45.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "libc",
+ "mio",
+ "pin-project-lite",
+ "socket2",
+ "tokio-macros",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.26.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
+dependencies = [
+ "rustls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tower-service"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+
+[[package]]
+name = "tracing"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+dependencies = [
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
+[[package]]
+name = "webpki-root-certs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01a83f7e1a9f8712695c03eabe9ed3fbca0feff0152f33f12593e5a6303cb1a4"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "which"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
+dependencies = [
+ "either",
+ "home",
+ "once_cell",
+ "rustix",
+]
+
+[[package]]
+name = "winapi-util"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
+dependencies = [
+ "windows_aarch64_gnullvm 0.53.0",
+ "windows_aarch64_msvc 0.53.0",
+ "windows_i686_gnu 0.53.0",
+ "windows_i686_gnullvm 0.53.0",
+ "windows_i686_msvc 0.53.0",
+ "windows_x86_64_gnu 0.53.0",
+ "windows_x86_64_gnullvm 0.53.0",
+ "windows_x86_64_msvc 0.53.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
+
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
diff --git a/vendor/hyper-rustls/Cargo.toml b/vendor/hyper-rustls/Cargo.toml
new file mode 100644
index 00000000..96b44cdf
--- /dev/null
+++ b/vendor/hyper-rustls/Cargo.toml
@@ -0,0 +1,171 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.71"
+name = "hyper-rustls"
+version = "0.27.7"
+build = false
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
+description = "Rustls+hyper integration for pure rust HTTPS"
+homepage = "https://github.com/rustls/hyper-rustls"
+documentation = "https://docs.rs/hyper-rustls/"
+readme = "README.md"
+license = "Apache-2.0 OR ISC OR MIT"
+repository = "https://github.com/rustls/hyper-rustls"
+
+[package.metadata.docs.rs]
+features = [
+ "http1",
+ "http2",
+ "logging",
+ "native-tokio",
+ "ring",
+ "rustls-platform-verifier",
+ "tls12",
+ "webpki-tokio",
+]
+no-default-features = true
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[features]
+aws-lc-rs = ["rustls/aws_lc_rs"]
+default = [
+ "native-tokio",
+ "http1",
+ "tls12",
+ "logging",
+ "aws-lc-rs",
+]
+fips = [
+ "aws-lc-rs",
+ "rustls/fips",
+]
+http1 = ["hyper-util/http1"]
+http2 = ["hyper-util/http2"]
+logging = [
+ "log",
+ "tokio-rustls/logging",
+ "rustls/logging",
+]
+native-tokio = ["rustls-native-certs"]
+ring = ["rustls/ring"]
+tls12 = [
+ "tokio-rustls/tls12",
+ "rustls/tls12",
+]
+webpki-tokio = ["webpki-roots"]
+
+[lib]
+name = "hyper_rustls"
+path = "src/lib.rs"
+
+[[example]]
+name = "client"
+path = "examples/client.rs"
+required-features = [
+ "native-tokio",
+ "http1",
+]
+
+[[example]]
+name = "server"
+path = "examples/server.rs"
+required-features = ["aws-lc-rs"]
+
+[[test]]
+name = "tests"
+path = "tests/tests.rs"
+
+[dependencies.http]
+version = "1"
+
+[dependencies.hyper]
+version = "1"
+default-features = false
+
+[dependencies.hyper-util]
+version = "0.1"
+features = [
+ "client-legacy",
+ "tokio",
+]
+default-features = false
+
+[dependencies.log]
+version = "0.4.4"
+optional = true
+
+[dependencies.pki-types]
+version = "1"
+package = "rustls-pki-types"
+
+[dependencies.rustls]
+version = "0.23"
+default-features = false
+
+[dependencies.rustls-native-certs]
+version = "0.8"
+optional = true
+
+[dependencies.rustls-platform-verifier]
+version = "0.6"
+optional = true
+
+[dependencies.tokio]
+version = "1.0"
+
+[dependencies.tokio-rustls]
+version = "0.26"
+default-features = false
+
+[dependencies.tower-service]
+version = "0.3"
+
+[dependencies.webpki-roots]
+version = "1"
+optional = true
+
+[dev-dependencies.cfg-if]
+version = "1"
+
+[dev-dependencies.http-body-util]
+version = "0.1"
+
+[dev-dependencies.hyper-util]
+version = "0.1"
+features = ["server-auto"]
+default-features = false
+
+[dev-dependencies.rustls]
+version = "0.23"
+features = ["tls12"]
+default-features = false
+
+[dev-dependencies.rustls-pemfile]
+version = "2"
+
+[dev-dependencies.tokio]
+version = "1.0"
+features = [
+ "io-std",
+ "macros",
+ "net",
+ "rt-multi-thread",
+]
diff --git a/vendor/hyper-rustls/LICENSE b/vendor/hyper-rustls/LICENSE
new file mode 100644
index 00000000..58f1746e
--- /dev/null
+++ b/vendor/hyper-rustls/LICENSE
@@ -0,0 +1,10 @@
+hyper-rustls is distributed under the following three licenses:
+
+- Apache License version 2.0.
+- MIT license.
+- ISC license.
+
+These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC
+respectively. You may use this software under the terms of any
+of these licenses, at your option.
+
diff --git a/vendor/hyper-rustls/LICENSE-APACHE b/vendor/hyper-rustls/LICENSE-APACHE
new file mode 100644
index 00000000..16fe87b0
--- /dev/null
+++ b/vendor/hyper-rustls/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/hyper-rustls/LICENSE-ISC b/vendor/hyper-rustls/LICENSE-ISC
new file mode 100644
index 00000000..03acf1bd
--- /dev/null
+++ b/vendor/hyper-rustls/LICENSE-ISC
@@ -0,0 +1,15 @@
+ISC License (ISC)
+Copyright (c) 2016, Joseph Birr-Pixton <jpixton@gmail.com>
+
+Permission to use, copy, modify, and/or distribute this software for
+any purpose with or without fee is hereby granted, provided that the
+above copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/vendor/hyper-rustls/LICENSE-MIT b/vendor/hyper-rustls/LICENSE-MIT
new file mode 100644
index 00000000..ef480e6f
--- /dev/null
+++ b/vendor/hyper-rustls/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2016 Joseph Birr-Pixton <jpixton@gmail.com>
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/vendor/hyper-rustls/README.md b/vendor/hyper-rustls/README.md
new file mode 100644
index 00000000..047c19ec
--- /dev/null
+++ b/vendor/hyper-rustls/README.md
@@ -0,0 +1,64 @@
+# hyper-rustls
+
+This is an integration between the [Rustls TLS stack](https://github.com/rustls/rustls) and the
+[hyper HTTP library](https://github.com/hyperium/hyper).
+
+[![Build Status](https://github.com/rustls/hyper-rustls/actions/workflows/build.yml/badge.svg)](https://github.com/rustls/hyper-rustls/actions)
+[![Crate](https://img.shields.io/crates/v/hyper-rustls.svg)](https://crates.io/crates/hyper-rustls)
+[![Documentation](https://docs.rs/hyper-rustls/badge.svg)](https://docs.rs/hyper-rustls)
+
+# Release history
+
+Release history can be found [on GitHub](https://github.com/rustls/hyper-rustls/releases).
+
+# License
+
+hyper-rustls is distributed under the following three licenses:
+
+- Apache License version 2.0.
+- MIT license.
+- ISC license.
+
+These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC respectively. You may use this
+software under the terms of any of these licenses, at your option.
+
+## Running examples
+
+### server
+
+```bash
+cargo run --example server
+```
+
+### client
+
+```bash
+cargo run --example client "https://docs.rs/hyper-rustls/latest/hyper_rustls/"
+```
+
+## Crate features
+
+This crate exposes a number of features to add support for different portions of `hyper-util`,
+`rustls`, and other dependencies.
+
+| Feature flag | Enabled by default | Description |
+| ------------ | ------------------ | ----------- |
+| `aws-lc-rs` | **yes** | Enables use of the [AWS-LC][aws-lc-rs] backend for [`rustls`][rustls] |
+| `http1` | **yes** | Enables HTTP/1 support in [`hyper-util`][hyper-util] |
+| `http2` | **no** | Enables HTTP/2 support in [`hyper-util`][hyper-util] |
+| `webpki-tokio` | **no** | Uses a compiled-in set of root certificates trusted by Mozilla (via [`webpki-roots`][webpki-roots]) |
+| `native-tokio` | **yes** | Use the platform's native certificate store at runtime (via [`rustls-native-certs`][rustls-native-certs]) |
+| `rustls-platform-verifier` | **no** | Use the operating system's verifier for certificate verification (via [`rustls-platform-verifier`][rustls-platform-verifier]) |
+| `ring` | **no** | Enables use of the [`ring`][ring] backend for [`rustls`][rustls] |
+| `tls12` | **yes** | Enables support for TLS 1.2 (only TLS 1.3 supported when disabled) |
+| `logging` | **yes** | Enables logging of protocol-level diagnostics and errors via [`log`][log] |
+| `fips` | **no** | Enables support for using a FIPS 140-3 compliant backend via AWS-LC (enables `aws-lc-rs` feature) |
+
+[aws-lc-rs]: https://docs.rs/aws-lc-rs
+[rustls]: https://docs.rs/rustls
+[hyper-util]: https://docs.rs/hyper-util
+[webpki-roots]: https://docs.rs/webpki-roots
+[rustls-native-certs]: https://docs.rs/rustls-native-certs
+[rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier
+[ring]: https://docs.rs/ring
+[log]: https://docs.rs/log
diff --git a/vendor/hyper-rustls/RELEASING.md b/vendor/hyper-rustls/RELEASING.md
new file mode 100644
index 00000000..bcc0a699
--- /dev/null
+++ b/vendor/hyper-rustls/RELEASING.md
@@ -0,0 +1,26 @@
+# Making a hyper-rustls release
+
+This is a checklist for steps to make before/after making a rustls release.
+
+1. Attend to the README.md: this appears on crates.io for the release, and can't be edited after
+ the fact.
+ - Ensure the version has a good set of release notes. Move old release notes to OLDCHANGES.md
+ if this is getting excessively long.
+ - Write the version and date of the release.
+2. Run `cargo update` followed by `cargo outdated`, to check if we have any
+ dependency updates which are not already automatically taken by their semver specs.
+ - If we do, take them if possible with separate commits (but there should've been
+ dependabot PRs submitted for these already.)
+3. Now run `cargo test --all-features` to ensure our tests continue to pass with the
+ updated dependencies.
+4. Update `Cargo.toml` to set the correct version.
+5. Make a commit with the above changes, something like 'Prepare $VERSION'. This
+ should not contain functional changes: just versions numbers, and markdown changes.
+6. Do a dry run: check `cargo publish --dry-run`
+7. Push the above commit. Wait for CI to confirm it as green.
+ - Any red _should_ naturally block the release.
+ - If rustc nightly is broken, this _may_ be acceptable if the reason is understood
+ and does not point to a defect.
+8. Tag the released version: `git tag -m '0.20.0' v/0.20.0`
+9. Push the tag: `git push --tags`
+10. Do the release: `cargo publish`.
diff --git a/vendor/hyper-rustls/examples/client.rs b/vendor/hyper-rustls/examples/client.rs
new file mode 100644
index 00000000..c45bc2a7
--- /dev/null
+++ b/vendor/hyper-rustls/examples/client.rs
@@ -0,0 +1,105 @@
+//! Simple HTTPS GET client based on hyper-rustls
+//!
+//! First parameter is the mandatory URL to GET.
+//! Second parameter is an optional path to CA store.
+use http::Uri;
+use http_body_util::{BodyExt, Empty};
+use hyper::body::Bytes;
+use hyper_rustls::ConfigBuilderExt;
+use hyper_util::{client::legacy::Client, rt::TokioExecutor};
+use rustls::RootCertStore;
+
+use std::str::FromStr;
+use std::{env, fs, io};
+
+fn main() {
+ // Send GET request and inspect result, with proper error handling.
+ if let Err(e) = run_client() {
+ eprintln!("FAILED: {}", e);
+ std::process::exit(1);
+ }
+}
+
+fn error(err: String) -> io::Error {
+ io::Error::new(io::ErrorKind::Other, err)
+}
+
+#[tokio::main]
+async fn run_client() -> io::Result<()> {
+ // Set a process wide default crypto provider.
+ #[cfg(feature = "ring")]
+ let _ = rustls::crypto::ring::default_provider().install_default();
+ #[cfg(feature = "aws-lc-rs")]
+ let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
+
+ // First parameter is target URL (mandatory).
+ let url = match env::args().nth(1) {
+ Some(ref url) => Uri::from_str(url).map_err(|e| error(format!("{}", e)))?,
+ None => {
+ println!("Usage: client <url> <ca_store>");
+ return Ok(());
+ }
+ };
+
+ // Second parameter is custom Root-CA store (optional, defaults to native cert store).
+ let mut ca = match env::args().nth(2) {
+ Some(ref path) => {
+ let f = fs::File::open(path)
+ .map_err(|e| error(format!("failed to open {}: {}", path, e)))?;
+ let rd = io::BufReader::new(f);
+ Some(rd)
+ }
+ None => None,
+ };
+
+ // Prepare the TLS client config
+ let tls = match ca {
+ Some(ref mut rd) => {
+ // Read trust roots
+ let certs = rustls_pemfile::certs(rd).collect::<Result<Vec<_>, _>>()?;
+ let mut roots = RootCertStore::empty();
+ roots.add_parsable_certificates(certs);
+ // TLS client config using the custom CA store for lookups
+ rustls::ClientConfig::builder()
+ .with_root_certificates(roots)
+ .with_no_client_auth()
+ }
+ // Default TLS client config with native roots
+ None => rustls::ClientConfig::builder()
+ .with_native_roots()?
+ .with_no_client_auth(),
+ };
+ // Prepare the HTTPS connector
+ let https = hyper_rustls::HttpsConnectorBuilder::new()
+ .with_tls_config(tls)
+ .https_or_http()
+ .enable_http1()
+ .build();
+
+ // Build the hyper client from the HTTPS connector.
+ let client: Client<_, Empty<Bytes>> = Client::builder(TokioExecutor::new()).build(https);
+
+ // Prepare a chain of futures which sends a GET request, inspects
+ // the returned headers, collects the whole body and prints it to
+ // stdout.
+ let fut = async move {
+ let res = client
+ .get(url)
+ .await
+ .map_err(|e| error(format!("Could not get: {:?}", e)))?;
+ println!("Status:\n{}", res.status());
+ println!("Headers:\n{:#?}", res.headers());
+
+ let body = res
+ .into_body()
+ .collect()
+ .await
+ .map_err(|e| error(format!("Could not get body: {:?}", e)))?
+ .to_bytes();
+ println!("Body:\n{}", String::from_utf8_lossy(&body));
+
+ Ok(())
+ };
+
+ fut.await
+}
diff --git a/vendor/hyper-rustls/examples/openssl.cnf b/vendor/hyper-rustls/examples/openssl.cnf
new file mode 100644
index 00000000..cda95b5a
--- /dev/null
+++ b/vendor/hyper-rustls/examples/openssl.cnf
@@ -0,0 +1,25 @@
+
+[ v3_end ]
+basicConstraints = critical,CA:false
+keyUsage = nonRepudiation, digitalSignature
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+subjectAltName = @alt_names
+
+[ v3_client ]
+basicConstraints = critical,CA:false
+keyUsage = nonRepudiation, digitalSignature
+extendedKeyUsage = critical, clientAuth
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+
+[ v3_inter ]
+subjectKeyIdentifier = hash
+extendedKeyUsage = critical, serverAuth, clientAuth
+basicConstraints = CA:true
+keyUsage = cRLSign, keyCertSign, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign
+
+[ alt_names ]
+DNS.1 = testserver.com
+DNS.2 = second.testserver.com
+DNS.3 = localhost
diff --git a/vendor/hyper-rustls/examples/refresh-certificates.sh b/vendor/hyper-rustls/examples/refresh-certificates.sh
new file mode 100755
index 00000000..db98af73
--- /dev/null
+++ b/vendor/hyper-rustls/examples/refresh-certificates.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+set -xe
+
+openssl req -nodes \
+ -x509 \
+ -days 3650 \
+ -newkey rsa:4096 \
+ -keyout ca.key \
+ -out ca.cert \
+ -sha256 \
+ -batch \
+ -subj "/CN=ponytown RSA CA"
+
+openssl req -nodes \
+ -newkey rsa:3072 \
+ -keyout inter.key \
+ -out inter.req \
+ -sha256 \
+ -batch \
+ -subj "/CN=ponytown RSA level 2 intermediate"
+
+openssl req -nodes \
+ -newkey rsa:2048 \
+ -keyout end.key \
+ -out end.req \
+ -sha256 \
+ -batch \
+ -subj "/CN=testserver.com"
+
+openssl rsa \
+ -in end.key \
+ -out sample.rsa
+
+openssl x509 -req \
+ -in inter.req \
+ -out inter.cert \
+ -CA ca.cert \
+ -CAkey ca.key \
+ -sha256 \
+ -days 3650 \
+ -set_serial 123 \
+ -extensions v3_inter -extfile openssl.cnf
+
+openssl x509 -req \
+ -in end.req \
+ -out end.cert \
+ -CA inter.cert \
+ -CAkey inter.key \
+ -sha256 \
+ -days 2000 \
+ -set_serial 456 \
+ -extensions v3_end -extfile openssl.cnf
+
+cat end.cert inter.cert ca.cert > sample.pem
+rm *.key *.cert *.req
diff --git a/vendor/hyper-rustls/examples/sample.pem b/vendor/hyper-rustls/examples/sample.pem
new file mode 100644
index 00000000..50b24b45
--- /dev/null
+++ b/vendor/hyper-rustls/examples/sample.pem
@@ -0,0 +1,79 @@
+-----BEGIN CERTIFICATE-----
+MIIEADCCAmigAwIBAgICAcgwDQYJKoZIhvcNAQELBQAwLDEqMCgGA1UEAwwhcG9u
+eXRvd24gUlNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMB4XDTIyMDcwNDE0MzA1OFoX
+DTI3MTIyNTE0MzA1OFowGTEXMBUGA1UEAwwOdGVzdHNlcnZlci5jb20wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDL35qLQLIqswCmHJxyczYF2p0YxXCq
+gMvtRcKVElnifPMFrbGCY1aYBmhIiXPGRwhfythAtYfDQsrXFADZd52JPgZCR/u6
+DQMqKD2lcvFQkf7Kee/fNTOuQTQPh1XQx4ntxvicSATwEnuU28NwVnOU//Zzq2xn
+Q34gUQNHWp1pN+B1La7emm/Ucgs1/2hMxwCZYUnRoiUoRGXUSzZuWokDOstPNkjc
++AjHmxONgowogmL2jKN9BjBw/8psGoqEOjMO+Lb9iekOCzX4kqHaRUbTlbSAviQu
+2Q115xiZCBCZVtNE6DUG25buvpMSEXwpLd96nLywbrSCyueC7cd01/hpAgMBAAGj
+gb4wgbswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFHGnzC5Q
+A62Wmv4zfMk/kf/BxHevMEIGA1UdIwQ7MDmAFDMRUvwxXbYDBCxOdQ9xfBnNWUz0
+oR6kHDAaMRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0GCAXswOwYDVR0RBDQwMoIO
+dGVzdHNlcnZlci5jb22CFXNlY29uZC50ZXN0c2VydmVyLmNvbYIJbG9jYWxob3N0
+MA0GCSqGSIb3DQEBCwUAA4IBgQBqKNIM/JBGRmGEopm5/WNKV8UoxKPA+2jR020t
+RumXMAnJEfhsivF+Zw/rDmSDpmts/3cIlesKi47f13q4Mfj1QytQUDrsuQEyRTrV
+Go6BOQQ4dkS+IqnIfSuue70wpvrZHhRHNFdFt9qM5wCLQokXlP988sEWUmyPPCbO
+1BEpwWcP1kx+PdY8NKOhMnfq2RfluI/m4MA4NxJqAWajAhIbDNbvP8Ov4a71HPa6
+b1q9qIQE1ut8KycTrm9K32bVbvMHvR/TPUue8W0VvV2rWTGol5TSNgEQb9w6Kyf7
+N5HlRl9kZB4K8ckWH/JVn0pYNBQPgwbcUbJ/jp6w+LHrh+UW75maOY+IGjVICud8
+6Rc5DZZ2+AAbXJQZ1HMPrw9SW/16Eh/A4CIEsvbu9J+7IoSzhgcKFzOCUojzzRSj
+iU7w/HsvpltmVCAZcZ/VARFbe1By2wXX2GSw2p2FVC8orXs76QyruPAVgSHCTVes
+zzBo6GLScO/3b6uAcPM3MHRGGvE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEnzCCAoegAwIBAgIBezANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9wb255
+dG93biBSU0EgQ0EwHhcNMjIwNzA0MTQzMDU4WhcNMzIwNzAxMTQzMDU4WjAsMSow
+KAYDVQQDDCFwb255dG93biBSU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwggGiMA0G
+CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCsTkd2SKiy3yy20lygOhKfOySo3qpq
+TZVrpW11vQ58+6EcetXRnzIIK0HyhPmZrv9XKPpQclJvfY9jADNtu2CSj/v15OSB
+Love3GzmXSZz2A8QUZBPWx6HczDG1hFGzrCZPKzpeLnFD1LPsKCUkUOHl1acyy24
+DaCacQJPzPQWbMhbGmYRlDNb+2R2K6UKMAEVe4IOTv2aSIKDGLI+xlaBXYAJj48L
+//9eNmR3bMP3kkNKOKaaBk8vnYxKpZ+8ZHeHTmYWR9x1ZoMcbA9lKUwRpKAjY5JJ
+NVZMDmjlVQVvvBrvhgz/zgXtfuaQCryZ0f1sEY/zXhdealo3fGVomeoniD4XwA1c
+oaUFkbo5IM5HU/pXyAGRerDyhYLgRqQZMIRauvKRPN3jLsPOEQ0+gnXUUTr/YGIE
+KY3/Axg4P3hzZCFqJ5IgkgWZr/dKr9p/0cxSUGHTVcpEFOlkKIIIdRuR7Ng5sJml
+u7PAMWt6T+x02ORs1/WkyP7LyPQmuugYTicCAwEAAaNeMFwwHQYDVR0OBBYEFDMR
+UvwxXbYDBCxOdQ9xfBnNWUz0MCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEF
+BQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jANBgkqhkiG9w0BAQsFAAOC
+AgEAYzqmX+cNPgVD2HWgbeimUraTpI9JP5P4TbOHWmaJKecoy3Hwr71xyAOGiVXL
+urk1ZZe8n++GwuDEgRajN3HO9LR1Pu9qVIzTYIsz0ORRQHxujnF7CxK/I/vrIgde
+pddUdHNS0Y0g8J1emH9BgoD8a2YsGX4iDY4S4hIGBbGvQp9z8U/uG1mViAmlXybM
+b8bf0dx0tEFUyu8jsQP6nFLY/HhkEcvU6SnOzZHRsFko6NE44VIsHLd2+LS2LCM/
+NfAoTzgvj41M3zQCZapaHZc9KXfdcCvEFaySKGfEZeQTUR5W0FHsF5I4NLGryf5L
+h3ENQ1tgBTO5WnqL/5rbgv6va9VionPM5sbEwAcancejnkVs3NoYPIPPgBFjaFmL
+hNTpT9H2owdZvEwNDChVS0b8ukNNd4cERtvy0Ohc3mk0LGN0ABzrud0fIqa51LMh
+0N3dkPkiZ4XYk4yLJ5EwCrCNNH50QkGCOWpInKIPeSYcALGgBDbCDLv6rV3oSKrV
+tHCZQwXVKKgU4AQu7hlHBwJ61cH44ksydOidW3MNq1kDIp7ST8s7gVrItNgFnG+L
+Jpo270riwSUlWDY4hXw5Ff5lE+bWCmFyyOkLevDkD9v8M4HdwEVvafYYwn75fCIS
+5OnpSeIB08kKqCtW1WBwki0rYJjWqdzI7Z1MQ/AyScAKiGM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEsDCCApgCCQCfkxy3a+AgNjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9w
+b255dG93biBSU0EgQ0EwHhcNMjIwNzA0MTQzMDU3WhcNMzIwNzAxMTQzMDU3WjAa
+MRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQCj6nW8pnN50UsH2NjL97xZKxlXPe5ptXfvqXczMsw0vB3gI4xJ
+Tdmrnqo0K+VOH7vh+UXcOj2ZMY2ou6oDDK5Qpu9bvGPBIJH/rC1Ti2+u5Y4KTIUc
+jWAtzQJeFn8+oCMfskpLdtlWLRdAuwqNHjvxXdd2JnsX1Wid85U/rG2SNPLGjJAF
+xG7xzZC4VSO2WIXTGRMUkZfFc8fhWMjo3GaeF/qYjzfHDPWN/ll/7vfxyXJO/ohw
+FzpJSZtKmI+6PLxqB/oFrKfTDQUGzxjfHp187bI3eyUFMJsp18/tLYkLyxSWIg3o
+bq7ZVimHd1UG2Vb5Y+5pZkh22jmJ6bAa/kmNNwbsD+5vJhW1myGhmZSxkreYPWnS
+6ELrSMvbXccFfTYmdBlWsZx/zUVUzVCPe9jdJki2VXlicohqtvBQqe6LGGO37vvv
+Gwu1yzQ/rJy47rnaao7fSxqM8nsDjNR2Ev1v031QpEMWjfgUW0roW3H58RZSx+kU
+gzIS2CjJIqKxCp894FUQbC6r0wwAuKltl3ywz5qWkxY0O9bXS0YdEXiri5pdsWjr
+84shVVQwnoVD9539CLSdHZjlOCAzvSWHZH6ta2JZjUfYYz8cLyv2c2+y9BYrlvHw
+T7U7BqzngUk72gcRXd5+Onp+16gGxpGJqaxqj94Nh/yTUnr2Jd9YaXeFmQIDAQAB
+MA0GCSqGSIb3DQEBCwUAA4ICAQBzIRVRt3Yaw60tpkyz/i1xbKCbtC+HqYTEsXvZ
+RvZ5X1qyLAcmu4EW9RHXnlLiawDbES6lCMFfdBUK03Wis7socvoFUCBRW337F4z2
+IivHfIge4u+w5ouUKPzcpj6oeuR06tmNytYbno6l8tXJpm1eeO4KNZ0ZtodmyB5D
+yLrplFgxTdGGgyvxt8LoeLwGmPCyVt35x/Mz6x2lcq1+r7QJZ9sENhQYuA8UqHrw
+fmNoVIMXMEcPLcWtFl6nKTK9LrqAu1jgTBqGGZKRn5CYBBK3pNEGKiOIsZXDbyFS
+F59teFpJjyeJTbUbLxXDa15J6ExkHV9wFLEvfu/nzQzg8D9yzczSdbDkE2rrrL+s
+Q/H/pIXO/DesCWQ37VALn3B5gm9UBd5uogbSw8eamiwRFLQ0snP80pJQGJoTNn0P
+wrLLUf2gsKC2262igiA+imepm5wxbV9XGVZfHJgxCi5Zqrf6aWnjIqD2YtDvAHhs
+V8ZWN3QTjdnEcQbG0544rocoLNX/FzmyDgjfZKY5r6wt+FWNc/R4clkF+KxasxqB
+HdBs8j0lGV3ujvNXASLq9HI6VxZayrSfkR73hADCXIM/wzynKwMarvA4SXwYX9Pd
+cJ4+FMqrevPpamMHUsNndS0KfDTdjDp+TSBf87yiyRkD1Ri4ePslyfNvRyv3Xs7k
+47YFzA==
+-----END CERTIFICATE-----
diff --git a/vendor/hyper-rustls/examples/sample.rsa b/vendor/hyper-rustls/examples/sample.rsa
new file mode 100644
index 00000000..aec53472
--- /dev/null
+++ b/vendor/hyper-rustls/examples/sample.rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAy9+ai0CyKrMAphyccnM2BdqdGMVwqoDL7UXClRJZ4nzzBa2x
+gmNWmAZoSIlzxkcIX8rYQLWHw0LK1xQA2XediT4GQkf7ug0DKig9pXLxUJH+ynnv
+3zUzrkE0D4dV0MeJ7cb4nEgE8BJ7lNvDcFZzlP/2c6tsZ0N+IFEDR1qdaTfgdS2u
+3ppv1HILNf9oTMcAmWFJ0aIlKERl1Es2blqJAzrLTzZI3PgIx5sTjYKMKIJi9oyj
+fQYwcP/KbBqKhDozDvi2/YnpDgs1+JKh2kVG05W0gL4kLtkNdecYmQgQmVbTROg1
+BtuW7r6TEhF8KS3fepy8sG60gsrngu3HdNf4aQIDAQABAoIBAFTehqVFj2W7EqAT
+9QSn9WtGcHNpbddsunfRvIj2FLj2LuzEO8r9s4Sh1jOsFKgL1e6asJ9vck7UtUAH
+sbrV0pzZVx2sfZwb4p9gFRmU2eQigqCjVjnjGdqGhjeYrR62kjKLy96zFGskJpH3
+UkqnkoIKc/v+9qeeLxkg4G6JyFGOFHJAZEraxoGydJk9n/yBEZ/+3W7JUJaGOUNU
+M7BYsCS2VOJr+cCqmCk1j8NvYvWWxTPsIXgGJl4EOoskzlzJnYLdh9fPFZu3uOIx
+hpm3DBNp6X+qXf1lmx9EdpyeXKpLFIgJM7+nw2uWzxW7XMlRERi+5Tprc/pjrqUq
+gpfyvMkCgYEA909QcJpS3qHoWyxGbI1zosVIZXdnj8L+GF/2kEQEU5iEYT+2M1U+
+gCPLr49gNwkD1FdBSCy+Fw20zi35jGmxNwhgp4V94CGYzqwQzpnvgIRBMiAIoEwI
+CD5/t34DZ/82u8Gb7UYVrzOD54rJ628Q+tJEJak3TqoShbvcxJC/rXMCgYEA0wmO
+SRoxrBE3rFzNQkqHbMHLe9LksW9YSIXdMBjq4DhzQEwI0YgPLajXnsLurqHaJrQA
+JPtYkqiJkV7rvJLBo5wxwU+O2JKKa2jcMwuCZ4hOg5oBfK6ES9QJZUL7kDe2vsWy
+rL+rnxJheUjDPBTopGHuuc9Nogid35CE0wy7S7MCgYArxB+KLeVofOKv79/uqgHC
+1oL/Yegz6uAo1CLAWSki2iTjSPEnmHhdGPic8xSl6LSCyYZGDZT+Y3CR5FT7YmD4
+SkVAoEEsfwWZ3Z2D0n4uEjmvczfTlmD9hIH5qRVVPDcldxfvH64KuWUofslJHvi0
+Sq3AtHeTNknc3Ogu6SbivQKBgQC4ZAsMWHS6MTkBwvwdRd1Z62INyNDFL9JlW4FN
+uxfN3cTlkwnJeiY48OOk9hFySDzBwFi3910Gl3fLqrIyy8+hUqIuk4LuO+vxuWdc
+uluwdmqTlgZimGFDl/q1nXcMJYHo4fgh9D7R+E9ul2Luph43MtJRS447W2gFpNJJ
+TUCA/QKBgQC07GFP2BN74UvL12f+FpZvE/UFtWnSZ8yJSq8oYpIbhmoF5EUF+XdA
+E2y3l1cvmDJFo4RNZl+IQIbHACR3y1XOnh4/B9fMEsVQHK3x8exPk1vAk687bBG8
+TVDmdP52XEKHplcVoYKvGzw/wsObLAGyIbJ00t1VPU+7guTPsc+H/w==
+-----END RSA PRIVATE KEY-----
diff --git a/vendor/hyper-rustls/examples/server.rs b/vendor/hyper-rustls/examples/server.rs
new file mode 100644
index 00000000..8f7803fa
--- /dev/null
+++ b/vendor/hyper-rustls/examples/server.rs
@@ -0,0 +1,138 @@
+//! Simple HTTPS echo service based on hyper_util and rustls
+//!
+//! First parameter is the mandatory port to use.
+//! Certificate and private key are hardcoded to sample files.
+//! hyper will automatically use HTTP/2 if a client starts talking HTTP/2,
+//! otherwise HTTP/1.1 will be used.
+
+use std::net::{Ipv4Addr, SocketAddr};
+use std::sync::Arc;
+use std::{env, fs, io};
+
+use http::{Method, Request, Response, StatusCode};
+use http_body_util::{BodyExt, Full};
+use hyper::body::{Bytes, Incoming};
+use hyper::service::service_fn;
+use hyper_util::rt::{TokioExecutor, TokioIo};
+use hyper_util::server::conn::auto::Builder;
+use pki_types::{CertificateDer, PrivateKeyDer};
+use rustls::ServerConfig;
+use tokio::net::TcpListener;
+use tokio_rustls::TlsAcceptor;
+
+fn main() {
+ // Serve an echo service over HTTPS, with proper error handling.
+ if let Err(e) = run_server() {
+ eprintln!("FAILED: {}", e);
+ std::process::exit(1);
+ }
+}
+
+fn error(err: String) -> io::Error {
+ io::Error::new(io::ErrorKind::Other, err)
+}
+
+#[tokio::main]
+async fn run_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
+ // Set a process wide default crypto provider.
+ #[cfg(feature = "ring")]
+ let _ = rustls::crypto::ring::default_provider().install_default();
+ #[cfg(feature = "aws-lc-rs")]
+ let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
+
+ // First parameter is port number (optional, defaults to 1337)
+ let port = match env::args().nth(1) {
+ Some(ref p) => p.parse()?,
+ None => 1337,
+ };
+ let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port);
+
+ // Load public certificate.
+ let certs = load_certs("examples/sample.pem")?;
+ // Load private key.
+ let key = load_private_key("examples/sample.rsa")?;
+
+ println!("Starting to serve on https://{}", addr);
+
+ // Create a TCP listener via tokio.
+ let incoming = TcpListener::bind(&addr).await?;
+
+ // Build TLS configuration.
+ let mut server_config = ServerConfig::builder()
+ .with_no_client_auth()
+ .with_single_cert(certs, key)
+ .map_err(|e| error(e.to_string()))?;
+ server_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()];
+ let tls_acceptor = TlsAcceptor::from(Arc::new(server_config));
+
+ let service = service_fn(echo);
+
+ loop {
+ let (tcp_stream, _remote_addr) = incoming.accept().await?;
+
+ let tls_acceptor = tls_acceptor.clone();
+ tokio::spawn(async move {
+ let tls_stream = match tls_acceptor.accept(tcp_stream).await {
+ Ok(tls_stream) => tls_stream,
+ Err(err) => {
+ eprintln!("failed to perform tls handshake: {err:#}");
+ return;
+ }
+ };
+ if let Err(err) = Builder::new(TokioExecutor::new())
+ .serve_connection(TokioIo::new(tls_stream), service)
+ .await
+ {
+ eprintln!("failed to serve connection: {err:#}");
+ }
+ });
+ }
+}
+
+// Custom echo service, handling two different routes and a
+// catch-all 404 responder.
+async fn echo(req: Request<Incoming>) -> Result<Response<Full<Bytes>>, hyper::Error> {
+ let mut response = Response::new(Full::default());
+ match (req.method(), req.uri().path()) {
+ // Help route.
+ (&Method::GET, "/") => {
+ *response.body_mut() = Full::from("Try POST /echo\n");
+ }
+ // Echo service route.
+ (&Method::POST, "/echo") => {
+ *response.body_mut() = Full::from(
+ req.into_body()
+ .collect()
+ .await?
+ .to_bytes(),
+ );
+ }
+ // Catch-all 404.
+ _ => {
+ *response.status_mut() = StatusCode::NOT_FOUND;
+ }
+ };
+ Ok(response)
+}
+
+// Load public certificate from file.
+fn load_certs(filename: &str) -> io::Result<Vec<CertificateDer<'static>>> {
+ // Open certificate file.
+ let certfile = fs::File::open(filename)
+ .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?;
+ let mut reader = io::BufReader::new(certfile);
+
+ // Load and return certificate.
+ rustls_pemfile::certs(&mut reader).collect()
+}
+
+// Load private key from file.
+fn load_private_key(filename: &str) -> io::Result<PrivateKeyDer<'static>> {
+ // Open keyfile.
+ let keyfile = fs::File::open(filename)
+ .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?;
+ let mut reader = io::BufReader::new(keyfile);
+
+ // Load and return a single private key.
+ rustls_pemfile::private_key(&mut reader).map(|key| key.unwrap())
+}
diff --git a/vendor/hyper-rustls/src/config.rs b/vendor/hyper-rustls/src/config.rs
new file mode 100644
index 00000000..38382617
--- /dev/null
+++ b/vendor/hyper-rustls/src/config.rs
@@ -0,0 +1,136 @@
+#[cfg(feature = "rustls-native-certs")]
+use std::io;
+
+#[cfg(any(
+ feature = "rustls-platform-verifier",
+ feature = "rustls-native-certs",
+ feature = "webpki-roots"
+))]
+use rustls::client::WantsClientCert;
+use rustls::{ClientConfig, ConfigBuilder, WantsVerifier};
+#[cfg(feature = "rustls-native-certs")]
+use rustls_native_certs::CertificateResult;
+#[cfg(feature = "rustls-platform-verifier")]
+use rustls_platform_verifier::BuilderVerifierExt;
+
+/// Methods for configuring roots
+///
+/// This adds methods (gated by crate features) for easily configuring
+/// TLS server roots a rustls ClientConfig will trust.
+pub trait ConfigBuilderExt: sealed::Sealed {
+ /// Use the platform's native verifier to verify server certificates.
+ ///
+ /// See the documentation for [rustls-platform-verifier] for more details.
+ ///
+ /// # Panics
+ ///
+ /// Since 0.27.7, this method will panic if the platform verifier cannot be initialized.
+ /// Use `try_with_platform_verifier()` instead to handle errors gracefully.
+ ///
+ /// [rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier
+ #[deprecated(since = "0.27.7", note = "use `try_with_platform_verifier` instead")]
+ #[cfg(feature = "rustls-platform-verifier")]
+ fn with_platform_verifier(self) -> ConfigBuilder<ClientConfig, WantsClientCert>;
+
+ /// Use the platform's native verifier to verify server certificates.
+ ///
+ /// See the documentation for [rustls-platform-verifier] for more details.
+ ///
+ /// [rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier
+ #[cfg(feature = "rustls-platform-verifier")]
+ fn try_with_platform_verifier(
+ self,
+ ) -> Result<ConfigBuilder<ClientConfig, WantsClientCert>, rustls::Error>;
+
+ /// This configures the platform's trusted certs, as implemented by
+ /// rustls-native-certs
+ ///
+ /// This will return an error if no valid certs were found. In that case,
+ /// it's recommended to use `with_webpki_roots`.
+ #[cfg(feature = "rustls-native-certs")]
+ fn with_native_roots(self) -> Result<ConfigBuilder<ClientConfig, WantsClientCert>, io::Error>;
+
+ /// This configures the webpki roots, which are Mozilla's set of
+ /// trusted roots as packaged by webpki-roots.
+ #[cfg(feature = "webpki-roots")]
+ fn with_webpki_roots(self) -> ConfigBuilder<ClientConfig, WantsClientCert>;
+}
+
+impl ConfigBuilderExt for ConfigBuilder<ClientConfig, WantsVerifier> {
+ #[cfg(feature = "rustls-platform-verifier")]
+ fn with_platform_verifier(self) -> ConfigBuilder<ClientConfig, WantsClientCert> {
+ self.try_with_platform_verifier()
+ .expect("failure to initialize platform verifier")
+ }
+
+ #[cfg(feature = "rustls-platform-verifier")]
+ fn try_with_platform_verifier(
+ self,
+ ) -> Result<ConfigBuilder<ClientConfig, WantsClientCert>, rustls::Error> {
+ BuilderVerifierExt::with_platform_verifier(self)
+ }
+
+ #[cfg(feature = "rustls-native-certs")]
+ #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
+ fn with_native_roots(self) -> Result<ConfigBuilder<ClientConfig, WantsClientCert>, io::Error> {
+ let mut roots = rustls::RootCertStore::empty();
+ let mut valid_count = 0;
+ let mut invalid_count = 0;
+
+ let CertificateResult { certs, errors, .. } = rustls_native_certs::load_native_certs();
+ if !errors.is_empty() {
+ crate::log::warn!("native root CA certificate loading errors: {errors:?}");
+ }
+
+ if certs.is_empty() {
+ return Err(io::Error::new(
+ io::ErrorKind::NotFound,
+ format!("no native root CA certificates found (errors: {errors:?})"),
+ ));
+ }
+
+ for cert in certs {
+ match roots.add(cert) {
+ Ok(_) => valid_count += 1,
+ Err(err) => {
+ crate::log::debug!("certificate parsing failed: {:?}", err);
+ invalid_count += 1
+ }
+ }
+ }
+
+ crate::log::debug!(
+ "with_native_roots processed {} valid and {} invalid certs",
+ valid_count,
+ invalid_count
+ );
+ if roots.is_empty() {
+ crate::log::debug!("no valid native root CA certificates found");
+ Err(io::Error::new(
+ io::ErrorKind::NotFound,
+ format!("no valid native root CA certificates found ({invalid_count} invalid)"),
+ ))?
+ }
+
+ Ok(self.with_root_certificates(roots))
+ }
+
+ #[cfg(feature = "webpki-roots")]
+ fn with_webpki_roots(self) -> ConfigBuilder<ClientConfig, WantsClientCert> {
+ let mut roots = rustls::RootCertStore::empty();
+ roots.extend(
+ webpki_roots::TLS_SERVER_ROOTS
+ .iter()
+ .cloned(),
+ );
+ self.with_root_certificates(roots)
+ }
+}
+
+mod sealed {
+ use super::*;
+
+ pub trait Sealed {}
+
+ impl Sealed for ConfigBuilder<ClientConfig, WantsVerifier> {}
+}
diff --git a/vendor/hyper-rustls/src/connector.rs b/vendor/hyper-rustls/src/connector.rs
new file mode 100644
index 00000000..f8abe457
--- /dev/null
+++ b/vendor/hyper-rustls/src/connector.rs
@@ -0,0 +1,296 @@
+use std::future::Future;
+use std::pin::Pin;
+use std::sync::Arc;
+use std::task::{Context, Poll};
+use std::{fmt, io};
+
+use http::Uri;
+use hyper::rt;
+use hyper_util::client::legacy::connect::Connection;
+use hyper_util::rt::TokioIo;
+use pki_types::ServerName;
+use tokio_rustls::TlsConnector;
+use tower_service::Service;
+
+use crate::stream::MaybeHttpsStream;
+
+pub(crate) mod builder;
+
+type BoxError = Box<dyn std::error::Error + Send + Sync>;
+
+/// A Connector for the `https` scheme.
+#[derive(Clone)]
+pub struct HttpsConnector<T> {
+ force_https: bool,
+ http: T,
+ tls_config: Arc<rustls::ClientConfig>,
+ server_name_resolver: Arc<dyn ResolveServerName + Sync + Send>,
+}
+
+impl<T> HttpsConnector<T> {
+ /// Creates a [`crate::HttpsConnectorBuilder`] to configure a `HttpsConnector`.
+ ///
+ /// This is the same as [`crate::HttpsConnectorBuilder::new()`].
+ pub fn builder() -> builder::ConnectorBuilder<builder::WantsTlsConfig> {
+ builder::ConnectorBuilder::new()
+ }
+
+ /// Force the use of HTTPS when connecting.
+ ///
+ /// If a URL is not `https` when connecting, an error is returned.
+ pub fn enforce_https(&mut self) {
+ self.force_https = true;
+ }
+}
+
+impl<T> Service<Uri> for HttpsConnector<T>
+where
+ T: Service<Uri>,
+ T::Response: Connection + rt::Read + rt::Write + Send + Unpin + 'static,
+ T::Future: Send + 'static,
+ T::Error: Into<BoxError>,
+{
+ type Response = MaybeHttpsStream<T::Response>;
+ type Error = BoxError;
+
+ #[allow(clippy::type_complexity)]
+ type Future =
+ Pin<Box<dyn Future<Output = Result<MaybeHttpsStream<T::Response>, BoxError>> + Send>>;
+
+ fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+ match self.http.poll_ready(cx) {
+ Poll::Ready(Ok(())) => Poll::Ready(Ok(())),
+ Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())),
+ Poll::Pending => Poll::Pending,
+ }
+ }
+
+ fn call(&mut self, dst: Uri) -> Self::Future {
+ // dst.scheme() would need to derive Eq to be matchable;
+ // use an if cascade instead
+ match dst.scheme() {
+ Some(scheme) if scheme == &http::uri::Scheme::HTTP && !self.force_https => {
+ let future = self.http.call(dst);
+ return Box::pin(async move {
+ Ok(MaybeHttpsStream::Http(future.await.map_err(Into::into)?))
+ });
+ }
+ Some(scheme) if scheme != &http::uri::Scheme::HTTPS => {
+ let message = format!("unsupported scheme {scheme}");
+ return Box::pin(async move {
+ Err(io::Error::new(io::ErrorKind::Other, message).into())
+ });
+ }
+ Some(_) => {}
+ None => {
+ return Box::pin(async move {
+ Err(io::Error::new(io::ErrorKind::Other, "missing scheme").into())
+ })
+ }
+ };
+
+ let cfg = self.tls_config.clone();
+ let hostname = match self.server_name_resolver.resolve(&dst) {
+ Ok(hostname) => hostname,
+ Err(e) => {
+ return Box::pin(async move { Err(e) });
+ }
+ };
+
+ let connecting_future = self.http.call(dst);
+ Box::pin(async move {
+ let tcp = connecting_future
+ .await
+ .map_err(Into::into)?;
+ Ok(MaybeHttpsStream::Https(TokioIo::new(
+ TlsConnector::from(cfg)
+ .connect(hostname, TokioIo::new(tcp))
+ .await
+ .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?,
+ )))
+ })
+ }
+}
+
+impl<H, C> From<(H, C)> for HttpsConnector<H>
+where
+ C: Into<Arc<rustls::ClientConfig>>,
+{
+ fn from((http, cfg): (H, C)) -> Self {
+ Self {
+ force_https: false,
+ http,
+ tls_config: cfg.into(),
+ server_name_resolver: Arc::new(DefaultServerNameResolver::default()),
+ }
+ }
+}
+
+impl<T> fmt::Debug for HttpsConnector<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("HttpsConnector")
+ .field("force_https", &self.force_https)
+ .finish()
+ }
+}
+
+/// The default server name resolver, which uses the hostname in the URI.
+#[derive(Default)]
+pub struct DefaultServerNameResolver(());
+
+impl ResolveServerName for DefaultServerNameResolver {
+ fn resolve(
+ &self,
+ uri: &Uri,
+ ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>> {
+ let mut hostname = uri.host().unwrap_or_default();
+
+ // Remove square brackets around IPv6 address.
+ if let Some(trimmed) = hostname
+ .strip_prefix('[')
+ .and_then(|h| h.strip_suffix(']'))
+ {
+ hostname = trimmed;
+ }
+
+ ServerName::try_from(hostname.to_string()).map_err(|e| Box::new(e) as _)
+ }
+}
+
+/// A server name resolver which always returns the same fixed name.
+pub struct FixedServerNameResolver {
+ name: ServerName<'static>,
+}
+
+impl FixedServerNameResolver {
+ /// Creates a new resolver returning the specified name.
+ pub fn new(name: ServerName<'static>) -> Self {
+ Self { name }
+ }
+}
+
+impl ResolveServerName for FixedServerNameResolver {
+ fn resolve(
+ &self,
+ _: &Uri,
+ ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>> {
+ Ok(self.name.clone())
+ }
+}
+
+impl<F, E> ResolveServerName for F
+where
+ F: Fn(&Uri) -> Result<ServerName<'static>, E>,
+ E: Into<Box<dyn std::error::Error + Sync + Send>>,
+{
+ fn resolve(
+ &self,
+ uri: &Uri,
+ ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>> {
+ self(uri).map_err(Into::into)
+ }
+}
+
+/// A trait implemented by types that can resolve a [`ServerName`] for a request.
+pub trait ResolveServerName {
+ /// Maps a [`Uri`] into a [`ServerName`].
+ fn resolve(
+ &self,
+ uri: &Uri,
+ ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>>;
+}
+
+#[cfg(all(
+ test,
+ any(feature = "ring", feature = "aws-lc-rs"),
+ any(
+ feature = "rustls-native-certs",
+ feature = "webpki-roots",
+ feature = "rustls-platform-verifier",
+ )
+))]
+mod tests {
+ use std::future::poll_fn;
+
+ use http::Uri;
+ use hyper_util::rt::TokioIo;
+ use tokio::net::TcpStream;
+ use tower_service::Service;
+
+ use super::*;
+ use crate::{ConfigBuilderExt, HttpsConnectorBuilder, MaybeHttpsStream};
+
+ #[tokio::test]
+ async fn connects_https() {
+ connect(Allow::Any, Scheme::Https)
+ .await
+ .unwrap();
+ }
+
+ #[tokio::test]
+ async fn connects_http() {
+ connect(Allow::Any, Scheme::Http)
+ .await
+ .unwrap();
+ }
+
+ #[tokio::test]
+ async fn connects_https_only() {
+ connect(Allow::Https, Scheme::Https)
+ .await
+ .unwrap();
+ }
+
+ #[tokio::test]
+ async fn enforces_https_only() {
+ let message = connect(Allow::Https, Scheme::Http)
+ .await
+ .unwrap_err()
+ .to_string();
+
+ assert_eq!(message, "unsupported scheme http");
+ }
+
+ async fn connect(
+ allow: Allow,
+ scheme: Scheme,
+ ) -> Result<MaybeHttpsStream<TokioIo<TcpStream>>, BoxError> {
+ let config_builder = rustls::ClientConfig::builder();
+ cfg_if::cfg_if! {
+ if #[cfg(feature = "rustls-platform-verifier")] {
+ let config_builder = config_builder.try_with_platform_verifier()?;
+ } else if #[cfg(feature = "rustls-native-certs")] {
+ let config_builder = config_builder.with_native_roots().unwrap();
+ } else if #[cfg(feature = "webpki-roots")] {
+ let config_builder = config_builder.with_webpki_roots();
+ }
+ }
+ let config = config_builder.with_no_client_auth();
+
+ let builder = HttpsConnectorBuilder::new().with_tls_config(config);
+ let mut service = match allow {
+ Allow::Https => builder.https_only(),
+ Allow::Any => builder.https_or_http(),
+ }
+ .enable_http1()
+ .build();
+
+ poll_fn(|cx| service.poll_ready(cx)).await?;
+ service
+ .call(Uri::from_static(match scheme {
+ Scheme::Https => "https://google.com",
+ Scheme::Http => "http://google.com",
+ }))
+ .await
+ }
+
+ enum Allow {
+ Https,
+ Any,
+ }
+
+ enum Scheme {
+ Https,
+ Http,
+ }
+}
diff --git a/vendor/hyper-rustls/src/connector/builder.rs b/vendor/hyper-rustls/src/connector/builder.rs
new file mode 100644
index 00000000..417d1303
--- /dev/null
+++ b/vendor/hyper-rustls/src/connector/builder.rs
@@ -0,0 +1,500 @@
+use std::sync::Arc;
+
+use hyper_util::client::legacy::connect::HttpConnector;
+#[cfg(any(
+ feature = "rustls-native-certs",
+ feature = "rustls-platform-verifier",
+ feature = "webpki-roots"
+))]
+use rustls::crypto::CryptoProvider;
+use rustls::ClientConfig;
+
+use super::{DefaultServerNameResolver, HttpsConnector, ResolveServerName};
+#[cfg(any(
+ feature = "rustls-native-certs",
+ feature = "webpki-roots",
+ feature = "rustls-platform-verifier"
+))]
+use crate::config::ConfigBuilderExt;
+use pki_types::ServerName;
+
+/// A builder for an [`HttpsConnector`]
+///
+/// This makes configuration flexible and explicit and ensures connector
+/// features match crate features
+///
+/// # Examples
+///
+/// ```
+/// use hyper_rustls::HttpsConnectorBuilder;
+///
+/// # #[cfg(all(feature = "webpki-roots", feature = "http1", feature="aws-lc-rs"))]
+/// # {
+/// # let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
+/// let https = HttpsConnectorBuilder::new()
+/// .with_webpki_roots()
+/// .https_only()
+/// .enable_http1()
+/// .build();
+/// # }
+/// ```
+pub struct ConnectorBuilder<State>(State);
+
+/// State of a builder that needs a TLS client config next
+pub struct WantsTlsConfig(());
+
+impl ConnectorBuilder<WantsTlsConfig> {
+ /// Creates a new [`ConnectorBuilder`]
+ pub fn new() -> Self {
+ Self(WantsTlsConfig(()))
+ }
+
+ /// Passes a rustls [`ClientConfig`] to configure the TLS connection
+ ///
+ /// The [`alpn_protocols`](ClientConfig::alpn_protocols) field is
+ /// required to be empty (or the function will panic) and will be
+ /// rewritten to match the enabled schemes (see
+ /// [`enable_http1`](ConnectorBuilder::enable_http1),
+ /// [`enable_http2`](ConnectorBuilder::enable_http2)) before the
+ /// connector is built.
+ pub fn with_tls_config(self, config: ClientConfig) -> ConnectorBuilder<WantsSchemes> {
+ assert!(
+ config.alpn_protocols.is_empty(),
+ "ALPN protocols should not be pre-defined"
+ );
+ ConnectorBuilder(WantsSchemes { tls_config: config })
+ }
+
+ /// Shorthand for using rustls' default crypto provider and other defaults, and
+ /// the platform verifier.
+ ///
+ /// See [`ConfigBuilderExt::with_platform_verifier()`].
+ #[cfg(all(
+ any(feature = "ring", feature = "aws-lc-rs"),
+ feature = "rustls-platform-verifier"
+ ))]
+ pub fn with_platform_verifier(self) -> ConnectorBuilder<WantsSchemes> {
+ self.try_with_platform_verifier()
+ .expect("failure to initialize platform verifier")
+ }
+
+ /// Shorthand for using rustls' default crypto provider and other defaults, and
+ /// the platform verifier.
+ ///
+ /// See [`ConfigBuilderExt::with_platform_verifier()`].
+ #[cfg(all(
+ any(feature = "ring", feature = "aws-lc-rs"),
+ feature = "rustls-platform-verifier"
+ ))]
+ pub fn try_with_platform_verifier(
+ self,
+ ) -> Result<ConnectorBuilder<WantsSchemes>, rustls::Error> {
+ Ok(self.with_tls_config(
+ ClientConfig::builder()
+ .try_with_platform_verifier()?
+ .with_no_client_auth(),
+ ))
+ }
+
+ /// Shorthand for using a custom [`CryptoProvider`] and the platform verifier.
+ ///
+ /// See [`ConfigBuilderExt::with_platform_verifier()`].
+ #[cfg(feature = "rustls-platform-verifier")]
+ pub fn with_provider_and_platform_verifier(
+ self,
+ provider: impl Into<Arc<CryptoProvider>>,
+ ) -> std::io::Result<ConnectorBuilder<WantsSchemes>> {
+ Ok(self.with_tls_config(
+ ClientConfig::builder_with_provider(provider.into())
+ .with_safe_default_protocol_versions()
+ .and_then(|builder| builder.try_with_platform_verifier())
+ .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
+ .with_no_client_auth(),
+ ))
+ }
+
+ /// Shorthand for using rustls' default crypto provider and safe defaults, with
+ /// native roots.
+ ///
+ /// See [`ConfigBuilderExt::with_native_roots`]
+ #[cfg(all(
+ any(feature = "ring", feature = "aws-lc-rs"),
+ feature = "rustls-native-certs"
+ ))]
+ pub fn with_native_roots(self) -> std::io::Result<ConnectorBuilder<WantsSchemes>> {
+ Ok(self.with_tls_config(
+ ClientConfig::builder()
+ .with_native_roots()?
+ .with_no_client_auth(),
+ ))
+ }
+
+ /// Shorthand for using a custom [`CryptoProvider`] and native roots
+ ///
+ /// See [`ConfigBuilderExt::with_native_roots`]
+ #[cfg(feature = "rustls-native-certs")]
+ pub fn with_provider_and_native_roots(
+ self,
+ provider: impl Into<Arc<CryptoProvider>>,
+ ) -> std::io::Result<ConnectorBuilder<WantsSchemes>> {
+ Ok(self.with_tls_config(
+ ClientConfig::builder_with_provider(provider.into())
+ .with_safe_default_protocol_versions()
+ .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
+ .with_native_roots()?
+ .with_no_client_auth(),
+ ))
+ }
+
+ /// Shorthand for using rustls' default crypto provider and its
+ /// safe defaults.
+ ///
+ /// See [`ConfigBuilderExt::with_webpki_roots`]
+ #[cfg(all(any(feature = "ring", feature = "aws-lc-rs"), feature = "webpki-roots"))]
+ pub fn with_webpki_roots(self) -> ConnectorBuilder<WantsSchemes> {
+ self.with_tls_config(
+ ClientConfig::builder()
+ .with_webpki_roots()
+ .with_no_client_auth(),
+ )
+ }
+
+ /// Shorthand for using a custom [`CryptoProvider`], Rustls' safe default
+ /// protocol versions and Mozilla roots
+ ///
+ /// See [`ConfigBuilderExt::with_webpki_roots`]
+ #[cfg(feature = "webpki-roots")]
+ pub fn with_provider_and_webpki_roots(
+ self,
+ provider: impl Into<Arc<CryptoProvider>>,
+ ) -> Result<ConnectorBuilder<WantsSchemes>, rustls::Error> {
+ Ok(self.with_tls_config(
+ ClientConfig::builder_with_provider(provider.into())
+ .with_safe_default_protocol_versions()?
+ .with_webpki_roots()
+ .with_no_client_auth(),
+ ))
+ }
+}
+
+impl Default for ConnectorBuilder<WantsTlsConfig> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+/// State of a builder that needs schemes (https:// and http://) to be
+/// configured next
+pub struct WantsSchemes {
+ tls_config: ClientConfig,
+}
+
+impl ConnectorBuilder<WantsSchemes> {
+ /// Enforce the use of HTTPS when connecting
+ ///
+ /// Only URLs using the HTTPS scheme will be connectable.
+ pub fn https_only(self) -> ConnectorBuilder<WantsProtocols1> {
+ ConnectorBuilder(WantsProtocols1 {
+ tls_config: self.0.tls_config,
+ https_only: true,
+ server_name_resolver: None,
+ })
+ }
+
+ /// Allow both HTTPS and HTTP when connecting
+ ///
+ /// HTTPS URLs will be handled through rustls,
+ /// HTTP URLs will be handled by the lower-level connector.
+ pub fn https_or_http(self) -> ConnectorBuilder<WantsProtocols1> {
+ ConnectorBuilder(WantsProtocols1 {
+ tls_config: self.0.tls_config,
+ https_only: false,
+ server_name_resolver: None,
+ })
+ }
+}
+
+/// State of a builder that needs to have some protocols (HTTP1 or later)
+/// enabled next
+///
+/// No protocol has been enabled at this point.
+pub struct WantsProtocols1 {
+ tls_config: ClientConfig,
+ https_only: bool,
+ server_name_resolver: Option<Arc<dyn ResolveServerName + Sync + Send>>,
+}
+
+impl WantsProtocols1 {
+ fn wrap_connector<H>(self, conn: H) -> HttpsConnector<H> {
+ HttpsConnector {
+ force_https: self.https_only,
+ http: conn,
+ tls_config: std::sync::Arc::new(self.tls_config),
+ server_name_resolver: self
+ .server_name_resolver
+ .unwrap_or_else(|| Arc::new(DefaultServerNameResolver::default())),
+ }
+ }
+
+ fn build(self) -> HttpsConnector<HttpConnector> {
+ let mut http = HttpConnector::new();
+ // HttpConnector won't enforce scheme, but HttpsConnector will
+ http.enforce_http(false);
+ self.wrap_connector(http)
+ }
+}
+
+impl ConnectorBuilder<WantsProtocols1> {
+ /// Enable HTTP1
+ ///
+ /// This needs to be called explicitly, no protocol is enabled by default
+ #[cfg(feature = "http1")]
+ pub fn enable_http1(self) -> ConnectorBuilder<WantsProtocols2> {
+ ConnectorBuilder(WantsProtocols2 { inner: self.0 })
+ }
+
+ /// Enable HTTP2
+ ///
+ /// This needs to be called explicitly, no protocol is enabled by default
+ #[cfg(feature = "http2")]
+ pub fn enable_http2(mut self) -> ConnectorBuilder<WantsProtocols3> {
+ self.0.tls_config.alpn_protocols = vec![b"h2".to_vec()];
+ ConnectorBuilder(WantsProtocols3 {
+ inner: self.0,
+ enable_http1: false,
+ })
+ }
+
+ /// Enable all HTTP versions built into this library (enabled with Cargo features)
+ ///
+ /// For now, this could enable both HTTP 1 and 2, depending on active features.
+ /// In the future, other supported versions will be enabled as well.
+ #[cfg(feature = "http2")]
+ pub fn enable_all_versions(mut self) -> ConnectorBuilder<WantsProtocols3> {
+ #[cfg(feature = "http1")]
+ let alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+ #[cfg(not(feature = "http1"))]
+ let alpn_protocols = vec![b"h2".to_vec()];
+
+ self.0.tls_config.alpn_protocols = alpn_protocols;
+ ConnectorBuilder(WantsProtocols3 {
+ inner: self.0,
+ enable_http1: cfg!(feature = "http1"),
+ })
+ }
+
+ /// Override server name for the TLS stack
+ ///
+ /// By default, for each connection hyper-rustls will extract host portion
+ /// of the destination URL and verify that server certificate contains
+ /// this value.
+ ///
+ /// If this method is called, hyper-rustls will instead use this resolver
+ /// to compute the value used to verify the server certificate.
+ pub fn with_server_name_resolver(
+ mut self,
+ resolver: impl ResolveServerName + 'static + Sync + Send,
+ ) -> Self {
+ self.0.server_name_resolver = Some(Arc::new(resolver));
+ self
+ }
+
+ /// Override server name for the TLS stack
+ ///
+ /// By default, for each connection hyper-rustls will extract host portion
+ /// of the destination URL and verify that server certificate contains
+ /// this value.
+ ///
+ /// If this method is called, hyper-rustls will instead verify that server
+ /// certificate contains `override_server_name`. Domain name included in
+ /// the URL will not affect certificate validation.
+ #[deprecated(
+ since = "0.27.1",
+ note = "use Self::with_server_name_resolver with FixedServerNameResolver instead"
+ )]
+ pub fn with_server_name(self, mut override_server_name: String) -> Self {
+ // remove square brackets around IPv6 address.
+ if let Some(trimmed) = override_server_name
+ .strip_prefix('[')
+ .and_then(|s| s.strip_suffix(']'))
+ {
+ override_server_name = trimmed.to_string();
+ }
+
+ self.with_server_name_resolver(move |_: &_| {
+ ServerName::try_from(override_server_name.clone())
+ })
+ }
+}
+
+/// State of a builder with HTTP1 enabled, that may have some other
+/// protocols (HTTP2 or later) enabled next
+///
+/// At this point a connector can be built, see
+/// [`build`](ConnectorBuilder<WantsProtocols2>::build) and
+/// [`wrap_connector`](ConnectorBuilder<WantsProtocols2>::wrap_connector).
+pub struct WantsProtocols2 {
+ inner: WantsProtocols1,
+}
+
+impl ConnectorBuilder<WantsProtocols2> {
+ /// Enable HTTP2
+ ///
+ /// This needs to be called explicitly, no protocol is enabled by default
+ #[cfg(feature = "http2")]
+ pub fn enable_http2(mut self) -> ConnectorBuilder<WantsProtocols3> {
+ self.0.inner.tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+ ConnectorBuilder(WantsProtocols3 {
+ inner: self.0.inner,
+ enable_http1: true,
+ })
+ }
+
+ /// This builds an [`HttpsConnector`] built on hyper's default [`HttpConnector`]
+ pub fn build(self) -> HttpsConnector<HttpConnector> {
+ self.0.inner.build()
+ }
+
+ /// This wraps an arbitrary low-level connector into an [`HttpsConnector`]
+ pub fn wrap_connector<H>(self, conn: H) -> HttpsConnector<H> {
+ // HTTP1-only, alpn_protocols stays empty
+ // HttpConnector doesn't have a way to say http1-only;
+ // its connection pool may still support HTTP2
+ // though it won't be used
+ self.0.inner.wrap_connector(conn)
+ }
+}
+
+/// State of a builder with HTTP2 (and possibly HTTP1) enabled
+///
+/// At this point a connector can be built, see
+/// [`build`](ConnectorBuilder<WantsProtocols3>::build) and
+/// [`wrap_connector`](ConnectorBuilder<WantsProtocols3>::wrap_connector).
+#[cfg(feature = "http2")]
+pub struct WantsProtocols3 {
+ inner: WantsProtocols1,
+ // ALPN is built piecemeal without the need to read back this field
+ #[allow(dead_code)]
+ enable_http1: bool,
+}
+
+#[cfg(feature = "http2")]
+impl ConnectorBuilder<WantsProtocols3> {
+ /// This builds an [`HttpsConnector`] built on hyper's default [`HttpConnector`]
+ pub fn build(self) -> HttpsConnector<HttpConnector> {
+ self.0.inner.build()
+ }
+
+ /// This wraps an arbitrary low-level connector into an [`HttpsConnector`]
+ pub fn wrap_connector<H>(self, conn: H) -> HttpsConnector<H> {
+ // If HTTP1 is disabled, we can set http2_only
+ // on the Client (a higher-level object that uses the connector)
+ // client.http2_only(!self.0.enable_http1);
+ self.0.inner.wrap_connector(conn)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ // Typical usage
+ #[test]
+ #[cfg(all(feature = "webpki-roots", feature = "http1"))]
+ fn test_builder() {
+ ensure_global_state();
+ let _connector = super::ConnectorBuilder::new()
+ .with_webpki_roots()
+ .https_only()
+ .enable_http1()
+ .build();
+ }
+
+ #[test]
+ #[cfg(feature = "http1")]
+ #[should_panic(expected = "ALPN protocols should not be pre-defined")]
+ fn test_reject_predefined_alpn() {
+ ensure_global_state();
+ let roots = rustls::RootCertStore::empty();
+ let mut config_with_alpn = rustls::ClientConfig::builder()
+ .with_root_certificates(roots)
+ .with_no_client_auth();
+ config_with_alpn.alpn_protocols = vec![b"fancyprotocol".to_vec()];
+ let _connector = super::ConnectorBuilder::new()
+ .with_tls_config(config_with_alpn)
+ .https_only()
+ .enable_http1()
+ .build();
+ }
+
+ #[test]
+ #[cfg(all(feature = "http1", feature = "http2"))]
+ fn test_alpn() {
+ ensure_global_state();
+ let roots = rustls::RootCertStore::empty();
+ let tls_config = rustls::ClientConfig::builder()
+ .with_root_certificates(roots)
+ .with_no_client_auth();
+ let connector = super::ConnectorBuilder::new()
+ .with_tls_config(tls_config.clone())
+ .https_only()
+ .enable_http1()
+ .build();
+ assert!(connector
+ .tls_config
+ .alpn_protocols
+ .is_empty());
+ let connector = super::ConnectorBuilder::new()
+ .with_tls_config(tls_config.clone())
+ .https_only()
+ .enable_http2()
+ .build();
+ assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]);
+ let connector = super::ConnectorBuilder::new()
+ .with_tls_config(tls_config.clone())
+ .https_only()
+ .enable_http1()
+ .enable_http2()
+ .build();
+ assert_eq!(
+ &connector.tls_config.alpn_protocols,
+ &[b"h2".to_vec(), b"http/1.1".to_vec()]
+ );
+ let connector = super::ConnectorBuilder::new()
+ .with_tls_config(tls_config)
+ .https_only()
+ .enable_all_versions()
+ .build();
+ assert_eq!(
+ &connector.tls_config.alpn_protocols,
+ &[b"h2".to_vec(), b"http/1.1".to_vec()]
+ );
+ }
+
+ #[test]
+ #[cfg(all(not(feature = "http1"), feature = "http2"))]
+ fn test_alpn_http2() {
+ let roots = rustls::RootCertStore::empty();
+ let tls_config = rustls::ClientConfig::builder()
+ .with_safe_defaults()
+ .with_root_certificates(roots)
+ .with_no_client_auth();
+ let connector = super::ConnectorBuilder::new()
+ .with_tls_config(tls_config.clone())
+ .https_only()
+ .enable_http2()
+ .build();
+ assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]);
+ let connector = super::ConnectorBuilder::new()
+ .with_tls_config(tls_config)
+ .https_only()
+ .enable_all_versions()
+ .build();
+ assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]);
+ }
+
+ fn ensure_global_state() {
+ #[cfg(feature = "ring")]
+ let _ = rustls::crypto::ring::default_provider().install_default();
+ #[cfg(feature = "aws-lc-rs")]
+ let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
+ }
+}
diff --git a/vendor/hyper-rustls/src/lib.rs b/vendor/hyper-rustls/src/lib.rs
new file mode 100644
index 00000000..89e355ae
--- /dev/null
+++ b/vendor/hyper-rustls/src/lib.rs
@@ -0,0 +1,76 @@
+//! # hyper-rustls
+//!
+//! A pure-Rust HTTPS connector for [hyper](https://hyper.rs), based on
+//! [Rustls](https://github.com/rustls/rustls).
+//!
+//! ## Example client
+//!
+//! ```no_run
+//! # #[cfg(all(feature = "rustls-native-certs", feature = "http1"))]
+//! # fn main() {
+//! use http::StatusCode;
+//! use http_body_util::Empty;
+//! use hyper::body::Bytes;
+//! use hyper_util::client::legacy::Client;
+//! use hyper_util::rt::TokioExecutor;
+//!
+//! let mut rt = tokio::runtime::Runtime::new().unwrap();
+//! let url = ("https://hyper.rs").parse().unwrap();
+//! let https = hyper_rustls::HttpsConnectorBuilder::new()
+//! .with_native_roots()
+//! .expect("no native root CA certificates found")
+//! .https_only()
+//! .enable_http1()
+//! .build();
+//!
+//! let client: Client<_, Empty<Bytes>> = Client::builder(TokioExecutor::new()).build(https);
+//!
+//! let res = rt.block_on(client.get(url)).unwrap();
+//! assert_eq!(res.status(), StatusCode::OK);
+//! # }
+//! # #[cfg(not(all(feature = "rustls-native-certs", feature = "http1")))]
+//! # fn main() {}
+//! ```
+
+#![warn(missing_docs, unreachable_pub, clippy::use_self)]
+#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
+
+mod config;
+mod connector;
+mod stream;
+
+#[cfg(feature = "logging")]
+mod log {
+ #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))]
+ pub(crate) use log::debug;
+ #[cfg(feature = "rustls-native-certs")]
+ pub(crate) use log::warn;
+}
+
+#[cfg(not(feature = "logging"))]
+mod log {
+ #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))]
+ macro_rules! debug ( ($($tt:tt)*) => {{}} );
+ #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))]
+ pub(crate) use debug;
+ #[cfg(feature = "rustls-native-certs")]
+ macro_rules! warn_ ( ($($tt:tt)*) => {{}} );
+ #[cfg(feature = "rustls-native-certs")]
+ pub(crate) use warn_ as warn;
+}
+
+pub use crate::config::ConfigBuilderExt;
+pub use crate::connector::builder::ConnectorBuilder as HttpsConnectorBuilder;
+pub use crate::connector::{
+ DefaultServerNameResolver, FixedServerNameResolver, HttpsConnector, ResolveServerName,
+};
+pub use crate::stream::MaybeHttpsStream;
+
+/// The various states of the [`HttpsConnectorBuilder`]
+pub mod builderstates {
+ #[cfg(feature = "http2")]
+ pub use crate::connector::builder::WantsProtocols3;
+ pub use crate::connector::builder::{
+ WantsProtocols1, WantsProtocols2, WantsSchemes, WantsTlsConfig,
+ };
+}
diff --git a/vendor/hyper-rustls/src/stream.rs b/vendor/hyper-rustls/src/stream.rs
new file mode 100644
index 00000000..f08e7b1b
--- /dev/null
+++ b/vendor/hyper-rustls/src/stream.rs
@@ -0,0 +1,121 @@
+// Copied from hyperium/hyper-tls#62e3376/src/stream.rs
+use std::fmt;
+use std::io;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+use hyper::rt;
+use hyper_util::client::legacy::connect::{Connected, Connection};
+
+use hyper_util::rt::TokioIo;
+use tokio_rustls::client::TlsStream;
+
+/// A stream that might be protected with TLS.
+#[allow(clippy::large_enum_variant)]
+pub enum MaybeHttpsStream<T> {
+ /// A stream over plain text.
+ Http(T),
+ /// A stream protected with TLS.
+ Https(TokioIo<TlsStream<TokioIo<T>>>),
+}
+
+impl<T: rt::Read + rt::Write + Connection + Unpin> Connection for MaybeHttpsStream<T> {
+ fn connected(&self) -> Connected {
+ match self {
+ Self::Http(s) => s.connected(),
+ Self::Https(s) => {
+ let (tcp, tls) = s.inner().get_ref();
+ if tls.alpn_protocol() == Some(b"h2") {
+ tcp.inner().connected().negotiated_h2()
+ } else {
+ tcp.inner().connected()
+ }
+ }
+ }
+ }
+}
+
+impl<T: fmt::Debug> fmt::Debug for MaybeHttpsStream<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Self::Http(..) => f.pad("Http(..)"),
+ Self::Https(..) => f.pad("Https(..)"),
+ }
+ }
+}
+
+impl<T> From<T> for MaybeHttpsStream<T> {
+ fn from(inner: T) -> Self {
+ Self::Http(inner)
+ }
+}
+
+impl<T> From<TlsStream<TokioIo<T>>> for MaybeHttpsStream<T> {
+ fn from(inner: TlsStream<TokioIo<T>>) -> Self {
+ Self::Https(TokioIo::new(inner))
+ }
+}
+
+impl<T: rt::Read + rt::Write + Unpin> rt::Read for MaybeHttpsStream<T> {
+ #[inline]
+ fn poll_read(
+ self: Pin<&mut Self>,
+ cx: &mut Context,
+ buf: rt::ReadBufCursor<'_>,
+ ) -> Poll<Result<(), io::Error>> {
+ match Pin::get_mut(self) {
+ Self::Http(s) => Pin::new(s).poll_read(cx, buf),
+ Self::Https(s) => Pin::new(s).poll_read(cx, buf),
+ }
+ }
+}
+
+impl<T: rt::Write + rt::Read + Unpin> rt::Write for MaybeHttpsStream<T> {
+ #[inline]
+ fn poll_write(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ buf: &[u8],
+ ) -> Poll<Result<usize, io::Error>> {
+ match Pin::get_mut(self) {
+ Self::Http(s) => Pin::new(s).poll_write(cx, buf),
+ Self::Https(s) => Pin::new(s).poll_write(cx, buf),
+ }
+ }
+
+ #[inline]
+ fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
+ match Pin::get_mut(self) {
+ Self::Http(s) => Pin::new(s).poll_flush(cx),
+ Self::Https(s) => Pin::new(s).poll_flush(cx),
+ }
+ }
+
+ #[inline]
+ fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
+ match Pin::get_mut(self) {
+ Self::Http(s) => Pin::new(s).poll_shutdown(cx),
+ Self::Https(s) => Pin::new(s).poll_shutdown(cx),
+ }
+ }
+
+ #[inline]
+ fn is_write_vectored(&self) -> bool {
+ match self {
+ Self::Http(s) => s.is_write_vectored(),
+ Self::Https(s) => s.is_write_vectored(),
+ }
+ }
+
+ #[inline]
+ fn poll_write_vectored(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ bufs: &[io::IoSlice<'_>],
+ ) -> Poll<Result<usize, io::Error>> {
+ match Pin::get_mut(self) {
+ Self::Http(s) => Pin::new(s).poll_write_vectored(cx, bufs),
+ Self::Https(s) => Pin::new(s).poll_write_vectored(cx, bufs),
+ }
+ }
+}
diff --git a/vendor/hyper-rustls/tests/tests.rs b/vendor/hyper-rustls/tests/tests.rs
new file mode 100644
index 00000000..91572bc5
--- /dev/null
+++ b/vendor/hyper-rustls/tests/tests.rs
@@ -0,0 +1,102 @@
+use std::env;
+use std::net::TcpStream;
+use std::path::PathBuf;
+use std::process::Command;
+use std::thread;
+use std::time;
+
+fn examples_dir() -> PathBuf {
+ let target_dir: PathBuf = env::var("CARGO_TARGET_DIR")
+ .unwrap_or_else(|_| "target".to_string())
+ .into();
+ target_dir
+ .join("debug")
+ .join("examples")
+}
+
+fn server_command() -> Command {
+ Command::new(examples_dir().join("server"))
+}
+
+fn client_command() -> Command {
+ Command::new(examples_dir().join("client"))
+}
+
+fn wait_for_server(addr: &str) {
+ for i in 0..10 {
+ if TcpStream::connect(addr).is_ok() {
+ return;
+ }
+ thread::sleep(time::Duration::from_millis(i * 100));
+ }
+ panic!("failed to connect to {:?} after 10 tries", addr);
+}
+
+#[test]
+fn client() {
+ let rc = client_command()
+ .arg("https://google.com")
+ .output()
+ .expect("cannot run client example");
+
+ assert!(rc.status.success());
+}
+
+#[test]
+fn server() {
+ let mut srv = server_command()
+ .arg("1337")
+ .spawn()
+ .expect("cannot run server example");
+
+ let addr = "localhost:1337";
+ wait_for_server(addr);
+
+ let output = Command::new("curl")
+ .arg("--insecure")
+ .arg("--http1.0")
+ .arg(format!("https://{}", addr))
+ .output()
+ .expect("cannot run curl");
+
+ srv.kill().unwrap();
+ srv.wait()
+ .expect("failed to wait on server process");
+
+ if !output.status.success() {
+ let version_stdout = Command::new("curl")
+ .arg("--version")
+ .output()
+ .expect("cannot run curl to collect --version")
+ .stdout;
+ println!("curl version: {}", String::from_utf8_lossy(&version_stdout));
+ println!("curl stderr:\n{}", String::from_utf8_lossy(&output.stderr));
+ }
+
+ assert_eq!(String::from_utf8_lossy(&output.stdout), "Try POST /echo\n");
+}
+
+#[test]
+fn custom_ca_store() {
+ let mut srv = server_command()
+ .arg("1338")
+ .spawn()
+ .expect("cannot run server example");
+
+ let addr = "localhost:1338";
+ wait_for_server(addr);
+
+ let rc = client_command()
+ .arg(format!("https://{}", addr))
+ .arg("examples/sample.pem")
+ .output()
+ .expect("cannot run client example");
+
+ srv.kill().unwrap();
+ srv.wait()
+ .expect("failed to wait on server process");
+
+ if !rc.status.success() {
+ assert_eq!(String::from_utf8_lossy(&rc.stdout), "");
+ }
+}