Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Vendor hyper-rustls and switch to ring backend

Add a vendored hyper-rustls crate and patch.crates-io entry so the
workspace uses a locally modified copy. Update crates/rocksky to build
rustls with the "ring" feature and install rustls::crypto::ring as the
default provider.

This avoids depending on aws-lc-rs/aws-lc-sys (cmake cross-compile)
which
breaks cargo-ndk/Android builds; ring has well-tested Android prebuilts.
Also remove the aws-lc entries from Cargo.lock as they're no longer used

+2302 -73
+2 -70
Cargo.lock
··· 1021 1021 ] 1022 1022 1023 1023 [[package]] 1024 - name = "aws-lc-rs" 1025 - version = "1.13.3" 1026 - source = "registry+https://github.com/rust-lang/crates.io-index" 1027 - checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" 1028 - dependencies = [ 1029 - "aws-lc-sys", 1030 - "zeroize", 1031 - ] 1032 - 1033 - [[package]] 1034 - name = "aws-lc-sys" 1035 - version = "0.30.0" 1036 - source = "registry+https://github.com/rust-lang/crates.io-index" 1037 - checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" 1038 - dependencies = [ 1039 - "bindgen 0.69.5", 1040 - "cc", 1041 - "cmake", 1042 - "dunce", 1043 - "fs_extra", 1044 - ] 1045 - 1046 - [[package]] 1047 1024 name = "axum" 1048 1025 version = "0.7.5" 1049 1026 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1202 1179 1203 1180 [[package]] 1204 1181 name = "bindgen" 1205 - version = "0.69.5" 1206 - source = "registry+https://github.com/rust-lang/crates.io-index" 1207 - checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" 1208 - dependencies = [ 1209 - "bitflags 2.6.0", 1210 - "cexpr", 1211 - "clang-sys", 1212 - "itertools 0.12.1", 1213 - "lazy_static", 1214 - "lazycell", 1215 - "log", 1216 - "prettyplease", 1217 - "proc-macro2", 1218 - "quote", 1219 - "regex", 1220 - "rustc-hash 1.1.0", 1221 - "shlex", 1222 - "syn 2.0.91", 1223 - "which 4.4.2", 1224 - ] 1225 - 1226 - [[package]] 1227 - name = "bindgen" 1228 1182 version = "0.70.1" 1229 1183 source = "registry+https://github.com/rust-lang/crates.io-index" 1230 1184 checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" ··· 4143 4097 ] 4144 4098 4145 4099 [[package]] 4146 - name = "dunce" 4147 - version = "1.0.5" 4148 - source = "registry+https://github.com/rust-lang/crates.io-index" 4149 - checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" 4150 - 4151 - [[package]] 4152 4100 name = "dyn-clone" 4153 4101 version = "1.0.17" 4154 4102 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4810 4758 ] 4811 4759 4812 4760 [[package]] 4813 - name = "fs_extra" 4814 - version = "1.3.0" 4815 - source = "registry+https://github.com/rust-lang/crates.io-index" 4816 - checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" 4817 - 4818 - [[package]] 4819 4761 name = "fsevent-sys" 4820 4762 version = "4.1.0" 4821 4763 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5860 5802 [[package]] 5861 5803 name = "hyper-rustls" 5862 5804 version = "0.27.3" 5863 - source = "registry+https://github.com/rust-lang/crates.io-index" 5864 - checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" 5865 5805 dependencies = [ 5866 5806 "futures-util", 5867 5807 "http 1.1.0", ··· 6575 6515 ] 6576 6516 6577 6517 [[package]] 6578 - name = "lazycell" 6579 - version = "1.3.0" 6580 - source = "registry+https://github.com/rust-lang/crates.io-index" 6581 - checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 6582 - 6583 - [[package]] 6584 6518 name = "leb128fmt" 6585 6519 version = "0.1.0" 6586 6520 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 6753 6687 source = "registry+https://github.com/rust-lang/crates.io-index" 6754 6688 checksum = "ca8dfd1a173826d193e3b955e07c22765829890f62c677a59c4a410cb4f47c01" 6755 6689 dependencies = [ 6756 - "bindgen 0.70.1", 6690 + "bindgen", 6757 6691 "libloading 0.8.5", 6758 6692 ] 6759 6693 ··· 9897 9831 source = "registry+https://github.com/rust-lang/crates.io-index" 9898 9832 checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" 9899 9833 dependencies = [ 9900 - "aws-lc-rs", 9901 9834 "log", 9902 9835 "once_cell", 9903 9836 "ring", ··· 9980 9913 source = "registry+https://github.com/rust-lang/crates.io-index" 9981 9914 checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 9982 9915 dependencies = [ 9983 - "aws-lc-rs", 9984 9916 "ring", 9985 9917 "rustls-pki-types", 9986 9918 "untrusted", ··· 12579 12511 source = "registry+https://github.com/rust-lang/crates.io-index" 12580 12512 checksum = "2ee0be58935708fa4d7efb970c6cf9f2d9511d24ee24246481a65b6ee167348d" 12581 12513 dependencies = [ 12582 - "bindgen 0.70.1", 12514 + "bindgen", 12583 12515 "bitflags 2.6.0", 12584 12516 "fslock", 12585 12517 "gzip-header",
+8
Cargo.toml
··· 298 298 ] } 299 299 opentelemetry_sdk = "0.27.0" 300 300 301 + # Vendored hyper-rustls 0.27.3 with one feature change: default uses `ring` 302 + # instead of `aws-lc-rs`. aws-lc-rs requires cmake-cross-compile of a C 303 + # library (aws-lc-sys) which doesn't survive cargo-ndk's flag injection on 304 + # Android NDK. ring has well-tested Android pre-builts. Desktop builds 305 + # behave identically (ring is also fine on macOS/Linux). 306 + [patch.crates-io] 307 + hyper-rustls = { path = "vendor/hyper-rustls" } 308 + 301 309 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1 -1
crates/rocksky/Cargo.toml
··· 26 26 tonic-web = "0.12.3" 27 27 tungstenite = { version = "0.26.2", features = ["rustls-tls-webpki-roots"] } 28 28 tokio-tungstenite = { version = "0.26.2", features = ["rustls-tls-webpki-roots"] } 29 - rustls = { version = "0.23", features = ["aws-lc-rs"] } 29 + rustls = { version = "0.23", default-features = false, features = ["ring", "logging", "std", "tls12"] } 30 30 webpki-roots = "0.26" 31 31 futures-util = "0.3.31" 32 32 tokio-stream = "0.1.17"
+4 -2
crates/rocksky/src/lib.rs
··· 42 42 } 43 43 44 44 pub async fn run_ws_session(token: String) -> Result<(), Error> { 45 - // Install the default crypto provider for rustls 0.23+ 46 - let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); 45 + // Install the default crypto provider for rustls 0.23+. ring instead 46 + // of aws_lc_rs because aws-lc-sys's cmake cross-compile doesn't survive 47 + // cargo-ndk's flag injection on Android. 48 + let _ = rustls::crypto::ring::default_provider().install_default(); 47 49 48 50 let rocksky_ws = 49 51 env::var("ROCKSKY_WS").unwrap_or_else(|_| "wss://api.rocksky.app/ws".to_string());
+1
vendor/hyper-rustls/.cargo-ok
··· 1 + {"v":1}
+6
vendor/hyper-rustls/.cargo_vcs_info.json
··· 1 + { 2 + "git": { 3 + "sha1": "dc54bc01f345e409137f43587c2a9cc6e50c988c" 4 + }, 5 + "path_in_vcs": "" 6 + }
+11
vendor/hyper-rustls/.github/dependabot.yml
··· 1 + version: 2 2 + updates: 3 + - package-ecosystem: cargo 4 + directory: "/" 5 + schedule: 6 + interval: daily 7 + open-pull-requests-limit: 10 8 + - package-ecosystem: github-actions 9 + directory: "/" 10 + schedule: 11 + interval: weekly
+182
vendor/hyper-rustls/.github/workflows/build.yml
··· 1 + name: rustls 2 + 3 + permissions: 4 + contents: read 5 + 6 + on: 7 + push: 8 + pull_request: 9 + merge_group: 10 + schedule: 11 + - cron: '23 6 * * 5' 12 + 13 + jobs: 14 + build: 15 + name: Build+test 16 + runs-on: ${{ matrix.os }} 17 + strategy: 18 + fail-fast: false 19 + matrix: 20 + # test a bunch of toolchains on ubuntu 21 + rust: 22 + - stable 23 + - beta 24 + - nightly 25 + os: [ubuntu-latest] 26 + # but only stable on macos/windows (slower platforms) 27 + include: 28 + - os: macos-latest 29 + rust: stable 30 + - os: windows-latest 31 + rust: stable 32 + steps: 33 + - name: Checkout sources 34 + uses: actions/checkout@v4 35 + with: 36 + persist-credentials: false 37 + 38 + - name: Install ${{ matrix.rust }} toolchain 39 + uses: dtolnay/rust-toolchain@master 40 + with: 41 + toolchain: ${{ matrix.rust }} 42 + 43 + - name: Install NASM for aws-lc-rs on Windows 44 + if: runner.os == 'Windows' 45 + uses: ilammy/setup-nasm@v1 46 + 47 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows 48 + if: runner.os == 'Windows' 49 + uses: seanmiddleditch/gha-setup-ninja@v5 50 + 51 + - name: cargo check (default features) 52 + run: cargo check --all-targets 53 + 54 + - name: cargo test (debug; default features) 55 + run: cargo test 56 + env: 57 + RUST_BACKTRACE: 1 58 + 59 + - name: cargo test (debug; native-tokio only) 60 + run: cargo test --no-default-features --features native-tokio 61 + env: 62 + RUST_BACKTRACE: 1 63 + 64 + - name: cargo test (debug; webpki-tokio only) 65 + run: cargo test --no-default-features --features webpki-tokio 66 + env: 67 + RUST_BACKTRACE: 1 68 + 69 + - name: cargo test (debug; defaults+ring) 70 + run: cargo test --no-default-features --features ring,native-tokio,http1,tls12,logging 71 + env: 72 + RUST_BACKTRACE: 1 73 + 74 + - name: cargo test (debug; all features) 75 + if: runner.os == 'Linux' 76 + run: cargo test --all-features 77 + env: 78 + RUST_BACKTRACE: 1 79 + 80 + - name: cargo test (debug; all features, excluding FIPS) 81 + if: runner.os != 'Linux' 82 + run: cargo test --features aws-lc-rs,http1,http2,webpki-tokio,native-tokio,ring,tls12,logging 83 + env: 84 + RUST_BACKTRACE: 1 85 + 86 + - name: cargo build (debug; no default features) 87 + run: cargo build --no-default-features 88 + 89 + - name: cargo test (debug; no default features; no run) 90 + run: cargo test --no-default-features --no-run 91 + 92 + - name: cargo test (release; no run) 93 + run: cargo test --release --no-run 94 + 95 + msrv: 96 + runs-on: ubuntu-latest 97 + steps: 98 + - name: Checkout sources 99 + uses: actions/checkout@v4 100 + with: 101 + persist-credentials: false 102 + 103 + - name: Install rust toolchain 104 + uses: dtolnay/rust-toolchain@master 105 + with: 106 + toolchain: "1.70" 107 + 108 + - name: Check MSRV 109 + run: cargo check --lib --all-features 110 + 111 + semver: 112 + name: Check semver compatibility 113 + runs-on: ubuntu-latest 114 + steps: 115 + - name: Checkout sources 116 + uses: actions/checkout@v4 117 + with: 118 + persist-credentials: false 119 + 120 + - name: Check semver 121 + uses: obi1kenobi/cargo-semver-checks-action@v2 122 + 123 + docs: 124 + name: Check for documentation errors 125 + runs-on: ubuntu-latest 126 + steps: 127 + - name: Checkout sources 128 + uses: actions/checkout@v4 129 + with: 130 + persist-credentials: false 131 + 132 + - name: Install rust toolchain 133 + uses: dtolnay/rust-toolchain@nightly 134 + 135 + - name: cargo doc (all features) 136 + # keep features in sync with Cargo.toml `[package.metadata.docs.rs]` section 137 + run: cargo doc --no-default-features --features http1,http2,webpki-tokio,native-tokio,ring,tls12,logging --no-deps 138 + env: 139 + RUSTDOCFLAGS: -Dwarnings 140 + 141 + format: 142 + name: Format 143 + runs-on: ubuntu-latest 144 + steps: 145 + - name: Checkout sources 146 + uses: actions/checkout@v4 147 + with: 148 + persist-credentials: false 149 + - name: Install rust toolchain 150 + uses: dtolnay/rust-toolchain@stable 151 + with: 152 + components: rustfmt 153 + - name: Check formatting 154 + run: cargo fmt --all -- --check 155 + 156 + clippy: 157 + name: Clippy 158 + runs-on: ubuntu-latest 159 + steps: 160 + - name: Checkout sources 161 + uses: actions/checkout@v4 162 + with: 163 + persist-credentials: false 164 + - name: Install rust toolchain 165 + uses: dtolnay/rust-toolchain@stable 166 + with: 167 + components: clippy 168 + - run: cargo clippy --all-features -- --deny warnings 169 + 170 + features: 171 + runs-on: ubuntu-latest 172 + steps: 173 + - name: Checkout sources 174 + uses: actions/checkout@v4 175 + with: 176 + persist-credentials: false 177 + - name: Install rust toolchain 178 + uses: dtolnay/rust-toolchain@stable 179 + - name: Install cargo-hack 180 + uses: taiki-e/install-action@cargo-hack 181 + - name: Check feature powerset 182 + run: cargo hack --no-dev-deps check --feature-powerset --depth 2
+3
vendor/hyper-rustls/.gitignore
··· 1 + Cargo.lock 2 + target/ 3 + /.idea
+1
vendor/hyper-rustls/.rustfmt.toml
··· 1 + chain_width=40
+175
vendor/hyper-rustls/Cargo.toml
··· 1 + # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO 2 + # 3 + # When uploading crates to the registry Cargo will automatically 4 + # "normalize" Cargo.toml files for maximal compatibility 5 + # with all versions of Cargo and also rewrite `path` dependencies 6 + # to registry (e.g., crates.io) dependencies. 7 + # 8 + # If you are reading this file be aware that the original Cargo.toml 9 + # will likely look very different (and much more reasonable). 10 + # See Cargo.toml.orig for the original contents. 11 + 12 + [package] 13 + edition = "2021" 14 + rust-version = "1.70" 15 + name = "hyper-rustls" 16 + version = "0.27.3" 17 + build = false 18 + autobins = false 19 + autoexamples = false 20 + autotests = false 21 + autobenches = false 22 + description = "Rustls+hyper integration for pure rust HTTPS" 23 + homepage = "https://github.com/rustls/hyper-rustls" 24 + documentation = "https://docs.rs/hyper-rustls/" 25 + readme = "README.md" 26 + license = "Apache-2.0 OR ISC OR MIT" 27 + repository = "https://github.com/rustls/hyper-rustls" 28 + 29 + [package.metadata.docs.rs] 30 + features = [ 31 + "http1", 32 + "http2", 33 + "logging", 34 + "native-tokio", 35 + "ring", 36 + "rustls-platform-verifier", 37 + "tls12", 38 + "webpki-tokio", 39 + ] 40 + no-default-features = true 41 + rustdoc-args = [ 42 + "--cfg", 43 + "docsrs", 44 + ] 45 + 46 + [lib] 47 + name = "hyper_rustls" 48 + path = "src/lib.rs" 49 + 50 + [[example]] 51 + name = "client" 52 + path = "examples/client.rs" 53 + required-features = [ 54 + "native-tokio", 55 + "http1", 56 + ] 57 + 58 + [[example]] 59 + name = "server" 60 + path = "examples/server.rs" 61 + required-features = ["aws-lc-rs"] 62 + 63 + [[test]] 64 + name = "tests" 65 + path = "tests/tests.rs" 66 + 67 + [dependencies.futures-util] 68 + version = "0.3" 69 + default-features = false 70 + 71 + [dependencies.http] 72 + version = "1" 73 + 74 + [dependencies.hyper] 75 + version = "1" 76 + default-features = false 77 + 78 + [dependencies.hyper-util] 79 + version = "0.1" 80 + features = [ 81 + "client-legacy", 82 + "tokio", 83 + ] 84 + default-features = false 85 + 86 + [dependencies.log] 87 + version = "0.4.4" 88 + optional = true 89 + 90 + [dependencies.pki-types] 91 + version = "1" 92 + package = "rustls-pki-types" 93 + 94 + [dependencies.rustls] 95 + version = "0.23" 96 + default-features = false 97 + 98 + [dependencies.rustls-native-certs] 99 + version = "0.8" 100 + optional = true 101 + 102 + [dependencies.rustls-platform-verifier] 103 + version = "0.3" 104 + optional = true 105 + 106 + [dependencies.tokio] 107 + version = "1.0" 108 + 109 + [dependencies.tokio-rustls] 110 + version = "0.26" 111 + default-features = false 112 + 113 + [dependencies.tower-service] 114 + version = "0.3" 115 + 116 + [dependencies.webpki-roots] 117 + version = "0.26" 118 + optional = true 119 + 120 + [dev-dependencies.http-body-util] 121 + version = "0.1" 122 + 123 + [dev-dependencies.hyper-util] 124 + version = "0.1" 125 + features = ["server-auto"] 126 + default-features = false 127 + 128 + [dev-dependencies.rustls] 129 + version = "0.23" 130 + features = ["tls12"] 131 + default-features = false 132 + 133 + [dev-dependencies.rustls-pemfile] 134 + version = "2" 135 + 136 + [dev-dependencies.tokio] 137 + version = "1.0" 138 + features = [ 139 + "io-std", 140 + "macros", 141 + "net", 142 + "rt-multi-thread", 143 + ] 144 + 145 + [features] 146 + aws-lc-rs = ["rustls/aws_lc_rs"] 147 + # PATCHED for rockbox-zig: default now uses ring instead of aws-lc-rs. 148 + # aws-lc-rs requires cmake-cross-compiling a C library (aws-lc-sys) which 149 + # doesn't work on Android NDK. ring has well-tested Android pre-built 150 + # binaries. Original line was: "aws-lc-rs", 151 + default = [ 152 + "native-tokio", 153 + "http1", 154 + "tls12", 155 + "logging", 156 + "ring", 157 + ] 158 + fips = [ 159 + "aws-lc-rs", 160 + "rustls/fips", 161 + ] 162 + http1 = ["hyper-util/http1"] 163 + http2 = ["hyper-util/http2"] 164 + logging = [ 165 + "log", 166 + "tokio-rustls/logging", 167 + "rustls/logging", 168 + ] 169 + native-tokio = ["rustls-native-certs"] 170 + ring = ["rustls/ring"] 171 + tls12 = [ 172 + "tokio-rustls/tls12", 173 + "rustls/tls12", 174 + ] 175 + webpki-tokio = ["webpki-roots"]
+69
vendor/hyper-rustls/Cargo.toml.orig
··· 1 + [package] 2 + name = "hyper-rustls" 3 + version = "0.27.3" 4 + edition = "2021" 5 + rust-version = "1.70" 6 + license = "Apache-2.0 OR ISC OR MIT" 7 + readme = "README.md" 8 + description = "Rustls+hyper integration for pure rust HTTPS" 9 + homepage = "https://github.com/rustls/hyper-rustls" 10 + repository = "https://github.com/rustls/hyper-rustls" 11 + documentation = "https://docs.rs/hyper-rustls/" 12 + 13 + [features] 14 + default = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] 15 + aws-lc-rs = ["rustls/aws_lc_rs"] 16 + fips = ["aws-lc-rs", "rustls/fips"] 17 + http1 = ["hyper-util/http1"] 18 + http2 = ["hyper-util/http2"] 19 + logging = ["log", "tokio-rustls/logging", "rustls/logging"] 20 + native-tokio = ["rustls-native-certs"] 21 + ring = ["rustls/ring"] 22 + tls12 = ["tokio-rustls/tls12", "rustls/tls12"] 23 + webpki-tokio = ["webpki-roots"] 24 + 25 + [dependencies] 26 + http = "1" 27 + hyper = { version = "1", default-features = false } 28 + hyper-util = { version = "0.1", default-features = false, features = ["client-legacy", "tokio"] } 29 + log = { version = "0.4.4", optional = true } 30 + pki-types = { package = "rustls-pki-types", version = "1" } 31 + rustls-native-certs = { version = "0.8", optional = true } 32 + rustls-platform-verifier = { version = "0.3", optional = true } 33 + rustls = { version = "0.23", default-features = false } 34 + tokio = "1.0" 35 + tokio-rustls = { version = "0.26", default-features = false } 36 + tower-service = "0.3" 37 + webpki-roots = { version = "0.26", optional = true } 38 + futures-util = { version = "0.3", default-features = false } 39 + 40 + [dev-dependencies] 41 + http-body-util = "0.1" 42 + hyper-util = { version = "0.1", default-features = false, features = ["server-auto"] } 43 + rustls = { version = "0.23", default-features = false, features = ["tls12"] } 44 + rustls-pemfile = "2" 45 + tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } 46 + 47 + [[example]] 48 + name = "client" 49 + path = "examples/client.rs" 50 + required-features = ["native-tokio", "http1"] 51 + 52 + [[example]] 53 + name = "server" 54 + path = "examples/server.rs" 55 + required-features = ["aws-lc-rs"] 56 + 57 + [package.metadata.docs.rs] 58 + no-default-features = true 59 + features = [ 60 + "http1", 61 + "http2", 62 + "logging", 63 + "native-tokio", 64 + "ring", 65 + "rustls-platform-verifier", 66 + "tls12", 67 + "webpki-tokio", 68 + ] 69 + rustdoc-args = ["--cfg", "docsrs"]
+10
vendor/hyper-rustls/LICENSE
··· 1 + hyper-rustls is distributed under the following three licenses: 2 + 3 + - Apache License version 2.0. 4 + - MIT license. 5 + - ISC license. 6 + 7 + These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC 8 + respectively. You may use this software under the terms of any 9 + of these licenses, at your option. 10 +
+201
vendor/hyper-rustls/LICENSE-APACHE
··· 1 + Apache License 2 + Version 2.0, January 2004 3 + http://www.apache.org/licenses/ 4 + 5 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 + 7 + 1. Definitions. 8 + 9 + "License" shall mean the terms and conditions for use, reproduction, 10 + and distribution as defined by Sections 1 through 9 of this document. 11 + 12 + "Licensor" shall mean the copyright owner or entity authorized by 13 + the copyright owner that is granting the License. 14 + 15 + "Legal Entity" shall mean the union of the acting entity and all 16 + other entities that control, are controlled by, or are under common 17 + control with that entity. For the purposes of this definition, 18 + "control" means (i) the power, direct or indirect, to cause the 19 + direction or management of such entity, whether by contract or 20 + otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 + outstanding shares, or (iii) beneficial ownership of such entity. 22 + 23 + "You" (or "Your") shall mean an individual or Legal Entity 24 + exercising permissions granted by this License. 25 + 26 + "Source" form shall mean the preferred form for making modifications, 27 + including but not limited to software source code, documentation 28 + source, and configuration files. 29 + 30 + "Object" form shall mean any form resulting from mechanical 31 + transformation or translation of a Source form, including but 32 + not limited to compiled object code, generated documentation, 33 + and conversions to other media types. 34 + 35 + "Work" shall mean the work of authorship, whether in Source or 36 + Object form, made available under the License, as indicated by a 37 + copyright notice that is included in or attached to the work 38 + (an example is provided in the Appendix below). 39 + 40 + "Derivative Works" shall mean any work, whether in Source or Object 41 + form, that is based on (or derived from) the Work and for which the 42 + editorial revisions, annotations, elaborations, or other modifications 43 + represent, as a whole, an original work of authorship. For the purposes 44 + of this License, Derivative Works shall not include works that remain 45 + separable from, or merely link (or bind by name) to the interfaces of, 46 + the Work and Derivative Works thereof. 47 + 48 + "Contribution" shall mean any work of authorship, including 49 + the original version of the Work and any modifications or additions 50 + to that Work or Derivative Works thereof, that is intentionally 51 + submitted to Licensor for inclusion in the Work by the copyright owner 52 + or by an individual or Legal Entity authorized to submit on behalf of 53 + the copyright owner. For the purposes of this definition, "submitted" 54 + means any form of electronic, verbal, or written communication sent 55 + to the Licensor or its representatives, including but not limited to 56 + communication on electronic mailing lists, source code control systems, 57 + and issue tracking systems that are managed by, or on behalf of, the 58 + Licensor for the purpose of discussing and improving the Work, but 59 + excluding communication that is conspicuously marked or otherwise 60 + designated in writing by the copyright owner as "Not a Contribution." 61 + 62 + "Contributor" shall mean Licensor and any individual or Legal Entity 63 + on behalf of whom a Contribution has been received by Licensor and 64 + subsequently incorporated within the Work. 65 + 66 + 2. Grant of Copyright License. Subject to the terms and conditions of 67 + this License, each Contributor hereby grants to You a perpetual, 68 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 + copyright license to reproduce, prepare Derivative Works of, 70 + publicly display, publicly perform, sublicense, and distribute the 71 + Work and such Derivative Works in Source or Object form. 72 + 73 + 3. Grant of Patent License. Subject to the terms and conditions of 74 + this License, each Contributor hereby grants to You a perpetual, 75 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 + (except as stated in this section) patent license to make, have made, 77 + use, offer to sell, sell, import, and otherwise transfer the Work, 78 + where such license applies only to those patent claims licensable 79 + by such Contributor that are necessarily infringed by their 80 + Contribution(s) alone or by combination of their Contribution(s) 81 + with the Work to which such Contribution(s) was submitted. If You 82 + institute patent litigation against any entity (including a 83 + cross-claim or counterclaim in a lawsuit) alleging that the Work 84 + or a Contribution incorporated within the Work constitutes direct 85 + or contributory patent infringement, then any patent licenses 86 + granted to You under this License for that Work shall terminate 87 + as of the date such litigation is filed. 88 + 89 + 4. Redistribution. You may reproduce and distribute copies of the 90 + Work or Derivative Works thereof in any medium, with or without 91 + modifications, and in Source or Object form, provided that You 92 + meet the following conditions: 93 + 94 + (a) You must give any other recipients of the Work or 95 + Derivative Works a copy of this License; and 96 + 97 + (b) You must cause any modified files to carry prominent notices 98 + stating that You changed the files; and 99 + 100 + (c) You must retain, in the Source form of any Derivative Works 101 + that You distribute, all copyright, patent, trademark, and 102 + attribution notices from the Source form of the Work, 103 + excluding those notices that do not pertain to any part of 104 + the Derivative Works; and 105 + 106 + (d) If the Work includes a "NOTICE" text file as part of its 107 + distribution, then any Derivative Works that You distribute must 108 + include a readable copy of the attribution notices contained 109 + within such NOTICE file, excluding those notices that do not 110 + pertain to any part of the Derivative Works, in at least one 111 + of the following places: within a NOTICE text file distributed 112 + as part of the Derivative Works; within the Source form or 113 + documentation, if provided along with the Derivative Works; or, 114 + within a display generated by the Derivative Works, if and 115 + wherever such third-party notices normally appear. The contents 116 + of the NOTICE file are for informational purposes only and 117 + do not modify the License. You may add Your own attribution 118 + notices within Derivative Works that You distribute, alongside 119 + or as an addendum to the NOTICE text from the Work, provided 120 + that such additional attribution notices cannot be construed 121 + as modifying the License. 122 + 123 + You may add Your own copyright statement to Your modifications and 124 + may provide additional or different license terms and conditions 125 + for use, reproduction, or distribution of Your modifications, or 126 + for any such Derivative Works as a whole, provided Your use, 127 + reproduction, and distribution of the Work otherwise complies with 128 + the conditions stated in this License. 129 + 130 + 5. Submission of Contributions. Unless You explicitly state otherwise, 131 + any Contribution intentionally submitted for inclusion in the Work 132 + by You to the Licensor shall be under the terms and conditions of 133 + this License, without any additional terms or conditions. 134 + Notwithstanding the above, nothing herein shall supersede or modify 135 + the terms of any separate license agreement you may have executed 136 + with Licensor regarding such Contributions. 137 + 138 + 6. Trademarks. This License does not grant permission to use the trade 139 + names, trademarks, service marks, or product names of the Licensor, 140 + except as required for reasonable and customary use in describing the 141 + origin of the Work and reproducing the content of the NOTICE file. 142 + 143 + 7. Disclaimer of Warranty. Unless required by applicable law or 144 + agreed to in writing, Licensor provides the Work (and each 145 + Contributor provides its Contributions) on an "AS IS" BASIS, 146 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 + implied, including, without limitation, any warranties or conditions 148 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 + PARTICULAR PURPOSE. You are solely responsible for determining the 150 + appropriateness of using or redistributing the Work and assume any 151 + risks associated with Your exercise of permissions under this License. 152 + 153 + 8. Limitation of Liability. In no event and under no legal theory, 154 + whether in tort (including negligence), contract, or otherwise, 155 + unless required by applicable law (such as deliberate and grossly 156 + negligent acts) or agreed to in writing, shall any Contributor be 157 + liable to You for damages, including any direct, indirect, special, 158 + incidental, or consequential damages of any character arising as a 159 + result of this License or out of the use or inability to use the 160 + Work (including but not limited to damages for loss of goodwill, 161 + work stoppage, computer failure or malfunction, or any and all 162 + other commercial damages or losses), even if such Contributor 163 + has been advised of the possibility of such damages. 164 + 165 + 9. Accepting Warranty or Additional Liability. While redistributing 166 + the Work or Derivative Works thereof, You may choose to offer, 167 + and charge a fee for, acceptance of support, warranty, indemnity, 168 + or other liability obligations and/or rights consistent with this 169 + License. However, in accepting such obligations, You may act only 170 + on Your own behalf and on Your sole responsibility, not on behalf 171 + of any other Contributor, and only if You agree to indemnify, 172 + defend, and hold each Contributor harmless for any liability 173 + incurred by, or claims asserted against, such Contributor by reason 174 + of your accepting any such warranty or additional liability. 175 + 176 + END OF TERMS AND CONDITIONS 177 + 178 + APPENDIX: How to apply the Apache License to your work. 179 + 180 + To apply the Apache License to your work, attach the following 181 + boilerplate notice, with the fields enclosed by brackets "[]" 182 + replaced with your own identifying information. (Don't include 183 + the brackets!) The text should be enclosed in the appropriate 184 + comment syntax for the file format. We also recommend that a 185 + file or class name and description of purpose be included on the 186 + same "printed page" as the copyright notice for easier 187 + identification within third-party archives. 188 + 189 + Copyright [yyyy] [name of copyright owner] 190 + 191 + Licensed under the Apache License, Version 2.0 (the "License"); 192 + you may not use this file except in compliance with the License. 193 + You may obtain a copy of the License at 194 + 195 + http://www.apache.org/licenses/LICENSE-2.0 196 + 197 + Unless required by applicable law or agreed to in writing, software 198 + distributed under the License is distributed on an "AS IS" BASIS, 199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 + See the License for the specific language governing permissions and 201 + limitations under the License.
+15
vendor/hyper-rustls/LICENSE-ISC
··· 1 + ISC License (ISC) 2 + Copyright (c) 2016, Joseph Birr-Pixton <jpixton@gmail.com> 3 + 4 + Permission to use, copy, modify, and/or distribute this software for 5 + any purpose with or without fee is hereby granted, provided that the 6 + above copyright notice and this permission notice appear in all copies. 7 + 8 + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 + WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 + WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 + AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 + DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 + PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 14 + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 15 + THIS SOFTWARE.
+25
vendor/hyper-rustls/LICENSE-MIT
··· 1 + Copyright (c) 2016 Joseph Birr-Pixton <jpixton@gmail.com> 2 + 3 + Permission is hereby granted, free of charge, to any 4 + person obtaining a copy of this software and associated 5 + documentation files (the "Software"), to deal in the 6 + Software without restriction, including without 7 + limitation the rights to use, copy, modify, merge, 8 + publish, distribute, sublicense, and/or sell copies of 9 + the Software, and to permit persons to whom the Software 10 + is furnished to do so, subject to the following 11 + conditions: 12 + 13 + The above copyright notice and this permission notice 14 + shall be included in all copies or substantial portions 15 + of the Software. 16 + 17 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 + TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 + SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 + DEALINGS IN THE SOFTWARE.
+64
vendor/hyper-rustls/README.md
··· 1 + # hyper-rustls 2 + 3 + This is an integration between the [Rustls TLS stack](https://github.com/rustls/rustls) and the 4 + [hyper HTTP library](https://github.com/hyperium/hyper). 5 + 6 + [![Build Status](https://github.com/rustls/hyper-rustls/actions/workflows/build.yml/badge.svg)](https://github.com/rustls/hyper-rustls/actions) 7 + [![Crate](https://img.shields.io/crates/v/hyper-rustls.svg)](https://crates.io/crates/hyper-rustls) 8 + [![Documentation](https://docs.rs/hyper-rustls/badge.svg)](https://docs.rs/hyper-rustls) 9 + 10 + # Release history 11 + 12 + Release history can be found [on GitHub](https://github.com/rustls/hyper-rustls/releases). 13 + 14 + # License 15 + 16 + hyper-rustls is distributed under the following three licenses: 17 + 18 + - Apache License version 2.0. 19 + - MIT license. 20 + - ISC license. 21 + 22 + These are included as LICENSE-APACHE, LICENSE-MIT and LICENSE-ISC respectively. You may use this 23 + software under the terms of any of these licenses, at your option. 24 + 25 + ## Running examples 26 + 27 + ### server 28 + 29 + ```bash 30 + cargo run --example server 31 + ``` 32 + 33 + ### client 34 + 35 + ```bash 36 + cargo run --example client "https://docs.rs/hyper-rustls/latest/hyper_rustls/" 37 + ``` 38 + 39 + ## Crate features 40 + 41 + This crate exposes a number of features to add support for different portions of `hyper-util`, 42 + `rustls`, and other dependencies. 43 + 44 + | Feature flag | Enabled by default | Description | 45 + | ------------ | ------------------ | ----------- | 46 + | `aws-lc-rs` | **yes** | Enables use of the [AWS-LC][aws-lc-rs] backend for [`rustls`][rustls] | 47 + | `http1` | **yes** | Enables HTTP/1 support in [`hyper-util`][hyper-util] | 48 + | `http2` | **no** | Enables HTTP/2 support in [`hyper-util`][hyper-util] | 49 + | `webpki-tokio` | **no** | Uses a compiled-in set of root certificates trusted by Mozilla (via [`webpki-roots`][webpki-roots]) | 50 + | `native-tokio` | **yes** | Use the platform's native certificate store at runtime (via [`rustls-native-certs`][rustls-native-certs]) | 51 + | `rustls-platform-verifier` | **no** | Use the operating system's verifier for certificate verification (via [`rustls-platform-verifier`][rustls-platform-verifier]) | 52 + | `ring` | **no** | Enables use of the [`ring`][ring] backend for [`rustls`][rustls] | 53 + | `tls12` | **yes** | Enables support for TLS 1.2 (only TLS 1.3 supported when disabled) | 54 + | `logging` | **yes** | Enables logging of protocol-level diagnostics and errors via [`log`][log] | 55 + | `fips` | **no** | Enables support for using a FIPS 140-3 compliant backend via AWS-LC (enables `aws-lc-rs` feature) | 56 + 57 + [aws-lc-rs]: https://docs.rs/aws-lc-rs 58 + [rustls]: https://docs.rs/rustls 59 + [hyper-util]: https://docs.rs/hyper-util 60 + [webpki-roots]: https://docs.rs/webpki-roots 61 + [rustls-native-certs]: https://docs.rs/rustls-native-certs 62 + [rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier 63 + [ring]: https://docs.rs/ring 64 + [log]: https://docs.rs/log
+26
vendor/hyper-rustls/RELEASING.md
··· 1 + # Making a hyper-rustls release 2 + 3 + This is a checklist for steps to make before/after making a rustls release. 4 + 5 + 1. Attend to the README.md: this appears on crates.io for the release, and can't be edited after 6 + the fact. 7 + - Ensure the version has a good set of release notes. Move old release notes to OLDCHANGES.md 8 + if this is getting excessively long. 9 + - Write the version and date of the release. 10 + 2. Run `cargo update` followed by `cargo outdated`, to check if we have any 11 + dependency updates which are not already automatically taken by their semver specs. 12 + - If we do, take them if possible with separate commits (but there should've been 13 + dependabot PRs submitted for these already.) 14 + 3. Now run `cargo test --all-features` to ensure our tests continue to pass with the 15 + updated dependencies. 16 + 4. Update `Cargo.toml` to set the correct version. 17 + 5. Make a commit with the above changes, something like 'Prepare $VERSION'. This 18 + should not contain functional changes: just versions numbers, and markdown changes. 19 + 6. Do a dry run: check `cargo publish --dry-run` 20 + 7. Push the above commit. Wait for CI to confirm it as green. 21 + - Any red _should_ naturally block the release. 22 + - If rustc nightly is broken, this _may_ be acceptable if the reason is understood 23 + and does not point to a defect. 24 + 8. Tag the released version: `git tag -m '0.20.0' v/0.20.0` 25 + 9. Push the tag: `git push --tags` 26 + 10. Do the release: `cargo publish`.
+105
vendor/hyper-rustls/examples/client.rs
··· 1 + //! Simple HTTPS GET client based on hyper-rustls 2 + //! 3 + //! First parameter is the mandatory URL to GET. 4 + //! Second parameter is an optional path to CA store. 5 + use http::Uri; 6 + use http_body_util::{BodyExt, Empty}; 7 + use hyper::body::Bytes; 8 + use hyper_rustls::ConfigBuilderExt; 9 + use hyper_util::{client::legacy::Client, rt::TokioExecutor}; 10 + use rustls::RootCertStore; 11 + 12 + use std::str::FromStr; 13 + use std::{env, fs, io}; 14 + 15 + fn main() { 16 + // Send GET request and inspect result, with proper error handling. 17 + if let Err(e) = run_client() { 18 + eprintln!("FAILED: {}", e); 19 + std::process::exit(1); 20 + } 21 + } 22 + 23 + fn error(err: String) -> io::Error { 24 + io::Error::new(io::ErrorKind::Other, err) 25 + } 26 + 27 + #[tokio::main] 28 + async fn run_client() -> io::Result<()> { 29 + // Set a process wide default crypto provider. 30 + #[cfg(feature = "ring")] 31 + let _ = rustls::crypto::ring::default_provider().install_default(); 32 + #[cfg(feature = "aws-lc-rs")] 33 + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); 34 + 35 + // First parameter is target URL (mandatory). 36 + let url = match env::args().nth(1) { 37 + Some(ref url) => Uri::from_str(url).map_err(|e| error(format!("{}", e)))?, 38 + None => { 39 + println!("Usage: client <url> <ca_store>"); 40 + return Ok(()); 41 + } 42 + }; 43 + 44 + // Second parameter is custom Root-CA store (optional, defaults to native cert store). 45 + let mut ca = match env::args().nth(2) { 46 + Some(ref path) => { 47 + let f = fs::File::open(path) 48 + .map_err(|e| error(format!("failed to open {}: {}", path, e)))?; 49 + let rd = io::BufReader::new(f); 50 + Some(rd) 51 + } 52 + None => None, 53 + }; 54 + 55 + // Prepare the TLS client config 56 + let tls = match ca { 57 + Some(ref mut rd) => { 58 + // Read trust roots 59 + let certs = rustls_pemfile::certs(rd).collect::<Result<Vec<_>, _>>()?; 60 + let mut roots = RootCertStore::empty(); 61 + roots.add_parsable_certificates(certs); 62 + // TLS client config using the custom CA store for lookups 63 + rustls::ClientConfig::builder() 64 + .with_root_certificates(roots) 65 + .with_no_client_auth() 66 + } 67 + // Default TLS client config with native roots 68 + None => rustls::ClientConfig::builder() 69 + .with_native_roots()? 70 + .with_no_client_auth(), 71 + }; 72 + // Prepare the HTTPS connector 73 + let https = hyper_rustls::HttpsConnectorBuilder::new() 74 + .with_tls_config(tls) 75 + .https_or_http() 76 + .enable_http1() 77 + .build(); 78 + 79 + // Build the hyper client from the HTTPS connector. 80 + let client: Client<_, Empty<Bytes>> = Client::builder(TokioExecutor::new()).build(https); 81 + 82 + // Prepare a chain of futures which sends a GET request, inspects 83 + // the returned headers, collects the whole body and prints it to 84 + // stdout. 85 + let fut = async move { 86 + let res = client 87 + .get(url) 88 + .await 89 + .map_err(|e| error(format!("Could not get: {:?}", e)))?; 90 + println!("Status:\n{}", res.status()); 91 + println!("Headers:\n{:#?}", res.headers()); 92 + 93 + let body = res 94 + .into_body() 95 + .collect() 96 + .await 97 + .map_err(|e| error(format!("Could not get body: {:?}", e)))? 98 + .to_bytes(); 99 + println!("Body:\n{}", String::from_utf8_lossy(&body)); 100 + 101 + Ok(()) 102 + }; 103 + 104 + fut.await 105 + }
+25
vendor/hyper-rustls/examples/openssl.cnf
··· 1 + 2 + [ v3_end ] 3 + basicConstraints = critical,CA:false 4 + keyUsage = nonRepudiation, digitalSignature 5 + subjectKeyIdentifier = hash 6 + authorityKeyIdentifier = keyid:always,issuer:always 7 + subjectAltName = @alt_names 8 + 9 + [ v3_client ] 10 + basicConstraints = critical,CA:false 11 + keyUsage = nonRepudiation, digitalSignature 12 + extendedKeyUsage = critical, clientAuth 13 + subjectKeyIdentifier = hash 14 + authorityKeyIdentifier = keyid:always,issuer:always 15 + 16 + [ v3_inter ] 17 + subjectKeyIdentifier = hash 18 + extendedKeyUsage = critical, serverAuth, clientAuth 19 + basicConstraints = CA:true 20 + keyUsage = cRLSign, keyCertSign, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign 21 + 22 + [ alt_names ] 23 + DNS.1 = testserver.com 24 + DNS.2 = second.testserver.com 25 + DNS.3 = localhost
+56
vendor/hyper-rustls/examples/refresh-certificates.sh
··· 1 + #!/bin/sh 2 + 3 + set -xe 4 + 5 + openssl req -nodes \ 6 + -x509 \ 7 + -days 3650 \ 8 + -newkey rsa:4096 \ 9 + -keyout ca.key \ 10 + -out ca.cert \ 11 + -sha256 \ 12 + -batch \ 13 + -subj "/CN=ponytown RSA CA" 14 + 15 + openssl req -nodes \ 16 + -newkey rsa:3072 \ 17 + -keyout inter.key \ 18 + -out inter.req \ 19 + -sha256 \ 20 + -batch \ 21 + -subj "/CN=ponytown RSA level 2 intermediate" 22 + 23 + openssl req -nodes \ 24 + -newkey rsa:2048 \ 25 + -keyout end.key \ 26 + -out end.req \ 27 + -sha256 \ 28 + -batch \ 29 + -subj "/CN=testserver.com" 30 + 31 + openssl rsa \ 32 + -in end.key \ 33 + -out sample.rsa 34 + 35 + openssl x509 -req \ 36 + -in inter.req \ 37 + -out inter.cert \ 38 + -CA ca.cert \ 39 + -CAkey ca.key \ 40 + -sha256 \ 41 + -days 3650 \ 42 + -set_serial 123 \ 43 + -extensions v3_inter -extfile openssl.cnf 44 + 45 + openssl x509 -req \ 46 + -in end.req \ 47 + -out end.cert \ 48 + -CA inter.cert \ 49 + -CAkey inter.key \ 50 + -sha256 \ 51 + -days 2000 \ 52 + -set_serial 456 \ 53 + -extensions v3_end -extfile openssl.cnf 54 + 55 + cat end.cert inter.cert ca.cert > sample.pem 56 + rm *.key *.cert *.req
+79
vendor/hyper-rustls/examples/sample.pem
··· 1 + -----BEGIN CERTIFICATE----- 2 + MIIEADCCAmigAwIBAgICAcgwDQYJKoZIhvcNAQELBQAwLDEqMCgGA1UEAwwhcG9u 3 + eXRvd24gUlNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMB4XDTIyMDcwNDE0MzA1OFoX 4 + DTI3MTIyNTE0MzA1OFowGTEXMBUGA1UEAwwOdGVzdHNlcnZlci5jb20wggEiMA0G 5 + CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDL35qLQLIqswCmHJxyczYF2p0YxXCq 6 + gMvtRcKVElnifPMFrbGCY1aYBmhIiXPGRwhfythAtYfDQsrXFADZd52JPgZCR/u6 7 + DQMqKD2lcvFQkf7Kee/fNTOuQTQPh1XQx4ntxvicSATwEnuU28NwVnOU//Zzq2xn 8 + Q34gUQNHWp1pN+B1La7emm/Ucgs1/2hMxwCZYUnRoiUoRGXUSzZuWokDOstPNkjc 9 + +AjHmxONgowogmL2jKN9BjBw/8psGoqEOjMO+Lb9iekOCzX4kqHaRUbTlbSAviQu 10 + 2Q115xiZCBCZVtNE6DUG25buvpMSEXwpLd96nLywbrSCyueC7cd01/hpAgMBAAGj 11 + gb4wgbswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFHGnzC5Q 12 + A62Wmv4zfMk/kf/BxHevMEIGA1UdIwQ7MDmAFDMRUvwxXbYDBCxOdQ9xfBnNWUz0 13 + oR6kHDAaMRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0GCAXswOwYDVR0RBDQwMoIO 14 + dGVzdHNlcnZlci5jb22CFXNlY29uZC50ZXN0c2VydmVyLmNvbYIJbG9jYWxob3N0 15 + MA0GCSqGSIb3DQEBCwUAA4IBgQBqKNIM/JBGRmGEopm5/WNKV8UoxKPA+2jR020t 16 + RumXMAnJEfhsivF+Zw/rDmSDpmts/3cIlesKi47f13q4Mfj1QytQUDrsuQEyRTrV 17 + Go6BOQQ4dkS+IqnIfSuue70wpvrZHhRHNFdFt9qM5wCLQokXlP988sEWUmyPPCbO 18 + 1BEpwWcP1kx+PdY8NKOhMnfq2RfluI/m4MA4NxJqAWajAhIbDNbvP8Ov4a71HPa6 19 + b1q9qIQE1ut8KycTrm9K32bVbvMHvR/TPUue8W0VvV2rWTGol5TSNgEQb9w6Kyf7 20 + N5HlRl9kZB4K8ckWH/JVn0pYNBQPgwbcUbJ/jp6w+LHrh+UW75maOY+IGjVICud8 21 + 6Rc5DZZ2+AAbXJQZ1HMPrw9SW/16Eh/A4CIEsvbu9J+7IoSzhgcKFzOCUojzzRSj 22 + iU7w/HsvpltmVCAZcZ/VARFbe1By2wXX2GSw2p2FVC8orXs76QyruPAVgSHCTVes 23 + zzBo6GLScO/3b6uAcPM3MHRGGvE= 24 + -----END CERTIFICATE----- 25 + -----BEGIN CERTIFICATE----- 26 + MIIEnzCCAoegAwIBAgIBezANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9wb255 27 + dG93biBSU0EgQ0EwHhcNMjIwNzA0MTQzMDU4WhcNMzIwNzAxMTQzMDU4WjAsMSow 28 + KAYDVQQDDCFwb255dG93biBSU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwggGiMA0G 29 + CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCsTkd2SKiy3yy20lygOhKfOySo3qpq 30 + TZVrpW11vQ58+6EcetXRnzIIK0HyhPmZrv9XKPpQclJvfY9jADNtu2CSj/v15OSB 31 + Love3GzmXSZz2A8QUZBPWx6HczDG1hFGzrCZPKzpeLnFD1LPsKCUkUOHl1acyy24 32 + DaCacQJPzPQWbMhbGmYRlDNb+2R2K6UKMAEVe4IOTv2aSIKDGLI+xlaBXYAJj48L 33 + //9eNmR3bMP3kkNKOKaaBk8vnYxKpZ+8ZHeHTmYWR9x1ZoMcbA9lKUwRpKAjY5JJ 34 + NVZMDmjlVQVvvBrvhgz/zgXtfuaQCryZ0f1sEY/zXhdealo3fGVomeoniD4XwA1c 35 + oaUFkbo5IM5HU/pXyAGRerDyhYLgRqQZMIRauvKRPN3jLsPOEQ0+gnXUUTr/YGIE 36 + KY3/Axg4P3hzZCFqJ5IgkgWZr/dKr9p/0cxSUGHTVcpEFOlkKIIIdRuR7Ng5sJml 37 + u7PAMWt6T+x02ORs1/WkyP7LyPQmuugYTicCAwEAAaNeMFwwHQYDVR0OBBYEFDMR 38 + UvwxXbYDBCxOdQ9xfBnNWUz0MCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEF 39 + BQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jANBgkqhkiG9w0BAQsFAAOC 40 + AgEAYzqmX+cNPgVD2HWgbeimUraTpI9JP5P4TbOHWmaJKecoy3Hwr71xyAOGiVXL 41 + urk1ZZe8n++GwuDEgRajN3HO9LR1Pu9qVIzTYIsz0ORRQHxujnF7CxK/I/vrIgde 42 + pddUdHNS0Y0g8J1emH9BgoD8a2YsGX4iDY4S4hIGBbGvQp9z8U/uG1mViAmlXybM 43 + b8bf0dx0tEFUyu8jsQP6nFLY/HhkEcvU6SnOzZHRsFko6NE44VIsHLd2+LS2LCM/ 44 + NfAoTzgvj41M3zQCZapaHZc9KXfdcCvEFaySKGfEZeQTUR5W0FHsF5I4NLGryf5L 45 + h3ENQ1tgBTO5WnqL/5rbgv6va9VionPM5sbEwAcancejnkVs3NoYPIPPgBFjaFmL 46 + hNTpT9H2owdZvEwNDChVS0b8ukNNd4cERtvy0Ohc3mk0LGN0ABzrud0fIqa51LMh 47 + 0N3dkPkiZ4XYk4yLJ5EwCrCNNH50QkGCOWpInKIPeSYcALGgBDbCDLv6rV3oSKrV 48 + tHCZQwXVKKgU4AQu7hlHBwJ61cH44ksydOidW3MNq1kDIp7ST8s7gVrItNgFnG+L 49 + Jpo270riwSUlWDY4hXw5Ff5lE+bWCmFyyOkLevDkD9v8M4HdwEVvafYYwn75fCIS 50 + 5OnpSeIB08kKqCtW1WBwki0rYJjWqdzI7Z1MQ/AyScAKiGM= 51 + -----END CERTIFICATE----- 52 + -----BEGIN CERTIFICATE----- 53 + MIIEsDCCApgCCQCfkxy3a+AgNjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9w 54 + b255dG93biBSU0EgQ0EwHhcNMjIwNzA0MTQzMDU3WhcNMzIwNzAxMTQzMDU3WjAa 55 + MRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC 56 + DwAwggIKAoICAQCj6nW8pnN50UsH2NjL97xZKxlXPe5ptXfvqXczMsw0vB3gI4xJ 57 + Tdmrnqo0K+VOH7vh+UXcOj2ZMY2ou6oDDK5Qpu9bvGPBIJH/rC1Ti2+u5Y4KTIUc 58 + jWAtzQJeFn8+oCMfskpLdtlWLRdAuwqNHjvxXdd2JnsX1Wid85U/rG2SNPLGjJAF 59 + xG7xzZC4VSO2WIXTGRMUkZfFc8fhWMjo3GaeF/qYjzfHDPWN/ll/7vfxyXJO/ohw 60 + FzpJSZtKmI+6PLxqB/oFrKfTDQUGzxjfHp187bI3eyUFMJsp18/tLYkLyxSWIg3o 61 + bq7ZVimHd1UG2Vb5Y+5pZkh22jmJ6bAa/kmNNwbsD+5vJhW1myGhmZSxkreYPWnS 62 + 6ELrSMvbXccFfTYmdBlWsZx/zUVUzVCPe9jdJki2VXlicohqtvBQqe6LGGO37vvv 63 + Gwu1yzQ/rJy47rnaao7fSxqM8nsDjNR2Ev1v031QpEMWjfgUW0roW3H58RZSx+kU 64 + gzIS2CjJIqKxCp894FUQbC6r0wwAuKltl3ywz5qWkxY0O9bXS0YdEXiri5pdsWjr 65 + 84shVVQwnoVD9539CLSdHZjlOCAzvSWHZH6ta2JZjUfYYz8cLyv2c2+y9BYrlvHw 66 + T7U7BqzngUk72gcRXd5+Onp+16gGxpGJqaxqj94Nh/yTUnr2Jd9YaXeFmQIDAQAB 67 + MA0GCSqGSIb3DQEBCwUAA4ICAQBzIRVRt3Yaw60tpkyz/i1xbKCbtC+HqYTEsXvZ 68 + RvZ5X1qyLAcmu4EW9RHXnlLiawDbES6lCMFfdBUK03Wis7socvoFUCBRW337F4z2 69 + IivHfIge4u+w5ouUKPzcpj6oeuR06tmNytYbno6l8tXJpm1eeO4KNZ0ZtodmyB5D 70 + yLrplFgxTdGGgyvxt8LoeLwGmPCyVt35x/Mz6x2lcq1+r7QJZ9sENhQYuA8UqHrw 71 + fmNoVIMXMEcPLcWtFl6nKTK9LrqAu1jgTBqGGZKRn5CYBBK3pNEGKiOIsZXDbyFS 72 + F59teFpJjyeJTbUbLxXDa15J6ExkHV9wFLEvfu/nzQzg8D9yzczSdbDkE2rrrL+s 73 + Q/H/pIXO/DesCWQ37VALn3B5gm9UBd5uogbSw8eamiwRFLQ0snP80pJQGJoTNn0P 74 + wrLLUf2gsKC2262igiA+imepm5wxbV9XGVZfHJgxCi5Zqrf6aWnjIqD2YtDvAHhs 75 + V8ZWN3QTjdnEcQbG0544rocoLNX/FzmyDgjfZKY5r6wt+FWNc/R4clkF+KxasxqB 76 + HdBs8j0lGV3ujvNXASLq9HI6VxZayrSfkR73hADCXIM/wzynKwMarvA4SXwYX9Pd 77 + cJ4+FMqrevPpamMHUsNndS0KfDTdjDp+TSBf87yiyRkD1Ri4ePslyfNvRyv3Xs7k 78 + 47YFzA== 79 + -----END CERTIFICATE-----
+27
vendor/hyper-rustls/examples/sample.rsa
··· 1 + -----BEGIN RSA PRIVATE KEY----- 2 + MIIEpAIBAAKCAQEAy9+ai0CyKrMAphyccnM2BdqdGMVwqoDL7UXClRJZ4nzzBa2x 3 + gmNWmAZoSIlzxkcIX8rYQLWHw0LK1xQA2XediT4GQkf7ug0DKig9pXLxUJH+ynnv 4 + 3zUzrkE0D4dV0MeJ7cb4nEgE8BJ7lNvDcFZzlP/2c6tsZ0N+IFEDR1qdaTfgdS2u 5 + 3ppv1HILNf9oTMcAmWFJ0aIlKERl1Es2blqJAzrLTzZI3PgIx5sTjYKMKIJi9oyj 6 + fQYwcP/KbBqKhDozDvi2/YnpDgs1+JKh2kVG05W0gL4kLtkNdecYmQgQmVbTROg1 7 + BtuW7r6TEhF8KS3fepy8sG60gsrngu3HdNf4aQIDAQABAoIBAFTehqVFj2W7EqAT 8 + 9QSn9WtGcHNpbddsunfRvIj2FLj2LuzEO8r9s4Sh1jOsFKgL1e6asJ9vck7UtUAH 9 + sbrV0pzZVx2sfZwb4p9gFRmU2eQigqCjVjnjGdqGhjeYrR62kjKLy96zFGskJpH3 10 + UkqnkoIKc/v+9qeeLxkg4G6JyFGOFHJAZEraxoGydJk9n/yBEZ/+3W7JUJaGOUNU 11 + M7BYsCS2VOJr+cCqmCk1j8NvYvWWxTPsIXgGJl4EOoskzlzJnYLdh9fPFZu3uOIx 12 + hpm3DBNp6X+qXf1lmx9EdpyeXKpLFIgJM7+nw2uWzxW7XMlRERi+5Tprc/pjrqUq 13 + gpfyvMkCgYEA909QcJpS3qHoWyxGbI1zosVIZXdnj8L+GF/2kEQEU5iEYT+2M1U+ 14 + gCPLr49gNwkD1FdBSCy+Fw20zi35jGmxNwhgp4V94CGYzqwQzpnvgIRBMiAIoEwI 15 + CD5/t34DZ/82u8Gb7UYVrzOD54rJ628Q+tJEJak3TqoShbvcxJC/rXMCgYEA0wmO 16 + SRoxrBE3rFzNQkqHbMHLe9LksW9YSIXdMBjq4DhzQEwI0YgPLajXnsLurqHaJrQA 17 + JPtYkqiJkV7rvJLBo5wxwU+O2JKKa2jcMwuCZ4hOg5oBfK6ES9QJZUL7kDe2vsWy 18 + rL+rnxJheUjDPBTopGHuuc9Nogid35CE0wy7S7MCgYArxB+KLeVofOKv79/uqgHC 19 + 1oL/Yegz6uAo1CLAWSki2iTjSPEnmHhdGPic8xSl6LSCyYZGDZT+Y3CR5FT7YmD4 20 + SkVAoEEsfwWZ3Z2D0n4uEjmvczfTlmD9hIH5qRVVPDcldxfvH64KuWUofslJHvi0 21 + Sq3AtHeTNknc3Ogu6SbivQKBgQC4ZAsMWHS6MTkBwvwdRd1Z62INyNDFL9JlW4FN 22 + uxfN3cTlkwnJeiY48OOk9hFySDzBwFi3910Gl3fLqrIyy8+hUqIuk4LuO+vxuWdc 23 + uluwdmqTlgZimGFDl/q1nXcMJYHo4fgh9D7R+E9ul2Luph43MtJRS447W2gFpNJJ 24 + TUCA/QKBgQC07GFP2BN74UvL12f+FpZvE/UFtWnSZ8yJSq8oYpIbhmoF5EUF+XdA 25 + E2y3l1cvmDJFo4RNZl+IQIbHACR3y1XOnh4/B9fMEsVQHK3x8exPk1vAk687bBG8 26 + TVDmdP52XEKHplcVoYKvGzw/wsObLAGyIbJ00t1VPU+7guTPsc+H/w== 27 + -----END RSA PRIVATE KEY-----
+138
vendor/hyper-rustls/examples/server.rs
··· 1 + //! Simple HTTPS echo service based on hyper_util and rustls 2 + //! 3 + //! First parameter is the mandatory port to use. 4 + //! Certificate and private key are hardcoded to sample files. 5 + //! hyper will automatically use HTTP/2 if a client starts talking HTTP/2, 6 + //! otherwise HTTP/1.1 will be used. 7 + 8 + use std::net::{Ipv4Addr, SocketAddr}; 9 + use std::sync::Arc; 10 + use std::{env, fs, io}; 11 + 12 + use http::{Method, Request, Response, StatusCode}; 13 + use http_body_util::{BodyExt, Full}; 14 + use hyper::body::{Bytes, Incoming}; 15 + use hyper::service::service_fn; 16 + use hyper_util::rt::{TokioExecutor, TokioIo}; 17 + use hyper_util::server::conn::auto::Builder; 18 + use pki_types::{CertificateDer, PrivateKeyDer}; 19 + use rustls::ServerConfig; 20 + use tokio::net::TcpListener; 21 + use tokio_rustls::TlsAcceptor; 22 + 23 + fn main() { 24 + // Serve an echo service over HTTPS, with proper error handling. 25 + if let Err(e) = run_server() { 26 + eprintln!("FAILED: {}", e); 27 + std::process::exit(1); 28 + } 29 + } 30 + 31 + fn error(err: String) -> io::Error { 32 + io::Error::new(io::ErrorKind::Other, err) 33 + } 34 + 35 + #[tokio::main] 36 + async fn run_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { 37 + // Set a process wide default crypto provider. 38 + #[cfg(feature = "ring")] 39 + let _ = rustls::crypto::ring::default_provider().install_default(); 40 + #[cfg(feature = "aws-lc-rs")] 41 + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); 42 + 43 + // First parameter is port number (optional, defaults to 1337) 44 + let port = match env::args().nth(1) { 45 + Some(ref p) => p.parse()?, 46 + None => 1337, 47 + }; 48 + let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port); 49 + 50 + // Load public certificate. 51 + let certs = load_certs("examples/sample.pem")?; 52 + // Load private key. 53 + let key = load_private_key("examples/sample.rsa")?; 54 + 55 + println!("Starting to serve on https://{}", addr); 56 + 57 + // Create a TCP listener via tokio. 58 + let incoming = TcpListener::bind(&addr).await?; 59 + 60 + // Build TLS configuration. 61 + let mut server_config = ServerConfig::builder() 62 + .with_no_client_auth() 63 + .with_single_cert(certs, key) 64 + .map_err(|e| error(e.to_string()))?; 65 + server_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()]; 66 + let tls_acceptor = TlsAcceptor::from(Arc::new(server_config)); 67 + 68 + let service = service_fn(echo); 69 + 70 + loop { 71 + let (tcp_stream, _remote_addr) = incoming.accept().await?; 72 + 73 + let tls_acceptor = tls_acceptor.clone(); 74 + tokio::spawn(async move { 75 + let tls_stream = match tls_acceptor.accept(tcp_stream).await { 76 + Ok(tls_stream) => tls_stream, 77 + Err(err) => { 78 + eprintln!("failed to perform tls handshake: {err:#}"); 79 + return; 80 + } 81 + }; 82 + if let Err(err) = Builder::new(TokioExecutor::new()) 83 + .serve_connection(TokioIo::new(tls_stream), service) 84 + .await 85 + { 86 + eprintln!("failed to serve connection: {err:#}"); 87 + } 88 + }); 89 + } 90 + } 91 + 92 + // Custom echo service, handling two different routes and a 93 + // catch-all 404 responder. 94 + async fn echo(req: Request<Incoming>) -> Result<Response<Full<Bytes>>, hyper::Error> { 95 + let mut response = Response::new(Full::default()); 96 + match (req.method(), req.uri().path()) { 97 + // Help route. 98 + (&Method::GET, "/") => { 99 + *response.body_mut() = Full::from("Try POST /echo\n"); 100 + } 101 + // Echo service route. 102 + (&Method::POST, "/echo") => { 103 + *response.body_mut() = Full::from( 104 + req.into_body() 105 + .collect() 106 + .await? 107 + .to_bytes(), 108 + ); 109 + } 110 + // Catch-all 404. 111 + _ => { 112 + *response.status_mut() = StatusCode::NOT_FOUND; 113 + } 114 + }; 115 + Ok(response) 116 + } 117 + 118 + // Load public certificate from file. 119 + fn load_certs(filename: &str) -> io::Result<Vec<CertificateDer<'static>>> { 120 + // Open certificate file. 121 + let certfile = fs::File::open(filename) 122 + .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?; 123 + let mut reader = io::BufReader::new(certfile); 124 + 125 + // Load and return certificate. 126 + rustls_pemfile::certs(&mut reader).collect() 127 + } 128 + 129 + // Load private key from file. 130 + fn load_private_key(filename: &str) -> io::Result<PrivateKeyDer<'static>> { 131 + // Open keyfile. 132 + let keyfile = fs::File::open(filename) 133 + .map_err(|e| error(format!("failed to open {}: {}", filename, e)))?; 134 + let mut reader = io::BufReader::new(keyfile); 135 + 136 + // Load and return a single private key. 137 + rustls_pemfile::private_key(&mut reader).map(|key| key.unwrap()) 138 + }
+107
vendor/hyper-rustls/src/config.rs
··· 1 + #[cfg(feature = "rustls-native-certs")] 2 + use std::io; 3 + #[cfg(feature = "rustls-platform-verifier")] 4 + use std::sync::Arc; 5 + 6 + #[cfg(any( 7 + feature = "rustls-platform-verifier", 8 + feature = "rustls-native-certs", 9 + feature = "webpki-roots" 10 + ))] 11 + use rustls::client::WantsClientCert; 12 + use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; 13 + #[cfg(feature = "rustls-native-certs")] 14 + use rustls_native_certs::CertificateResult; 15 + 16 + /// Methods for configuring roots 17 + /// 18 + /// This adds methods (gated by crate features) for easily configuring 19 + /// TLS server roots a rustls ClientConfig will trust. 20 + pub trait ConfigBuilderExt { 21 + /// Use the platform's native verifier to verify server certificates. 22 + /// 23 + /// See the documentation for [rustls-platform-verifier] for more details. 24 + /// 25 + /// [rustls-platform-verifier]: https://docs.rs/rustls-platform-verifier 26 + #[cfg(feature = "rustls-platform-verifier")] 27 + fn with_platform_verifier(self) -> ConfigBuilder<ClientConfig, WantsClientCert>; 28 + 29 + /// This configures the platform's trusted certs, as implemented by 30 + /// rustls-native-certs 31 + /// 32 + /// This will return an error if no valid certs were found. In that case, 33 + /// it's recommended to use `with_webpki_roots`. 34 + #[cfg(feature = "rustls-native-certs")] 35 + fn with_native_roots(self) -> Result<ConfigBuilder<ClientConfig, WantsClientCert>, io::Error>; 36 + 37 + /// This configures the webpki roots, which are Mozilla's set of 38 + /// trusted roots as packaged by webpki-roots. 39 + #[cfg(feature = "webpki-roots")] 40 + fn with_webpki_roots(self) -> ConfigBuilder<ClientConfig, WantsClientCert>; 41 + } 42 + 43 + impl ConfigBuilderExt for ConfigBuilder<ClientConfig, WantsVerifier> { 44 + #[cfg(feature = "rustls-platform-verifier")] 45 + fn with_platform_verifier(self) -> ConfigBuilder<ClientConfig, WantsClientCert> { 46 + self.dangerous() 47 + .with_custom_certificate_verifier(Arc::new( 48 + rustls_platform_verifier::Verifier::default(), 49 + )) 50 + } 51 + 52 + #[cfg(feature = "rustls-native-certs")] 53 + #[cfg_attr(not(feature = "logging"), allow(unused_variables))] 54 + fn with_native_roots(self) -> Result<ConfigBuilder<ClientConfig, WantsClientCert>, io::Error> { 55 + let mut roots = rustls::RootCertStore::empty(); 56 + let mut valid_count = 0; 57 + let mut invalid_count = 0; 58 + 59 + let CertificateResult { certs, errors, .. } = rustls_native_certs::load_native_certs(); 60 + if !errors.is_empty() { 61 + crate::log::warn!("native root CA certificate loading errors: {errors:?}"); 62 + } 63 + 64 + if certs.is_empty() { 65 + return Err(io::Error::new( 66 + io::ErrorKind::NotFound, 67 + format!("no native root CA certificates found (errors: {errors:?})"), 68 + )); 69 + } 70 + 71 + for cert in certs { 72 + match roots.add(cert) { 73 + Ok(_) => valid_count += 1, 74 + Err(err) => { 75 + crate::log::debug!("certificate parsing failed: {:?}", err); 76 + invalid_count += 1 77 + } 78 + } 79 + } 80 + 81 + crate::log::debug!( 82 + "with_native_roots processed {} valid and {} invalid certs", 83 + valid_count, 84 + invalid_count 85 + ); 86 + if roots.is_empty() { 87 + crate::log::debug!("no valid native root CA certificates found"); 88 + Err(io::Error::new( 89 + io::ErrorKind::NotFound, 90 + format!("no valid native root CA certificates found ({invalid_count} invalid)"), 91 + ))? 92 + } 93 + 94 + Ok(self.with_root_certificates(roots)) 95 + } 96 + 97 + #[cfg(feature = "webpki-roots")] 98 + fn with_webpki_roots(self) -> ConfigBuilder<ClientConfig, WantsClientCert> { 99 + let mut roots = rustls::RootCertStore::empty(); 100 + roots.extend( 101 + webpki_roots::TLS_SERVER_ROOTS 102 + .iter() 103 + .cloned(), 104 + ); 105 + self.with_root_certificates(roots) 106 + } 107 + }
+201
vendor/hyper-rustls/src/connector.rs
··· 1 + use std::future::Future; 2 + use std::pin::Pin; 3 + use std::sync::Arc; 4 + use std::task::{Context, Poll}; 5 + use std::{fmt, io}; 6 + 7 + use http::Uri; 8 + use hyper::rt; 9 + use hyper_util::client::legacy::connect::Connection; 10 + use hyper_util::rt::TokioIo; 11 + use pki_types::ServerName; 12 + use tokio_rustls::TlsConnector; 13 + use tower_service::Service; 14 + 15 + use crate::stream::MaybeHttpsStream; 16 + 17 + pub(crate) mod builder; 18 + 19 + type BoxError = Box<dyn std::error::Error + Send + Sync>; 20 + 21 + /// A Connector for the `https` scheme. 22 + #[derive(Clone)] 23 + pub struct HttpsConnector<T> { 24 + force_https: bool, 25 + http: T, 26 + tls_config: Arc<rustls::ClientConfig>, 27 + server_name_resolver: Arc<dyn ResolveServerName + Sync + Send>, 28 + } 29 + 30 + impl<T> HttpsConnector<T> { 31 + /// Creates a [`crate::HttpsConnectorBuilder`] to configure a `HttpsConnector`. 32 + /// 33 + /// This is the same as [`crate::HttpsConnectorBuilder::new()`]. 34 + pub fn builder() -> builder::ConnectorBuilder<builder::WantsTlsConfig> { 35 + builder::ConnectorBuilder::new() 36 + } 37 + 38 + /// Force the use of HTTPS when connecting. 39 + /// 40 + /// If a URL is not `https` when connecting, an error is returned. 41 + pub fn enforce_https(&mut self) { 42 + self.force_https = true; 43 + } 44 + } 45 + 46 + impl<T> Service<Uri> for HttpsConnector<T> 47 + where 48 + T: Service<Uri>, 49 + T::Response: Connection + rt::Read + rt::Write + Send + Unpin + 'static, 50 + T::Future: Send + 'static, 51 + T::Error: Into<BoxError>, 52 + { 53 + type Response = MaybeHttpsStream<T::Response>; 54 + type Error = BoxError; 55 + 56 + #[allow(clippy::type_complexity)] 57 + type Future = 58 + Pin<Box<dyn Future<Output = Result<MaybeHttpsStream<T::Response>, BoxError>> + Send>>; 59 + 60 + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 61 + match self.http.poll_ready(cx) { 62 + Poll::Ready(Ok(())) => Poll::Ready(Ok(())), 63 + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), 64 + Poll::Pending => Poll::Pending, 65 + } 66 + } 67 + 68 + fn call(&mut self, dst: Uri) -> Self::Future { 69 + // dst.scheme() would need to derive Eq to be matchable; 70 + // use an if cascade instead 71 + match dst.scheme() { 72 + Some(scheme) if scheme == &http::uri::Scheme::HTTP => { 73 + let future = self.http.call(dst); 74 + return Box::pin(async move { 75 + Ok(MaybeHttpsStream::Http(future.await.map_err(Into::into)?)) 76 + }); 77 + } 78 + Some(scheme) if scheme != &http::uri::Scheme::HTTPS => { 79 + let message = format!("unsupported scheme {scheme}"); 80 + return Box::pin(async move { 81 + Err(io::Error::new(io::ErrorKind::Other, message).into()) 82 + }); 83 + } 84 + Some(_) => {} 85 + None => { 86 + return Box::pin(async move { 87 + Err(io::Error::new(io::ErrorKind::Other, "missing scheme").into()) 88 + }) 89 + } 90 + }; 91 + 92 + let cfg = self.tls_config.clone(); 93 + let hostname = match self.server_name_resolver.resolve(&dst) { 94 + Ok(hostname) => hostname, 95 + Err(e) => { 96 + return Box::pin(async move { Err(e) }); 97 + } 98 + }; 99 + 100 + let connecting_future = self.http.call(dst); 101 + Box::pin(async move { 102 + let tcp = connecting_future 103 + .await 104 + .map_err(Into::into)?; 105 + Ok(MaybeHttpsStream::Https(TokioIo::new( 106 + TlsConnector::from(cfg) 107 + .connect(hostname, TokioIo::new(tcp)) 108 + .await 109 + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?, 110 + ))) 111 + }) 112 + } 113 + } 114 + 115 + impl<H, C> From<(H, C)> for HttpsConnector<H> 116 + where 117 + C: Into<Arc<rustls::ClientConfig>>, 118 + { 119 + fn from((http, cfg): (H, C)) -> Self { 120 + Self { 121 + force_https: false, 122 + http, 123 + tls_config: cfg.into(), 124 + server_name_resolver: Arc::new(DefaultServerNameResolver::default()), 125 + } 126 + } 127 + } 128 + 129 + impl<T> fmt::Debug for HttpsConnector<T> { 130 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 131 + f.debug_struct("HttpsConnector") 132 + .field("force_https", &self.force_https) 133 + .finish() 134 + } 135 + } 136 + 137 + /// The default server name resolver, which uses the hostname in the URI. 138 + #[derive(Default)] 139 + pub struct DefaultServerNameResolver(()); 140 + 141 + impl ResolveServerName for DefaultServerNameResolver { 142 + fn resolve( 143 + &self, 144 + uri: &Uri, 145 + ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>> { 146 + let mut hostname = uri.host().unwrap_or_default(); 147 + 148 + // Remove square brackets around IPv6 address. 149 + if let Some(trimmed) = hostname 150 + .strip_prefix('[') 151 + .and_then(|h| h.strip_suffix(']')) 152 + { 153 + hostname = trimmed; 154 + } 155 + 156 + ServerName::try_from(hostname.to_string()).map_err(|e| Box::new(e) as _) 157 + } 158 + } 159 + 160 + /// A server name resolver which always returns the same fixed name. 161 + pub struct FixedServerNameResolver { 162 + name: ServerName<'static>, 163 + } 164 + 165 + impl FixedServerNameResolver { 166 + /// Creates a new resolver returning the specified name. 167 + pub fn new(name: ServerName<'static>) -> Self { 168 + Self { name } 169 + } 170 + } 171 + 172 + impl ResolveServerName for FixedServerNameResolver { 173 + fn resolve( 174 + &self, 175 + _: &Uri, 176 + ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>> { 177 + Ok(self.name.clone()) 178 + } 179 + } 180 + 181 + impl<F, E> ResolveServerName for F 182 + where 183 + F: Fn(&Uri) -> Result<ServerName<'static>, E>, 184 + E: Into<Box<dyn std::error::Error + Sync + Send>>, 185 + { 186 + fn resolve( 187 + &self, 188 + uri: &Uri, 189 + ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>> { 190 + self(uri).map_err(Into::into) 191 + } 192 + } 193 + 194 + /// A trait implemented by types that can resolve a [`ServerName`] for a request. 195 + pub trait ResolveServerName { 196 + /// Maps a [`Uri`] into a [`ServerName`]. 197 + fn resolve( 198 + &self, 199 + uri: &Uri, 200 + ) -> Result<ServerName<'static>, Box<dyn std::error::Error + Sync + Send>>; 201 + }
+485
vendor/hyper-rustls/src/connector/builder.rs
··· 1 + use std::sync::Arc; 2 + 3 + use hyper_util::client::legacy::connect::HttpConnector; 4 + #[cfg(any( 5 + feature = "rustls-native-certs", 6 + feature = "rustls-platform-verifier", 7 + feature = "webpki-roots" 8 + ))] 9 + use rustls::crypto::CryptoProvider; 10 + use rustls::ClientConfig; 11 + 12 + use super::{DefaultServerNameResolver, HttpsConnector, ResolveServerName}; 13 + #[cfg(any( 14 + feature = "rustls-native-certs", 15 + feature = "webpki-roots", 16 + feature = "rustls-platform-verifier" 17 + ))] 18 + use crate::config::ConfigBuilderExt; 19 + use pki_types::ServerName; 20 + 21 + /// A builder for an [`HttpsConnector`] 22 + /// 23 + /// This makes configuration flexible and explicit and ensures connector 24 + /// features match crate features 25 + /// 26 + /// # Examples 27 + /// 28 + /// ``` 29 + /// use hyper_rustls::HttpsConnectorBuilder; 30 + /// 31 + /// # #[cfg(all(feature = "webpki-roots", feature = "http1", feature="aws-lc-rs"))] 32 + /// # { 33 + /// # let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); 34 + /// let https = HttpsConnectorBuilder::new() 35 + /// .with_webpki_roots() 36 + /// .https_only() 37 + /// .enable_http1() 38 + /// .build(); 39 + /// # } 40 + /// ``` 41 + pub struct ConnectorBuilder<State>(State); 42 + 43 + /// State of a builder that needs a TLS client config next 44 + pub struct WantsTlsConfig(()); 45 + 46 + impl ConnectorBuilder<WantsTlsConfig> { 47 + /// Creates a new [`ConnectorBuilder`] 48 + pub fn new() -> Self { 49 + Self(WantsTlsConfig(())) 50 + } 51 + 52 + /// Passes a rustls [`ClientConfig`] to configure the TLS connection 53 + /// 54 + /// The [`alpn_protocols`](ClientConfig::alpn_protocols) field is 55 + /// required to be empty (or the function will panic) and will be 56 + /// rewritten to match the enabled schemes (see 57 + /// [`enable_http1`](ConnectorBuilder::enable_http1), 58 + /// [`enable_http2`](ConnectorBuilder::enable_http2)) before the 59 + /// connector is built. 60 + pub fn with_tls_config(self, config: ClientConfig) -> ConnectorBuilder<WantsSchemes> { 61 + assert!( 62 + config.alpn_protocols.is_empty(), 63 + "ALPN protocols should not be pre-defined" 64 + ); 65 + ConnectorBuilder(WantsSchemes { tls_config: config }) 66 + } 67 + 68 + /// Shorthand for using rustls' default crypto provider and other defaults, and 69 + /// the platform verifier. 70 + /// 71 + /// See [`ConfigBuilderExt::with_platform_verifier()`]. 72 + #[cfg(all( 73 + any(feature = "ring", feature = "aws-lc-rs"), 74 + feature = "rustls-platform-verifier" 75 + ))] 76 + pub fn with_platform_verifier(self) -> ConnectorBuilder<WantsSchemes> { 77 + self.with_tls_config( 78 + ClientConfig::builder() 79 + .with_platform_verifier() 80 + .with_no_client_auth(), 81 + ) 82 + } 83 + 84 + /// Shorthand for using a custom [`CryptoProvider`] and the platform verifier. 85 + /// 86 + /// See [`ConfigBuilderExt::with_platform_verifier()`]. 87 + #[cfg(feature = "rustls-platform-verifier")] 88 + pub fn with_provider_and_platform_verifier( 89 + self, 90 + provider: impl Into<Arc<CryptoProvider>>, 91 + ) -> std::io::Result<ConnectorBuilder<WantsSchemes>> { 92 + Ok(self.with_tls_config( 93 + ClientConfig::builder_with_provider(provider.into()) 94 + .with_safe_default_protocol_versions() 95 + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? 96 + .with_platform_verifier() 97 + .with_no_client_auth(), 98 + )) 99 + } 100 + 101 + /// Shorthand for using rustls' default crypto provider and safe defaults, with 102 + /// native roots. 103 + /// 104 + /// See [`ConfigBuilderExt::with_native_roots`] 105 + #[cfg(all( 106 + any(feature = "ring", feature = "aws-lc-rs"), 107 + feature = "rustls-native-certs" 108 + ))] 109 + pub fn with_native_roots(self) -> std::io::Result<ConnectorBuilder<WantsSchemes>> { 110 + Ok(self.with_tls_config( 111 + ClientConfig::builder() 112 + .with_native_roots()? 113 + .with_no_client_auth(), 114 + )) 115 + } 116 + 117 + /// Shorthand for using a custom [`CryptoProvider`] and native roots 118 + /// 119 + /// See [`ConfigBuilderExt::with_native_roots`] 120 + #[cfg(feature = "rustls-native-certs")] 121 + pub fn with_provider_and_native_roots( 122 + self, 123 + provider: impl Into<Arc<CryptoProvider>>, 124 + ) -> std::io::Result<ConnectorBuilder<WantsSchemes>> { 125 + Ok(self.with_tls_config( 126 + ClientConfig::builder_with_provider(provider.into()) 127 + .with_safe_default_protocol_versions() 128 + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? 129 + .with_native_roots()? 130 + .with_no_client_auth(), 131 + )) 132 + } 133 + 134 + /// Shorthand for using rustls' default crypto provider and its 135 + /// safe defaults. 136 + /// 137 + /// See [`ConfigBuilderExt::with_webpki_roots`] 138 + #[cfg(all(any(feature = "ring", feature = "aws-lc-rs"), feature = "webpki-roots"))] 139 + pub fn with_webpki_roots(self) -> ConnectorBuilder<WantsSchemes> { 140 + self.with_tls_config( 141 + ClientConfig::builder() 142 + .with_webpki_roots() 143 + .with_no_client_auth(), 144 + ) 145 + } 146 + 147 + /// Shorthand for using a custom [`CryptoProvider`], Rustls' safe default 148 + /// protocol versions and Mozilla roots 149 + /// 150 + /// See [`ConfigBuilderExt::with_webpki_roots`] 151 + #[cfg(feature = "webpki-roots")] 152 + pub fn with_provider_and_webpki_roots( 153 + self, 154 + provider: impl Into<Arc<CryptoProvider>>, 155 + ) -> Result<ConnectorBuilder<WantsSchemes>, rustls::Error> { 156 + Ok(self.with_tls_config( 157 + ClientConfig::builder_with_provider(provider.into()) 158 + .with_safe_default_protocol_versions()? 159 + .with_webpki_roots() 160 + .with_no_client_auth(), 161 + )) 162 + } 163 + } 164 + 165 + impl Default for ConnectorBuilder<WantsTlsConfig> { 166 + fn default() -> Self { 167 + Self::new() 168 + } 169 + } 170 + 171 + /// State of a builder that needs schemes (https:// and http://) to be 172 + /// configured next 173 + pub struct WantsSchemes { 174 + tls_config: ClientConfig, 175 + } 176 + 177 + impl ConnectorBuilder<WantsSchemes> { 178 + /// Enforce the use of HTTPS when connecting 179 + /// 180 + /// Only URLs using the HTTPS scheme will be connectable. 181 + pub fn https_only(self) -> ConnectorBuilder<WantsProtocols1> { 182 + ConnectorBuilder(WantsProtocols1 { 183 + tls_config: self.0.tls_config, 184 + https_only: true, 185 + server_name_resolver: None, 186 + }) 187 + } 188 + 189 + /// Allow both HTTPS and HTTP when connecting 190 + /// 191 + /// HTTPS URLs will be handled through rustls, 192 + /// HTTP URLs will be handled by the lower-level connector. 193 + pub fn https_or_http(self) -> ConnectorBuilder<WantsProtocols1> { 194 + ConnectorBuilder(WantsProtocols1 { 195 + tls_config: self.0.tls_config, 196 + https_only: false, 197 + server_name_resolver: None, 198 + }) 199 + } 200 + } 201 + 202 + /// State of a builder that needs to have some protocols (HTTP1 or later) 203 + /// enabled next 204 + /// 205 + /// No protocol has been enabled at this point. 206 + pub struct WantsProtocols1 { 207 + tls_config: ClientConfig, 208 + https_only: bool, 209 + server_name_resolver: Option<Arc<dyn ResolveServerName + Sync + Send>>, 210 + } 211 + 212 + impl WantsProtocols1 { 213 + fn wrap_connector<H>(self, conn: H) -> HttpsConnector<H> { 214 + HttpsConnector { 215 + force_https: self.https_only, 216 + http: conn, 217 + tls_config: std::sync::Arc::new(self.tls_config), 218 + server_name_resolver: self 219 + .server_name_resolver 220 + .unwrap_or_else(|| Arc::new(DefaultServerNameResolver::default())), 221 + } 222 + } 223 + 224 + fn build(self) -> HttpsConnector<HttpConnector> { 225 + let mut http = HttpConnector::new(); 226 + // HttpConnector won't enforce scheme, but HttpsConnector will 227 + http.enforce_http(false); 228 + self.wrap_connector(http) 229 + } 230 + } 231 + 232 + impl ConnectorBuilder<WantsProtocols1> { 233 + /// Enable HTTP1 234 + /// 235 + /// This needs to be called explicitly, no protocol is enabled by default 236 + #[cfg(feature = "http1")] 237 + pub fn enable_http1(self) -> ConnectorBuilder<WantsProtocols2> { 238 + ConnectorBuilder(WantsProtocols2 { inner: self.0 }) 239 + } 240 + 241 + /// Enable HTTP2 242 + /// 243 + /// This needs to be called explicitly, no protocol is enabled by default 244 + #[cfg(feature = "http2")] 245 + pub fn enable_http2(mut self) -> ConnectorBuilder<WantsProtocols3> { 246 + self.0.tls_config.alpn_protocols = vec![b"h2".to_vec()]; 247 + ConnectorBuilder(WantsProtocols3 { 248 + inner: self.0, 249 + enable_http1: false, 250 + }) 251 + } 252 + 253 + /// Enable all HTTP versions built into this library (enabled with Cargo features) 254 + /// 255 + /// For now, this could enable both HTTP 1 and 2, depending on active features. 256 + /// In the future, other supported versions will be enabled as well. 257 + #[cfg(feature = "http2")] 258 + pub fn enable_all_versions(mut self) -> ConnectorBuilder<WantsProtocols3> { 259 + #[cfg(feature = "http1")] 260 + let alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; 261 + #[cfg(not(feature = "http1"))] 262 + let alpn_protocols = vec![b"h2".to_vec()]; 263 + 264 + self.0.tls_config.alpn_protocols = alpn_protocols; 265 + ConnectorBuilder(WantsProtocols3 { 266 + inner: self.0, 267 + enable_http1: cfg!(feature = "http1"), 268 + }) 269 + } 270 + 271 + /// Override server name for the TLS stack 272 + /// 273 + /// By default, for each connection hyper-rustls will extract host portion 274 + /// of the destination URL and verify that server certificate contains 275 + /// this value. 276 + /// 277 + /// If this method is called, hyper-rustls will instead use this resolver 278 + /// to compute the value used to verify the server certificate. 279 + pub fn with_server_name_resolver( 280 + mut self, 281 + resolver: impl ResolveServerName + 'static + Sync + Send, 282 + ) -> Self { 283 + self.0.server_name_resolver = Some(Arc::new(resolver)); 284 + self 285 + } 286 + 287 + /// Override server name for the TLS stack 288 + /// 289 + /// By default, for each connection hyper-rustls will extract host portion 290 + /// of the destination URL and verify that server certificate contains 291 + /// this value. 292 + /// 293 + /// If this method is called, hyper-rustls will instead verify that server 294 + /// certificate contains `override_server_name`. Domain name included in 295 + /// the URL will not affect certificate validation. 296 + #[deprecated( 297 + since = "0.27.1", 298 + note = "use Self::with_server_name_resolver with FixedServerNameResolver instead" 299 + )] 300 + pub fn with_server_name(self, mut override_server_name: String) -> Self { 301 + // remove square brackets around IPv6 address. 302 + if let Some(trimmed) = override_server_name 303 + .strip_prefix('[') 304 + .and_then(|s| s.strip_suffix(']')) 305 + { 306 + override_server_name = trimmed.to_string(); 307 + } 308 + 309 + self.with_server_name_resolver(move |_: &_| { 310 + ServerName::try_from(override_server_name.clone()) 311 + }) 312 + } 313 + } 314 + 315 + /// State of a builder with HTTP1 enabled, that may have some other 316 + /// protocols (HTTP2 or later) enabled next 317 + /// 318 + /// At this point a connector can be built, see 319 + /// [`build`](ConnectorBuilder<WantsProtocols2>::build) and 320 + /// [`wrap_connector`](ConnectorBuilder<WantsProtocols2>::wrap_connector). 321 + pub struct WantsProtocols2 { 322 + inner: WantsProtocols1, 323 + } 324 + 325 + impl ConnectorBuilder<WantsProtocols2> { 326 + /// Enable HTTP2 327 + /// 328 + /// This needs to be called explicitly, no protocol is enabled by default 329 + #[cfg(feature = "http2")] 330 + pub fn enable_http2(mut self) -> ConnectorBuilder<WantsProtocols3> { 331 + self.0.inner.tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; 332 + ConnectorBuilder(WantsProtocols3 { 333 + inner: self.0.inner, 334 + enable_http1: true, 335 + }) 336 + } 337 + 338 + /// This builds an [`HttpsConnector`] built on hyper's default [`HttpConnector`] 339 + pub fn build(self) -> HttpsConnector<HttpConnector> { 340 + self.0.inner.build() 341 + } 342 + 343 + /// This wraps an arbitrary low-level connector into an [`HttpsConnector`] 344 + pub fn wrap_connector<H>(self, conn: H) -> HttpsConnector<H> { 345 + // HTTP1-only, alpn_protocols stays empty 346 + // HttpConnector doesn't have a way to say http1-only; 347 + // its connection pool may still support HTTP2 348 + // though it won't be used 349 + self.0.inner.wrap_connector(conn) 350 + } 351 + } 352 + 353 + /// State of a builder with HTTP2 (and possibly HTTP1) enabled 354 + /// 355 + /// At this point a connector can be built, see 356 + /// [`build`](ConnectorBuilder<WantsProtocols3>::build) and 357 + /// [`wrap_connector`](ConnectorBuilder<WantsProtocols3>::wrap_connector). 358 + #[cfg(feature = "http2")] 359 + pub struct WantsProtocols3 { 360 + inner: WantsProtocols1, 361 + // ALPN is built piecemeal without the need to read back this field 362 + #[allow(dead_code)] 363 + enable_http1: bool, 364 + } 365 + 366 + #[cfg(feature = "http2")] 367 + impl ConnectorBuilder<WantsProtocols3> { 368 + /// This builds an [`HttpsConnector`] built on hyper's default [`HttpConnector`] 369 + pub fn build(self) -> HttpsConnector<HttpConnector> { 370 + self.0.inner.build() 371 + } 372 + 373 + /// This wraps an arbitrary low-level connector into an [`HttpsConnector`] 374 + pub fn wrap_connector<H>(self, conn: H) -> HttpsConnector<H> { 375 + // If HTTP1 is disabled, we can set http2_only 376 + // on the Client (a higher-level object that uses the connector) 377 + // client.http2_only(!self.0.enable_http1); 378 + self.0.inner.wrap_connector(conn) 379 + } 380 + } 381 + 382 + #[cfg(test)] 383 + mod tests { 384 + // Typical usage 385 + #[test] 386 + #[cfg(all(feature = "webpki-roots", feature = "http1"))] 387 + fn test_builder() { 388 + ensure_global_state(); 389 + let _connector = super::ConnectorBuilder::new() 390 + .with_webpki_roots() 391 + .https_only() 392 + .enable_http1() 393 + .build(); 394 + } 395 + 396 + #[test] 397 + #[cfg(feature = "http1")] 398 + #[should_panic(expected = "ALPN protocols should not be pre-defined")] 399 + fn test_reject_predefined_alpn() { 400 + ensure_global_state(); 401 + let roots = rustls::RootCertStore::empty(); 402 + let mut config_with_alpn = rustls::ClientConfig::builder() 403 + .with_root_certificates(roots) 404 + .with_no_client_auth(); 405 + config_with_alpn.alpn_protocols = vec![b"fancyprotocol".to_vec()]; 406 + let _connector = super::ConnectorBuilder::new() 407 + .with_tls_config(config_with_alpn) 408 + .https_only() 409 + .enable_http1() 410 + .build(); 411 + } 412 + 413 + #[test] 414 + #[cfg(all(feature = "http1", feature = "http2"))] 415 + fn test_alpn() { 416 + ensure_global_state(); 417 + let roots = rustls::RootCertStore::empty(); 418 + let tls_config = rustls::ClientConfig::builder() 419 + .with_root_certificates(roots) 420 + .with_no_client_auth(); 421 + let connector = super::ConnectorBuilder::new() 422 + .with_tls_config(tls_config.clone()) 423 + .https_only() 424 + .enable_http1() 425 + .build(); 426 + assert!(connector 427 + .tls_config 428 + .alpn_protocols 429 + .is_empty()); 430 + let connector = super::ConnectorBuilder::new() 431 + .with_tls_config(tls_config.clone()) 432 + .https_only() 433 + .enable_http2() 434 + .build(); 435 + assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); 436 + let connector = super::ConnectorBuilder::new() 437 + .with_tls_config(tls_config.clone()) 438 + .https_only() 439 + .enable_http1() 440 + .enable_http2() 441 + .build(); 442 + assert_eq!( 443 + &connector.tls_config.alpn_protocols, 444 + &[b"h2".to_vec(), b"http/1.1".to_vec()] 445 + ); 446 + let connector = super::ConnectorBuilder::new() 447 + .with_tls_config(tls_config) 448 + .https_only() 449 + .enable_all_versions() 450 + .build(); 451 + assert_eq!( 452 + &connector.tls_config.alpn_protocols, 453 + &[b"h2".to_vec(), b"http/1.1".to_vec()] 454 + ); 455 + } 456 + 457 + #[test] 458 + #[cfg(all(not(feature = "http1"), feature = "http2"))] 459 + fn test_alpn_http2() { 460 + let roots = rustls::RootCertStore::empty(); 461 + let tls_config = rustls::ClientConfig::builder() 462 + .with_safe_defaults() 463 + .with_root_certificates(roots) 464 + .with_no_client_auth(); 465 + let connector = super::ConnectorBuilder::new() 466 + .with_tls_config(tls_config.clone()) 467 + .https_only() 468 + .enable_http2() 469 + .build(); 470 + assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); 471 + let connector = super::ConnectorBuilder::new() 472 + .with_tls_config(tls_config) 473 + .https_only() 474 + .enable_all_versions() 475 + .build(); 476 + assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); 477 + } 478 + 479 + fn ensure_global_state() { 480 + #[cfg(feature = "ring")] 481 + let _ = rustls::crypto::ring::default_provider().install_default(); 482 + #[cfg(feature = "aws-lc-rs")] 483 + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); 484 + } 485 + }
+76
vendor/hyper-rustls/src/lib.rs
··· 1 + //! # hyper-rustls 2 + //! 3 + //! A pure-Rust HTTPS connector for [hyper](https://hyper.rs), based on 4 + //! [Rustls](https://github.com/rustls/rustls). 5 + //! 6 + //! ## Example client 7 + //! 8 + //! ```no_run 9 + //! # #[cfg(all(feature = "rustls-native-certs", feature = "http1"))] 10 + //! # fn main() { 11 + //! use http::StatusCode; 12 + //! use http_body_util::Empty; 13 + //! use hyper::body::Bytes; 14 + //! use hyper_util::client::legacy::Client; 15 + //! use hyper_util::rt::TokioExecutor; 16 + //! 17 + //! let mut rt = tokio::runtime::Runtime::new().unwrap(); 18 + //! let url = ("https://hyper.rs").parse().unwrap(); 19 + //! let https = hyper_rustls::HttpsConnectorBuilder::new() 20 + //! .with_native_roots() 21 + //! .expect("no native root CA certificates found") 22 + //! .https_only() 23 + //! .enable_http1() 24 + //! .build(); 25 + //! 26 + //! let client: Client<_, Empty<Bytes>> = Client::builder(TokioExecutor::new()).build(https); 27 + //! 28 + //! let res = rt.block_on(client.get(url)).unwrap(); 29 + //! assert_eq!(res.status(), StatusCode::OK); 30 + //! # } 31 + //! # #[cfg(not(all(feature = "rustls-native-certs", feature = "http1")))] 32 + //! # fn main() {} 33 + //! ``` 34 + 35 + #![warn(missing_docs, unreachable_pub, clippy::use_self)] 36 + #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] 37 + 38 + mod config; 39 + mod connector; 40 + mod stream; 41 + 42 + #[cfg(feature = "logging")] 43 + mod log { 44 + #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] 45 + pub(crate) use log::debug; 46 + #[cfg(feature = "rustls-native-certs")] 47 + pub(crate) use log::warn; 48 + } 49 + 50 + #[cfg(not(feature = "logging"))] 51 + mod log { 52 + #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] 53 + macro_rules! debug ( ($($tt:tt)*) => {{}} ); 54 + #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] 55 + pub(crate) use debug; 56 + #[cfg(feature = "rustls-native-certs")] 57 + macro_rules! warn_ ( ($($tt:tt)*) => {{}} ); 58 + #[cfg(feature = "rustls-native-certs")] 59 + pub(crate) use warn_ as warn; 60 + } 61 + 62 + pub use crate::config::ConfigBuilderExt; 63 + pub use crate::connector::builder::ConnectorBuilder as HttpsConnectorBuilder; 64 + pub use crate::connector::{ 65 + DefaultServerNameResolver, FixedServerNameResolver, HttpsConnector, ResolveServerName, 66 + }; 67 + pub use crate::stream::MaybeHttpsStream; 68 + 69 + /// The various states of the [`HttpsConnectorBuilder`] 70 + pub mod builderstates { 71 + #[cfg(feature = "http2")] 72 + pub use crate::connector::builder::WantsProtocols3; 73 + pub use crate::connector::builder::{ 74 + WantsProtocols1, WantsProtocols2, WantsSchemes, WantsTlsConfig, 75 + }; 76 + }
+101
vendor/hyper-rustls/src/stream.rs
··· 1 + // Copied from hyperium/hyper-tls#62e3376/src/stream.rs 2 + use std::fmt; 3 + use std::io; 4 + use std::pin::Pin; 5 + use std::task::{Context, Poll}; 6 + 7 + use hyper::rt; 8 + use hyper_util::client::legacy::connect::{Connected, Connection}; 9 + 10 + use hyper_util::rt::TokioIo; 11 + use tokio_rustls::client::TlsStream; 12 + 13 + /// A stream that might be protected with TLS. 14 + #[allow(clippy::large_enum_variant)] 15 + pub enum MaybeHttpsStream<T> { 16 + /// A stream over plain text. 17 + Http(T), 18 + /// A stream protected with TLS. 19 + Https(TokioIo<TlsStream<TokioIo<T>>>), 20 + } 21 + 22 + impl<T: rt::Read + rt::Write + Connection + Unpin> Connection for MaybeHttpsStream<T> { 23 + fn connected(&self) -> Connected { 24 + match self { 25 + Self::Http(s) => s.connected(), 26 + Self::Https(s) => { 27 + let (tcp, tls) = s.inner().get_ref(); 28 + if tls.alpn_protocol() == Some(b"h2") { 29 + tcp.inner().connected().negotiated_h2() 30 + } else { 31 + tcp.inner().connected() 32 + } 33 + } 34 + } 35 + } 36 + } 37 + 38 + impl<T: fmt::Debug> fmt::Debug for MaybeHttpsStream<T> { 39 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 40 + match *self { 41 + Self::Http(..) => f.pad("Http(..)"), 42 + Self::Https(..) => f.pad("Https(..)"), 43 + } 44 + } 45 + } 46 + 47 + impl<T> From<T> for MaybeHttpsStream<T> { 48 + fn from(inner: T) -> Self { 49 + Self::Http(inner) 50 + } 51 + } 52 + 53 + impl<T> From<TlsStream<TokioIo<T>>> for MaybeHttpsStream<T> { 54 + fn from(inner: TlsStream<TokioIo<T>>) -> Self { 55 + Self::Https(TokioIo::new(inner)) 56 + } 57 + } 58 + 59 + impl<T: rt::Read + rt::Write + Unpin> rt::Read for MaybeHttpsStream<T> { 60 + #[inline] 61 + fn poll_read( 62 + self: Pin<&mut Self>, 63 + cx: &mut Context, 64 + buf: rt::ReadBufCursor<'_>, 65 + ) -> Poll<Result<(), io::Error>> { 66 + match Pin::get_mut(self) { 67 + Self::Http(s) => Pin::new(s).poll_read(cx, buf), 68 + Self::Https(s) => Pin::new(s).poll_read(cx, buf), 69 + } 70 + } 71 + } 72 + 73 + impl<T: rt::Write + rt::Read + Unpin> rt::Write for MaybeHttpsStream<T> { 74 + #[inline] 75 + fn poll_write( 76 + self: Pin<&mut Self>, 77 + cx: &mut Context<'_>, 78 + buf: &[u8], 79 + ) -> Poll<Result<usize, io::Error>> { 80 + match Pin::get_mut(self) { 81 + Self::Http(s) => Pin::new(s).poll_write(cx, buf), 82 + Self::Https(s) => Pin::new(s).poll_write(cx, buf), 83 + } 84 + } 85 + 86 + #[inline] 87 + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> { 88 + match Pin::get_mut(self) { 89 + Self::Http(s) => Pin::new(s).poll_flush(cx), 90 + Self::Https(s) => Pin::new(s).poll_flush(cx), 91 + } 92 + } 93 + 94 + #[inline] 95 + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> { 96 + match Pin::get_mut(self) { 97 + Self::Http(s) => Pin::new(s).poll_shutdown(cx), 98 + Self::Https(s) => Pin::new(s).poll_shutdown(cx), 99 + } 100 + } 101 + }
+98
vendor/hyper-rustls/tests/tests.rs
··· 1 + use std::env; 2 + use std::net::TcpStream; 3 + use std::path::PathBuf; 4 + use std::process::Command; 5 + use std::thread; 6 + use std::time; 7 + 8 + fn examples_dir() -> PathBuf { 9 + let target_dir: PathBuf = env::var("CARGO_TARGET_DIR") 10 + .unwrap_or_else(|_| "target".to_string()) 11 + .into(); 12 + target_dir 13 + .join("debug") 14 + .join("examples") 15 + } 16 + 17 + fn server_command() -> Command { 18 + Command::new(examples_dir().join("server")) 19 + } 20 + 21 + fn client_command() -> Command { 22 + Command::new(examples_dir().join("client")) 23 + } 24 + 25 + fn wait_for_server(addr: &str) { 26 + for i in 0..10 { 27 + if TcpStream::connect(addr).is_ok() { 28 + return; 29 + } 30 + thread::sleep(time::Duration::from_millis(i * 100)); 31 + } 32 + panic!("failed to connect to {:?} after 10 tries", addr); 33 + } 34 + 35 + #[test] 36 + fn client() { 37 + let rc = client_command() 38 + .arg("https://google.com") 39 + .output() 40 + .expect("cannot run client example"); 41 + 42 + assert!(rc.status.success()); 43 + } 44 + 45 + #[test] 46 + fn server() { 47 + let mut srv = server_command() 48 + .arg("1337") 49 + .spawn() 50 + .expect("cannot run server example"); 51 + 52 + let addr = "localhost:1337"; 53 + wait_for_server(addr); 54 + 55 + let output = Command::new("curl") 56 + .arg("--insecure") 57 + .arg("--http1.0") 58 + .arg(format!("https://{}", addr)) 59 + .output() 60 + .expect("cannot run curl"); 61 + 62 + srv.kill().unwrap(); 63 + 64 + if !output.status.success() { 65 + let version_stdout = Command::new("curl") 66 + .arg("--version") 67 + .output() 68 + .expect("cannot run curl to collect --version") 69 + .stdout; 70 + println!("curl version: {}", String::from_utf8_lossy(&version_stdout)); 71 + println!("curl stderr:\n{}", String::from_utf8_lossy(&output.stderr)); 72 + } 73 + 74 + assert_eq!(String::from_utf8_lossy(&output.stdout), "Try POST /echo\n"); 75 + } 76 + 77 + #[test] 78 + fn custom_ca_store() { 79 + let mut srv = server_command() 80 + .arg("1338") 81 + .spawn() 82 + .expect("cannot run server example"); 83 + 84 + let addr = "localhost:1338"; 85 + wait_for_server(addr); 86 + 87 + let rc = client_command() 88 + .arg(format!("https://{}", addr)) 89 + .arg("examples/sample.pem") 90 + .output() 91 + .expect("cannot run client example"); 92 + 93 + srv.kill().unwrap(); 94 + 95 + if !rc.status.success() { 96 + assert_eq!(String::from_utf8_lossy(&rc.stdout), ""); 97 + } 98 + }