mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
chore: upgrade to reqwest 0.12.4 and rustls 0.22 (#24388)
Reland of https://github.com/denoland/deno/pull/24056 that doesn't suffer from the problem that was discovered in https://github.com/denoland/deno/pull/24261. It uses upgraded `hyper` and `hyper-util` that fixed the previous problem in https://github.com/hyperium/hyper/pull/3691.
This commit is contained in:
parent
9c1f741112
commit
8db420d552
35 changed files with 392 additions and 652 deletions
169
Cargo.lock
generated
169
Cargo.lock
generated
|
@ -736,7 +736,7 @@ dependencies = [
|
||||||
"flaky_test",
|
"flaky_test",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.1.0",
|
"hyper 1.4.0",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"nix 0.26.2",
|
"nix 0.26.2",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -1467,7 +1467,7 @@ dependencies = [
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_tls",
|
"deno_tls",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"http 0.2.12",
|
"http 1.1.0",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -1561,7 +1561,7 @@ dependencies = [
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"httparse",
|
"httparse",
|
||||||
"hyper 0.14.28",
|
"hyper 0.14.28",
|
||||||
"hyper 1.1.0",
|
"hyper 1.4.0",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"itertools",
|
"itertools",
|
||||||
"memmem",
|
"memmem",
|
||||||
|
@ -1604,6 +1604,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_fetch",
|
"deno_fetch",
|
||||||
|
@ -1614,6 +1615,7 @@ dependencies = [
|
||||||
"denokv_remote",
|
"denokv_remote",
|
||||||
"denokv_sqlite",
|
"denokv_sqlite",
|
||||||
"faster-hex",
|
"faster-hex",
|
||||||
|
"http 1.1.0",
|
||||||
"log",
|
"log",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"prost",
|
"prost",
|
||||||
|
@ -1674,9 +1676,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_native_certs"
|
name = "deno_native_certs"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4785d0bdc13819b665b71e4fb7e119d859568471e4c245ec5610857e70c9345"
|
checksum = "c867603d2a5dfea31f55cecebb572554caa395437786d058faa9a2814c8d6eb9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dlopen2",
|
"dlopen2",
|
||||||
"dlopen2_derive",
|
"dlopen2_derive",
|
||||||
|
@ -1729,10 +1731,10 @@ dependencies = [
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
"errno 0.2.8",
|
"errno 0.2.8",
|
||||||
"faster-hex",
|
"faster-hex",
|
||||||
"h2 0.3.26",
|
"h2 0.4.4",
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"home",
|
"home",
|
||||||
"http 0.2.12",
|
"http 1.1.0",
|
||||||
"idna 0.3.0",
|
"idna 0.3.0",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"ipnetwork",
|
"ipnetwork",
|
||||||
|
@ -1863,7 +1865,7 @@ dependencies = [
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 0.14.28",
|
"hyper 0.14.28",
|
||||||
"hyper 1.1.0",
|
"hyper 1.4.0",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
@ -2017,7 +2019,7 @@ dependencies = [
|
||||||
"h2 0.4.4",
|
"h2 0.4.4",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.1.0",
|
"hyper 1.4.0",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustls-tokio-stream",
|
"rustls-tokio-stream",
|
||||||
|
@ -2046,9 +2048,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "denokv_proto"
|
name = "denokv_proto"
|
||||||
version = "0.7.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd644ad038e7b6e8453463e96c278ba378e8bdc9f557959d511ac830ea0ec969"
|
checksum = "114538d2cacd2b219f05faa753d80950f95416e47c77904c7452d5f41e157059"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
@ -2056,16 +2058,15 @@ dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"prost",
|
"prost",
|
||||||
"prost-build",
|
|
||||||
"serde",
|
"serde",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "denokv_remote"
|
name = "denokv_remote"
|
||||||
version = "0.7.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23cfa4786f9c609711aab89ce173232ceda0617167881e58fd5e0b78868a6932"
|
checksum = "d57717b5123e8d1ec5f52973a67f98e3621274d362d18b245038967b402082df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
|
@ -2074,10 +2075,10 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"denokv_proto",
|
"denokv_proto",
|
||||||
"futures",
|
"futures",
|
||||||
|
"http 1.1.0",
|
||||||
"log",
|
"log",
|
||||||
"prost",
|
"prost",
|
||||||
"rand",
|
"rand",
|
||||||
"reqwest",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -2088,9 +2089,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "denokv_sqlite"
|
name = "denokv_sqlite"
|
||||||
version = "0.7.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f36c1c54cda2de93d0f4ded0392d0b6917bcd9b1d13c056dd7c309668aa43e17"
|
checksum = "188b792af19082cbfc7b666e71979775300482877d8b80601f4a5a86a80098a3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
|
@ -2659,7 +2660,7 @@ checksum = "f63dd7b57f9b33b1741fa631c9522eb35d43e96dcca4a6a91d5e4ca7c93acdc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.1.0",
|
"hyper 1.4.0",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"rand",
|
"rand",
|
||||||
|
@ -3409,9 +3410,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "1.1.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75"
|
checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
@ -3423,39 +3424,45 @@ dependencies = [
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"itoa",
|
"itoa",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"smallvec",
|
||||||
"tokio",
|
"tokio",
|
||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-rustls"
|
name = "hyper-rustls"
|
||||||
version = "0.24.2"
|
version = "0.26.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
|
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 0.2.12",
|
"http 1.1.0",
|
||||||
"hyper 0.14.28",
|
"hyper 1.4.0",
|
||||||
|
"hyper-util",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.2"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67"
|
checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body 1.0.0",
|
"http-body 1.0.0",
|
||||||
"hyper 1.1.0",
|
"hyper 1.4.0",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tower",
|
||||||
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3594,7 +3601,7 @@ dependencies = [
|
||||||
"socket2",
|
"socket2",
|
||||||
"widestring",
|
"widestring",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
"winreg",
|
"winreg 0.50.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5304,21 +5311,22 @@ checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.11.20"
|
version = "0.12.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
|
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-compression",
|
"async-compression",
|
||||||
"base64 0.21.7",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"encoding_rs",
|
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2 0.3.26",
|
"h2 0.4.4",
|
||||||
"http 0.2.12",
|
"http 1.1.0",
|
||||||
"http-body 0.4.6",
|
"http-body 1.0.0",
|
||||||
"hyper 0.14.28",
|
"http-body-util",
|
||||||
|
"hyper 1.4.0",
|
||||||
"hyper-rustls",
|
"hyper-rustls",
|
||||||
|
"hyper-util",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
|
@ -5328,9 +5336,11 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
|
"rustls-pki-types",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
|
"sync_wrapper",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"tokio-socks",
|
"tokio-socks",
|
||||||
|
@ -5342,7 +5352,7 @@ dependencies = [
|
||||||
"wasm-streams",
|
"wasm-streams",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"webpki-roots",
|
"webpki-roots",
|
||||||
"winreg",
|
"winreg 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5512,42 +5522,52 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.21.11"
|
version = "0.22.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
|
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
"rustls-webpki",
|
"rustls-webpki",
|
||||||
"sct",
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-native-certs"
|
name = "rustls-native-certs"
|
||||||
version = "0.6.3"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"openssl-probe",
|
"openssl-probe",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
|
"rustls-pki-types",
|
||||||
"schannel",
|
"schannel",
|
||||||
"security-framework",
|
"security-framework",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pemfile"
|
name = "rustls-pemfile"
|
||||||
version = "1.0.4"
|
version = "2.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
|
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.22.1",
|
||||||
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-tokio-stream"
|
name = "rustls-pki-types"
|
||||||
version = "0.2.24"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd707225bb670bcd2876886bb571753d1ce03a9cedfa2e629a79984ca9a93cfb"
|
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-tokio-stream"
|
||||||
|
version = "0.2.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c478c030dfd68498e6c59168d9eec4f8bead33152a5f3095ad4bdbdcea09d466"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
@ -5557,11 +5577,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.101.7"
|
version = "0.102.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5677,16 +5698,6 @@ dependencies = [
|
||||||
"sha2",
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sct"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
|
|
||||||
dependencies = [
|
|
||||||
"ring",
|
|
||||||
"untrusted",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sec1"
|
name = "sec1"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
|
@ -6655,6 +6666,12 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sync_wrapper"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synstructure"
|
name = "synstructure"
|
||||||
version = "0.12.6"
|
version = "0.12.6"
|
||||||
|
@ -6771,7 +6788,7 @@ dependencies = [
|
||||||
"h2 0.4.4",
|
"h2 0.4.4",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.1.0",
|
"hyper 1.4.0",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"jsonc-parser",
|
"jsonc-parser",
|
||||||
"lazy-regex",
|
"lazy-regex",
|
||||||
|
@ -6937,11 +6954,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.24.1"
|
version = "0.25.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls",
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -6978,7 +6996,10 @@ dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
"futures-util",
|
||||||
|
"hashbrown",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
@ -7036,6 +7057,7 @@ dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
@ -7611,9 +7633,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-streams"
|
name = "wasm-streams"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7"
|
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
@ -7634,9 +7656,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.25.4"
|
version = "0.26.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
|
checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core"
|
name = "wgpu-core"
|
||||||
|
@ -7973,6 +7998,16 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winres"
|
name = "winres"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
|
23
Cargo.toml
23
Cargo.toml
|
@ -55,10 +55,10 @@ deno_terminal = "0.1.1"
|
||||||
napi_sym = { version = "0.88.0", path = "./cli/napi/sym" }
|
napi_sym = { version = "0.88.0", path = "./cli/napi/sym" }
|
||||||
test_util = { package = "test_server", path = "./tests/util/server" }
|
test_util = { package = "test_server", path = "./tests/util/server" }
|
||||||
|
|
||||||
denokv_proto = "0.7.0"
|
denokv_proto = "0.8.1"
|
||||||
denokv_remote = "0.7.0"
|
denokv_remote = "0.8.1"
|
||||||
# denokv_sqlite brings in bundled sqlite if we don't disable the default features
|
# denokv_sqlite brings in bundled sqlite if we don't disable the default features
|
||||||
denokv_sqlite = { default-features = false, version = "0.7.0" }
|
denokv_sqlite = { default-features = false, version = "0.8.1" }
|
||||||
|
|
||||||
# exts
|
# exts
|
||||||
deno_broadcast_channel = { version = "0.152.0", path = "./ext/broadcast_channel" }
|
deno_broadcast_channel = { version = "0.152.0", path = "./ext/broadcast_channel" }
|
||||||
|
@ -118,8 +118,8 @@ http = "1.0"
|
||||||
http-body-util = "0.1"
|
http-body-util = "0.1"
|
||||||
http_v02 = { package = "http", version = "0.2.9" }
|
http_v02 = { package = "http", version = "0.2.9" }
|
||||||
httparse = "1.8.0"
|
httparse = "1.8.0"
|
||||||
hyper = { version = "=1.1.0", features = ["full"] }
|
hyper = { version = "=1.4.0", features = ["full"] }
|
||||||
hyper-util = { version = "=0.1.2", features = ["tokio", "server", "server-auto"] }
|
hyper-util = { version = "=0.1.6", features = ["tokio", "server", "server-auto"] }
|
||||||
hyper_v014 = { package = "hyper", version = "0.14.26", features = ["runtime", "http1"] }
|
hyper_v014 = { package = "hyper", version = "0.14.26", features = ["runtime", "http1"] }
|
||||||
indexmap = { version = "2", features = ["serde"] }
|
indexmap = { version = "2", features = ["serde"] }
|
||||||
jsonc-parser = { version = "=0.23.0", features = ["serde"] }
|
jsonc-parser = { version = "=0.23.0", features = ["serde"] }
|
||||||
|
@ -146,14 +146,13 @@ prost = "0.11"
|
||||||
prost-build = "0.11"
|
prost-build = "0.11"
|
||||||
rand = "=0.8.5"
|
rand = "=0.8.5"
|
||||||
regex = "^1.7.0"
|
regex = "^1.7.0"
|
||||||
reqwest = { version = "=0.11.20", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli", "socks", "json"] } # pinned because of https://github.com/seanmonstar/reqwest/pull/1955
|
reqwest = { version = "=0.12.4", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli", "socks", "json", "http2"] } # pinned because of https://github.com/seanmonstar/reqwest/pull/1955
|
||||||
ring = "^0.17.0"
|
ring = "^0.17.0"
|
||||||
rusqlite = { version = "=0.29.0", features = ["unlock_notify", "bundled"] }
|
rusqlite = { version = "=0.29.0", features = ["unlock_notify", "bundled"] }
|
||||||
# pinned because it was causing issues on cargo publish
|
rustls = "0.22.4"
|
||||||
rustls = "=0.21.11"
|
rustls-pemfile = "2"
|
||||||
rustls-pemfile = "1.0.0"
|
rustls-tokio-stream = "=0.2.23"
|
||||||
rustls-tokio-stream = "=0.2.24"
|
rustls-webpki = "0.102"
|
||||||
rustls-webpki = "0.101.4"
|
|
||||||
rustyline = "=13.0.0"
|
rustyline = "=13.0.0"
|
||||||
saffron = "=0.1.0"
|
saffron = "=0.1.0"
|
||||||
scopeguard = "1.2.0"
|
scopeguard = "1.2.0"
|
||||||
|
@ -180,7 +179,7 @@ twox-hash = "=1.6.3"
|
||||||
# Upgrading past 2.4.1 may cause WPT failures
|
# Upgrading past 2.4.1 may cause WPT failures
|
||||||
url = { version = "< 2.5.0", features = ["serde", "expose_internals"] }
|
url = { version = "< 2.5.0", features = ["serde", "expose_internals"] }
|
||||||
uuid = { version = "1.3.0", features = ["v4"] }
|
uuid = { version = "1.3.0", features = ["v4"] }
|
||||||
webpki-roots = "0.25.2"
|
webpki-roots = "0.26"
|
||||||
zeromq = { version = "=0.3.4", default-features = false, features = ["tcp-transport", "tokio-runtime"] }
|
zeromq = { version = "=0.3.4", default-features = false, features = ["tcp-transport", "tokio-runtime"] }
|
||||||
zstd = "=0.12.4"
|
zstd = "=0.12.4"
|
||||||
|
|
||||||
|
|
|
@ -705,21 +705,13 @@ pub fn get_root_cert_store(
|
||||||
for store in ca_stores.iter() {
|
for store in ca_stores.iter() {
|
||||||
match store.as_str() {
|
match store.as_str() {
|
||||||
"mozilla" => {
|
"mozilla" => {
|
||||||
root_cert_store.add_trust_anchors(
|
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.to_vec());
|
||||||
webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
|
|
||||||
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
|
||||||
ta.subject,
|
|
||||||
ta.spki,
|
|
||||||
ta.name_constraints,
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
"system" => {
|
"system" => {
|
||||||
let roots = load_native_certs().expect("could not load platform certs");
|
let roots = load_native_certs().expect("could not load platform certs");
|
||||||
for root in roots {
|
for root in roots {
|
||||||
root_cert_store
|
root_cert_store
|
||||||
.add(&rustls::Certificate(root.0))
|
.add(rustls::pki_types::CertificateDer::from(root.0))
|
||||||
.expect("Failed to add platform cert to root cert store");
|
.expect("Failed to add platform cert to root cert store");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -743,17 +735,17 @@ pub fn get_root_cert_store(
|
||||||
RootCertStoreLoadError::CaFileOpenError(err.to_string())
|
RootCertStoreLoadError::CaFileOpenError(err.to_string())
|
||||||
})?;
|
})?;
|
||||||
let mut reader = BufReader::new(certfile);
|
let mut reader = BufReader::new(certfile);
|
||||||
rustls_pemfile::certs(&mut reader)
|
rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>()
|
||||||
}
|
}
|
||||||
CaData::Bytes(data) => {
|
CaData::Bytes(data) => {
|
||||||
let mut reader = BufReader::new(Cursor::new(data));
|
let mut reader = BufReader::new(Cursor::new(data));
|
||||||
rustls_pemfile::certs(&mut reader)
|
rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(certs) => {
|
Ok(certs) => {
|
||||||
root_cert_store.add_parsable_certificates(&certs);
|
root_cert_store.add_parsable_certificates(certs);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(RootCertStoreLoadError::FailedAddPemFile(e.to_string()));
|
return Err(RootCertStoreLoadError::FailedAddPemFile(e.to_string()));
|
||||||
|
|
|
@ -587,7 +587,7 @@ mod test {
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::hash::RandomState;
|
use std::hash::RandomState;
|
||||||
|
|
||||||
use deno_runtime::deno_tls::RootCertStore;
|
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||||
|
|
||||||
use crate::version;
|
use crate::version;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ deno_core.workspace = true
|
||||||
deno_permissions.workspace = true
|
deno_permissions.workspace = true
|
||||||
deno_tls.workspace = true
|
deno_tls.workspace = true
|
||||||
dyn-clone = "1"
|
dyn-clone = "1"
|
||||||
http_v02.workspace = true
|
http.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl FetchHandler for FsFetchHandler {
|
||||||
let file = tokio::fs::File::open(path).map_err(|_| ()).await?;
|
let file = tokio::fs::File::open(path).map_err(|_| ()).await?;
|
||||||
let stream = ReaderStream::new(file);
|
let stream = ReaderStream::new(file);
|
||||||
let body = reqwest::Body::wrap_stream(stream);
|
let body = reqwest::Body::wrap_stream(stream);
|
||||||
let response = http_v02::Response::builder()
|
let response = http::Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
.body(body)
|
.body(body)
|
||||||
.map_err(|_| ())?
|
.map_err(|_| ())?
|
||||||
|
|
|
@ -47,8 +47,8 @@ use data_url::DataUrl;
|
||||||
use deno_tls::TlsKey;
|
use deno_tls::TlsKey;
|
||||||
use deno_tls::TlsKeys;
|
use deno_tls::TlsKeys;
|
||||||
use deno_tls::TlsKeysHolder;
|
use deno_tls::TlsKeysHolder;
|
||||||
use http_v02::header::CONTENT_LENGTH;
|
use http::header::CONTENT_LENGTH;
|
||||||
use http_v02::Uri;
|
use http::Uri;
|
||||||
use reqwest::header::HeaderMap;
|
use reqwest::header::HeaderMap;
|
||||||
use reqwest::header::HeaderName;
|
use reqwest::header::HeaderName;
|
||||||
use reqwest::header::HeaderValue;
|
use reqwest::header::HeaderValue;
|
||||||
|
@ -449,12 +449,9 @@ where
|
||||||
.decode_to_vec()
|
.decode_to_vec()
|
||||||
.map_err(|e| type_error(format!("{e:?}")))?;
|
.map_err(|e| type_error(format!("{e:?}")))?;
|
||||||
|
|
||||||
let response = http_v02::Response::builder()
|
let response = http::Response::builder()
|
||||||
.status(http_v02::StatusCode::OK)
|
.status(http::StatusCode::OK)
|
||||||
.header(
|
.header(http::header::CONTENT_TYPE, data_url.mime_type().to_string())
|
||||||
http_v02::header::CONTENT_TYPE,
|
|
||||||
data_url.mime_type().to_string(),
|
|
||||||
)
|
|
||||||
.body(reqwest::Body::from(body))?;
|
.body(reqwest::Body::from(body))?;
|
||||||
|
|
||||||
let fut = async move { Ok(Ok(Response::from(response))) };
|
let fut = async move { Ok(Ok(Response::from(response))) };
|
||||||
|
|
|
@ -17,6 +17,7 @@ path = "lib.rs"
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
base64.workspace = true
|
base64.workspace = true
|
||||||
|
bytes.workspace = true
|
||||||
chrono = { workspace = true, features = ["now"] }
|
chrono = { workspace = true, features = ["now"] }
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
deno_fetch.workspace = true
|
deno_fetch.workspace = true
|
||||||
|
@ -27,6 +28,7 @@ denokv_proto.workspace = true
|
||||||
denokv_remote.workspace = true
|
denokv_remote.workspace = true
|
||||||
denokv_sqlite.workspace = true
|
denokv_sqlite.workspace = true
|
||||||
faster-hex.workspace = true
|
faster-hex.workspace = true
|
||||||
|
http.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
num-bigint.workspace = true
|
num-bigint.workspace = true
|
||||||
prost.workspace = true
|
prost.workspace = true
|
||||||
|
|
|
@ -8,10 +8,14 @@ use std::sync::Arc;
|
||||||
use crate::DatabaseHandler;
|
use crate::DatabaseHandler;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use bytes::Bytes;
|
||||||
use deno_core::error::type_error;
|
use deno_core::error::type_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::futures::Stream;
|
||||||
|
use deno_core::futures::TryStreamExt as _;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
use deno_fetch::create_http_client;
|
use deno_fetch::create_http_client;
|
||||||
|
use deno_fetch::reqwest;
|
||||||
use deno_fetch::CreateHttpClientOptions;
|
use deno_fetch::CreateHttpClientOptions;
|
||||||
use deno_tls::rustls::RootCertStore;
|
use deno_tls::rustls::RootCertStore;
|
||||||
use deno_tls::Proxy;
|
use deno_tls::Proxy;
|
||||||
|
@ -19,6 +23,8 @@ use deno_tls::RootCertStoreProvider;
|
||||||
use deno_tls::TlsKeys;
|
use deno_tls::TlsKeys;
|
||||||
use denokv_remote::MetadataEndpoint;
|
use denokv_remote::MetadataEndpoint;
|
||||||
use denokv_remote::Remote;
|
use denokv_remote::Remote;
|
||||||
|
use denokv_remote::RemoteResponse;
|
||||||
|
use denokv_remote::RemoteTransport;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -102,11 +108,44 @@ impl<P: RemoteDbHandlerPermissions + 'static> denokv_remote::RemotePermissions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ReqwestClient(reqwest::Client);
|
||||||
|
pub struct ReqwestResponse(reqwest::Response);
|
||||||
|
|
||||||
|
impl RemoteTransport for ReqwestClient {
|
||||||
|
type Response = ReqwestResponse;
|
||||||
|
async fn post(
|
||||||
|
&self,
|
||||||
|
url: Url,
|
||||||
|
headers: http::HeaderMap,
|
||||||
|
body: Bytes,
|
||||||
|
) -> Result<(Url, http::StatusCode, Self::Response), anyhow::Error> {
|
||||||
|
let res = self.0.post(url).headers(headers).body(body).send().await?;
|
||||||
|
let url = res.url().clone();
|
||||||
|
let status = res.status();
|
||||||
|
Ok((url, status, ReqwestResponse(res)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemoteResponse for ReqwestResponse {
|
||||||
|
async fn bytes(self) -> Result<Bytes, anyhow::Error> {
|
||||||
|
Ok(self.0.bytes().await?)
|
||||||
|
}
|
||||||
|
fn stream(
|
||||||
|
self,
|
||||||
|
) -> impl Stream<Item = Result<Bytes, anyhow::Error>> + Send + Sync {
|
||||||
|
self.0.bytes_stream().map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
async fn text(self) -> Result<String, anyhow::Error> {
|
||||||
|
Ok(self.0.text().await?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
|
impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
|
||||||
for RemoteDbHandler<P>
|
for RemoteDbHandler<P>
|
||||||
{
|
{
|
||||||
type DB = Remote<PermissionChecker<P>>;
|
type DB = Remote<PermissionChecker<P>, ReqwestClient>;
|
||||||
|
|
||||||
async fn open(
|
async fn open(
|
||||||
&self,
|
&self,
|
||||||
|
@ -162,13 +201,14 @@ impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
|
||||||
http2: true,
|
http2: true,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
let reqwest_client = ReqwestClient(client);
|
||||||
|
|
||||||
let permissions = PermissionChecker {
|
let permissions = PermissionChecker {
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
_permissions: PhantomData,
|
_permissions: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
let remote = Remote::new(client, permissions, metadata_endpoint);
|
let remote = Remote::new(reqwest_client, permissions, metadata_endpoint);
|
||||||
|
|
||||||
Ok(remote)
|
Ok(remote)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,11 +31,11 @@ use deno_tls::create_client_config;
|
||||||
use deno_tls::load_certs;
|
use deno_tls::load_certs;
|
||||||
use deno_tls::load_private_keys;
|
use deno_tls::load_private_keys;
|
||||||
use deno_tls::new_resolver;
|
use deno_tls::new_resolver;
|
||||||
use deno_tls::rustls::Certificate;
|
use deno_tls::rustls::pki_types::ServerName;
|
||||||
use deno_tls::rustls::ClientConnection;
|
use deno_tls::rustls::ClientConnection;
|
||||||
use deno_tls::rustls::PrivateKey;
|
|
||||||
use deno_tls::rustls::ServerConfig;
|
use deno_tls::rustls::ServerConfig;
|
||||||
use deno_tls::rustls::ServerName;
|
use deno_tls::webpki::types::CertificateDer;
|
||||||
|
use deno_tls::webpki::types::PrivateKeyDer;
|
||||||
use deno_tls::ServerConfigProvider;
|
use deno_tls::ServerConfigProvider;
|
||||||
use deno_tls::SocketUse;
|
use deno_tls::SocketUse;
|
||||||
use deno_tls::TlsKey;
|
use deno_tls::TlsKey;
|
||||||
|
@ -48,7 +48,6 @@ use serde::Deserialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
@ -294,14 +293,14 @@ where
|
||||||
{
|
{
|
||||||
let rid = args.rid;
|
let rid = args.rid;
|
||||||
let hostname = match &*args.hostname {
|
let hostname = match &*args.hostname {
|
||||||
"" => "localhost",
|
"" => "localhost".to_string(),
|
||||||
n => n,
|
n => n.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut s = state.borrow_mut();
|
let mut s = state.borrow_mut();
|
||||||
let permissions = s.borrow_mut::<NP>();
|
let permissions = s.borrow_mut::<NP>();
|
||||||
permissions.check_net(&(hostname, Some(0)), "Deno.startTls()")?;
|
permissions.check_net(&(&hostname, Some(0)), "Deno.startTls()")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ca_certs = args
|
let ca_certs = args
|
||||||
|
@ -310,8 +309,8 @@ where
|
||||||
.map(|s| s.into_bytes())
|
.map(|s| s.into_bytes())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let hostname_dns =
|
let hostname_dns = ServerName::try_from(hostname.to_string())
|
||||||
ServerName::try_from(hostname).map_err(|_| invalid_hostname(hostname))?;
|
.map_err(|_| invalid_hostname(&hostname))?;
|
||||||
|
|
||||||
let unsafely_ignore_certificate_errors = state
|
let unsafely_ignore_certificate_errors = state
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -412,9 +411,9 @@ where
|
||||||
.borrow::<DefaultTlsOptions>()
|
.borrow::<DefaultTlsOptions>()
|
||||||
.root_cert_store()?;
|
.root_cert_store()?;
|
||||||
let hostname_dns = if let Some(server_name) = args.server_name {
|
let hostname_dns = if let Some(server_name) = args.server_name {
|
||||||
ServerName::try_from(server_name.as_str())
|
ServerName::try_from(server_name)
|
||||||
} else {
|
} else {
|
||||||
ServerName::try_from(&*addr.hostname)
|
ServerName::try_from(addr.hostname.clone())
|
||||||
}
|
}
|
||||||
.map_err(|_| invalid_hostname(&addr.hostname))?;
|
.map_err(|_| invalid_hostname(&addr.hostname))?;
|
||||||
let connect_addr = resolve_addr(&addr.hostname, addr.port)
|
let connect_addr = resolve_addr(&addr.hostname, addr.port)
|
||||||
|
@ -456,7 +455,9 @@ where
|
||||||
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
|
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_certs_from_file(path: &str) -> Result<Vec<Certificate>, AnyError> {
|
fn load_certs_from_file(
|
||||||
|
path: &str,
|
||||||
|
) -> Result<Vec<CertificateDer<'static>>, AnyError> {
|
||||||
let cert_file = File::open(path)?;
|
let cert_file = File::open(path)?;
|
||||||
let reader = &mut BufReader::new(cert_file);
|
let reader = &mut BufReader::new(cert_file);
|
||||||
load_certs(reader)
|
load_certs(reader)
|
||||||
|
@ -464,7 +465,7 @@ fn load_certs_from_file(path: &str) -> Result<Vec<Certificate>, AnyError> {
|
||||||
|
|
||||||
fn load_private_keys_from_file(
|
fn load_private_keys_from_file(
|
||||||
path: &str,
|
path: &str,
|
||||||
) -> Result<Vec<PrivateKey>, AnyError> {
|
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
|
||||||
let key_bytes = std::fs::read(path)?;
|
let key_bytes = std::fs::read(path)?;
|
||||||
load_private_keys(&key_bytes)
|
load_private_keys(&key_bytes)
|
||||||
}
|
}
|
||||||
|
@ -513,7 +514,6 @@ where
|
||||||
TlsKeys::Null => Err(anyhow!("Deno.listenTls requires a key")),
|
TlsKeys::Null => Err(anyhow!("Deno.listenTls requires a key")),
|
||||||
TlsKeys::Static(TlsKey(cert, key)) => {
|
TlsKeys::Static(TlsKey(cert, key)) => {
|
||||||
let mut tls_config = ServerConfig::builder()
|
let mut tls_config = ServerConfig::builder()
|
||||||
.with_safe_defaults()
|
|
||||||
.with_no_client_auth()
|
.with_no_client_auth()
|
||||||
.with_single_cert(cert, key)
|
.with_single_cert(cert, key)
|
||||||
.map_err(|e| anyhow!(e))?;
|
.map_err(|e| anyhow!(e))?;
|
||||||
|
|
|
@ -38,10 +38,10 @@ ecb.workspace = true
|
||||||
elliptic-curve.workspace = true
|
elliptic-curve.workspace = true
|
||||||
errno = "0.2.8"
|
errno = "0.2.8"
|
||||||
faster-hex.workspace = true
|
faster-hex.workspace = true
|
||||||
h2 = { version = "0.3.26", features = ["unstable"] }
|
h2.workspace = true
|
||||||
hkdf.workspace = true
|
hkdf.workspace = true
|
||||||
home = "0.5.9"
|
home = "0.5.9"
|
||||||
http_v02.workspace = true
|
http.workspace = true
|
||||||
idna = "0.3.0"
|
idna = "0.3.0"
|
||||||
indexmap.workspace = true
|
indexmap.workspace = true
|
||||||
ipnetwork = "0.20.0"
|
ipnetwork = "0.20.0"
|
||||||
|
|
|
@ -26,11 +26,11 @@ use deno_net::raw::NetworkStream;
|
||||||
use h2;
|
use h2;
|
||||||
use h2::Reason;
|
use h2::Reason;
|
||||||
use h2::RecvStream;
|
use h2::RecvStream;
|
||||||
use http_v02;
|
use http;
|
||||||
use http_v02::request::Parts;
|
use http::request::Parts;
|
||||||
use http_v02::HeaderMap;
|
use http::HeaderMap;
|
||||||
use http_v02::Response;
|
use http::Response;
|
||||||
use http_v02::StatusCode;
|
use http::StatusCode;
|
||||||
use reqwest::header::HeaderName;
|
use reqwest::header::HeaderName;
|
||||||
use reqwest::header::HeaderValue;
|
use reqwest::header::HeaderValue;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -311,7 +311,7 @@ pub async fn op_http2_client_request(
|
||||||
|
|
||||||
let url = url.join(&pseudo_path)?;
|
let url = url.join(&pseudo_path)?;
|
||||||
|
|
||||||
let mut req = http_v02::Request::builder()
|
let mut req = http::Request::builder()
|
||||||
.uri(url.as_str())
|
.uri(url.as_str())
|
||||||
.method(pseudo_method.as_str());
|
.method(pseudo_method.as_str());
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ pub async fn op_http2_client_send_trailers(
|
||||||
.get::<Http2ClientStream>(stream_rid)?;
|
.get::<Http2ClientStream>(stream_rid)?;
|
||||||
let mut stream = RcRef::map(&resource, |r| &r.stream).borrow_mut().await;
|
let mut stream = RcRef::map(&resource, |r| &r.stream).borrow_mut().await;
|
||||||
|
|
||||||
let mut trailers_map = http_v02::HeaderMap::new();
|
let mut trailers_map = http::HeaderMap::new();
|
||||||
for (name, value) in trailers {
|
for (name, value) in trailers {
|
||||||
trailers_map.insert(
|
trailers_map.insert(
|
||||||
HeaderName::from_bytes(&name).unwrap(),
|
HeaderName::from_bytes(&name).unwrap(),
|
||||||
|
|
|
@ -15,8 +15,8 @@ path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_core.workspace = true
|
deno_core.workspace = true
|
||||||
deno_native_certs = "0.2.0"
|
deno_native_certs = "0.3.0"
|
||||||
rustls = { workspace = true, features = ["dangerous_configuration"] }
|
rustls.workspace = true
|
||||||
rustls-pemfile.workspace = true
|
rustls-pemfile.workspace = true
|
||||||
rustls-tokio-stream.workspace = true
|
rustls-tokio-stream.workspace = true
|
||||||
rustls-webpki.workspace = true
|
rustls-webpki.workspace = true
|
||||||
|
|
177
ext/tls/lib.rs
177
ext/tls/lib.rs
|
@ -1,7 +1,9 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
pub use deno_native_certs;
|
pub use deno_native_certs;
|
||||||
pub use rustls;
|
pub use rustls;
|
||||||
|
use rustls::pki_types::CertificateDer;
|
||||||
|
use rustls::pki_types::PrivateKeyDer;
|
||||||
|
use rustls::pki_types::ServerName;
|
||||||
pub use rustls_pemfile;
|
pub use rustls_pemfile;
|
||||||
pub use rustls_tokio_stream::*;
|
pub use rustls_tokio_stream::*;
|
||||||
pub use webpki;
|
pub use webpki;
|
||||||
|
@ -11,14 +13,14 @@ use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::custom_error;
|
use deno_core::error::custom_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
|
||||||
use rustls::client::HandshakeSignatureValid;
|
use rustls::client::danger::HandshakeSignatureValid;
|
||||||
use rustls::client::ServerCertVerified;
|
use rustls::client::danger::ServerCertVerified;
|
||||||
use rustls::client::ServerCertVerifier;
|
use rustls::client::danger::ServerCertVerifier;
|
||||||
use rustls::client::WebPkiVerifier;
|
use rustls::client::WebPkiServerVerifier;
|
||||||
use rustls::ClientConfig;
|
use rustls::ClientConfig;
|
||||||
use rustls::DigitallySignedStruct;
|
use rustls::DigitallySignedStruct;
|
||||||
use rustls::Error;
|
use rustls::Error;
|
||||||
use rustls::ServerName;
|
use rustls::RootCertStore;
|
||||||
use rustls_pemfile::certs;
|
use rustls_pemfile::certs;
|
||||||
use rustls_pemfile::ec_private_keys;
|
use rustls_pemfile::ec_private_keys;
|
||||||
use rustls_pemfile::pkcs8_private_keys;
|
use rustls_pemfile::pkcs8_private_keys;
|
||||||
|
@ -27,16 +29,12 @@ use serde::Deserialize;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
use std::net::IpAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::SystemTime;
|
|
||||||
|
|
||||||
mod tls_key;
|
mod tls_key;
|
||||||
pub use tls_key::*;
|
pub use tls_key::*;
|
||||||
|
|
||||||
pub type Certificate = rustls::Certificate;
|
|
||||||
pub type PrivateKey = rustls::PrivateKey;
|
|
||||||
pub type RootCertStore = rustls::RootCertStore;
|
|
||||||
|
|
||||||
/// Lazily resolves the root cert store.
|
/// Lazily resolves the root cert store.
|
||||||
///
|
///
|
||||||
/// This was done because the root cert store is not needed in all cases
|
/// This was done because the root cert store is not needed in all cases
|
||||||
|
@ -48,56 +46,59 @@ pub trait RootCertStoreProvider: Send + Sync {
|
||||||
// This extension has no runtime apis, it only exports some shared native functions.
|
// This extension has no runtime apis, it only exports some shared native functions.
|
||||||
deno_core::extension!(deno_tls);
|
deno_core::extension!(deno_tls);
|
||||||
|
|
||||||
struct DefaultSignatureVerification;
|
#[derive(Debug)]
|
||||||
|
pub struct NoCertificateVerification {
|
||||||
impl ServerCertVerifier for DefaultSignatureVerification {
|
pub ic_allowlist: Vec<String>,
|
||||||
fn verify_server_cert(
|
default_verifier: Arc<WebPkiServerVerifier>,
|
||||||
&self,
|
|
||||||
_end_entity: &Certificate,
|
|
||||||
_intermediates: &[Certificate],
|
|
||||||
_server_name: &ServerName,
|
|
||||||
_scts: &mut dyn Iterator<Item = &[u8]>,
|
|
||||||
_ocsp_response: &[u8],
|
|
||||||
_now: SystemTime,
|
|
||||||
) -> Result<ServerCertVerified, Error> {
|
|
||||||
Err(Error::General("Should not be used".to_string()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NoCertificateVerification(pub Vec<String>);
|
impl NoCertificateVerification {
|
||||||
|
pub fn new(ic_allowlist: Vec<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
ic_allowlist,
|
||||||
|
default_verifier: WebPkiServerVerifier::builder(
|
||||||
|
create_default_root_cert_store().into(),
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
.unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ServerCertVerifier for NoCertificateVerification {
|
impl ServerCertVerifier for NoCertificateVerification {
|
||||||
|
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
||||||
|
self.default_verifier.supported_verify_schemes()
|
||||||
|
}
|
||||||
|
|
||||||
fn verify_server_cert(
|
fn verify_server_cert(
|
||||||
&self,
|
&self,
|
||||||
end_entity: &Certificate,
|
end_entity: &rustls::pki_types::CertificateDer<'_>,
|
||||||
intermediates: &[Certificate],
|
intermediates: &[rustls::pki_types::CertificateDer<'_>],
|
||||||
server_name: &ServerName,
|
server_name: &rustls::pki_types::ServerName<'_>,
|
||||||
scts: &mut dyn Iterator<Item = &[u8]>,
|
|
||||||
ocsp_response: &[u8],
|
ocsp_response: &[u8],
|
||||||
now: SystemTime,
|
now: rustls::pki_types::UnixTime,
|
||||||
) -> Result<ServerCertVerified, Error> {
|
) -> Result<ServerCertVerified, Error> {
|
||||||
if self.0.is_empty() {
|
if self.ic_allowlist.is_empty() {
|
||||||
return Ok(ServerCertVerified::assertion());
|
return Ok(ServerCertVerified::assertion());
|
||||||
}
|
}
|
||||||
let dns_name_or_ip_address = match server_name {
|
let dns_name_or_ip_address = match server_name {
|
||||||
ServerName::DnsName(dns_name) => dns_name.as_ref().to_owned(),
|
ServerName::DnsName(dns_name) => dns_name.as_ref().to_owned(),
|
||||||
ServerName::IpAddress(ip_address) => ip_address.to_string(),
|
ServerName::IpAddress(ip_address) => {
|
||||||
|
Into::<IpAddr>::into(*ip_address).to_string()
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// NOTE(bartlomieju): `ServerName` is a non-exhaustive enum
|
// NOTE(bartlomieju): `ServerName` is a non-exhaustive enum
|
||||||
// so we have this catch all errors here.
|
// so we have this catch all errors here.
|
||||||
return Err(Error::General("Unknown `ServerName` variant".to_string()));
|
return Err(Error::General("Unknown `ServerName` variant".to_string()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if self.0.contains(&dns_name_or_ip_address) {
|
if self.ic_allowlist.contains(&dns_name_or_ip_address) {
|
||||||
Ok(ServerCertVerified::assertion())
|
Ok(ServerCertVerified::assertion())
|
||||||
} else {
|
} else {
|
||||||
let root_store = create_default_root_cert_store();
|
self.default_verifier.verify_server_cert(
|
||||||
let verifier = WebPkiVerifier::new(root_store, None);
|
|
||||||
verifier.verify_server_cert(
|
|
||||||
end_entity,
|
end_entity,
|
||||||
intermediates,
|
intermediates,
|
||||||
server_name,
|
server_name,
|
||||||
scts,
|
|
||||||
ocsp_response,
|
ocsp_response,
|
||||||
now,
|
now,
|
||||||
)
|
)
|
||||||
|
@ -107,28 +108,32 @@ impl ServerCertVerifier for NoCertificateVerification {
|
||||||
fn verify_tls12_signature(
|
fn verify_tls12_signature(
|
||||||
&self,
|
&self,
|
||||||
message: &[u8],
|
message: &[u8],
|
||||||
cert: &rustls::Certificate,
|
cert: &rustls::pki_types::CertificateDer,
|
||||||
dss: &DigitallySignedStruct,
|
dss: &DigitallySignedStruct,
|
||||||
) -> Result<HandshakeSignatureValid, Error> {
|
) -> Result<HandshakeSignatureValid, Error> {
|
||||||
if self.0.is_empty() {
|
if self.ic_allowlist.is_empty() {
|
||||||
return Ok(HandshakeSignatureValid::assertion());
|
return Ok(HandshakeSignatureValid::assertion());
|
||||||
}
|
}
|
||||||
filter_invalid_encoding_err(
|
filter_invalid_encoding_err(
|
||||||
DefaultSignatureVerification.verify_tls12_signature(message, cert, dss),
|
self
|
||||||
|
.default_verifier
|
||||||
|
.verify_tls12_signature(message, cert, dss),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_tls13_signature(
|
fn verify_tls13_signature(
|
||||||
&self,
|
&self,
|
||||||
message: &[u8],
|
message: &[u8],
|
||||||
cert: &rustls::Certificate,
|
cert: &rustls::pki_types::CertificateDer,
|
||||||
dss: &DigitallySignedStruct,
|
dss: &DigitallySignedStruct,
|
||||||
) -> Result<HandshakeSignatureValid, Error> {
|
) -> Result<HandshakeSignatureValid, Error> {
|
||||||
if self.0.is_empty() {
|
if self.ic_allowlist.is_empty() {
|
||||||
return Ok(HandshakeSignatureValid::assertion());
|
return Ok(HandshakeSignatureValid::assertion());
|
||||||
}
|
}
|
||||||
filter_invalid_encoding_err(
|
filter_invalid_encoding_err(
|
||||||
DefaultSignatureVerification.verify_tls13_signature(message, cert, dss),
|
self
|
||||||
|
.default_verifier
|
||||||
|
.verify_tls13_signature(message, cert, dss),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,17 +154,10 @@ pub struct BasicAuth {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_default_root_cert_store() -> RootCertStore {
|
pub fn create_default_root_cert_store() -> RootCertStore {
|
||||||
let mut root_cert_store = RootCertStore::empty();
|
let root_cert_store = rustls::RootCertStore {
|
||||||
// TODO(@justinmchase): Consider also loading the system keychain here
|
roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(),
|
||||||
root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(
|
};
|
||||||
|ta| {
|
debug_assert!(!root_cert_store.is_empty());
|
||||||
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
|
||||||
ta.subject,
|
|
||||||
ta.spki,
|
|
||||||
ta.name_constraints,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
));
|
|
||||||
root_cert_store
|
root_cert_store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,10 +181,10 @@ pub fn create_client_config(
|
||||||
) -> Result<ClientConfig, AnyError> {
|
) -> Result<ClientConfig, AnyError> {
|
||||||
if let Some(ic_allowlist) = unsafely_ignore_certificate_errors {
|
if let Some(ic_allowlist) = unsafely_ignore_certificate_errors {
|
||||||
let client_config = ClientConfig::builder()
|
let client_config = ClientConfig::builder()
|
||||||
.with_safe_defaults()
|
.dangerous()
|
||||||
.with_custom_certificate_verifier(Arc::new(NoCertificateVerification(
|
.with_custom_certificate_verifier(Arc::new(
|
||||||
ic_allowlist,
|
NoCertificateVerification::new(ic_allowlist),
|
||||||
)));
|
));
|
||||||
|
|
||||||
// NOTE(bartlomieju): this if/else is duplicated at the end of the body of this function.
|
// NOTE(bartlomieju): this if/else is duplicated at the end of the body of this function.
|
||||||
// However it's not really feasible to deduplicate it as the `client_config` instances
|
// However it's not really feasible to deduplicate it as the `client_config` instances
|
||||||
|
@ -194,7 +192,7 @@ pub fn create_client_config(
|
||||||
// or client cert".
|
// or client cert".
|
||||||
let mut client = match maybe_cert_chain_and_key {
|
let mut client = match maybe_cert_chain_and_key {
|
||||||
TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config
|
TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config
|
||||||
.with_client_auth_cert(cert_chain, private_key)
|
.with_client_auth_cert(cert_chain, private_key.clone_key())
|
||||||
.expect("invalid client key or certificate"),
|
.expect("invalid client key or certificate"),
|
||||||
TlsKeys::Null => client_config.with_no_client_auth(),
|
TlsKeys::Null => client_config.with_no_client_auth(),
|
||||||
TlsKeys::Resolver(_) => unimplemented!(),
|
TlsKeys::Resolver(_) => unimplemented!(),
|
||||||
|
@ -204,18 +202,16 @@ pub fn create_client_config(
|
||||||
return Ok(client);
|
return Ok(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
let client_config = ClientConfig::builder()
|
|
||||||
.with_safe_defaults()
|
|
||||||
.with_root_certificates({
|
|
||||||
let mut root_cert_store =
|
let mut root_cert_store =
|
||||||
root_cert_store.unwrap_or_else(create_default_root_cert_store);
|
root_cert_store.unwrap_or_else(create_default_root_cert_store);
|
||||||
// If custom certs are specified, add them to the store
|
// If custom certs are specified, add them to the store
|
||||||
for cert in ca_certs {
|
for cert in ca_certs {
|
||||||
let reader = &mut BufReader::new(Cursor::new(cert));
|
let reader = &mut BufReader::new(Cursor::new(cert));
|
||||||
// This function does not return specific errors, if it fails give a generic message.
|
// This function does not return specific errors, if it fails give a generic message.
|
||||||
match rustls_pemfile::certs(reader) {
|
for r in rustls_pemfile::certs(reader) {
|
||||||
Ok(certs) => {
|
match r {
|
||||||
root_cert_store.add_parsable_certificates(&certs);
|
Ok(cert) => {
|
||||||
|
root_cert_store.add(cert)?;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
|
@ -225,12 +221,14 @@ pub fn create_client_config(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root_cert_store
|
}
|
||||||
});
|
|
||||||
|
let client_config =
|
||||||
|
ClientConfig::builder().with_root_certificates(root_cert_store);
|
||||||
|
|
||||||
let mut client = match maybe_cert_chain_and_key {
|
let mut client = match maybe_cert_chain_and_key {
|
||||||
TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config
|
TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config
|
||||||
.with_client_auth_cert(cert_chain, private_key)
|
.with_client_auth_cert(cert_chain, private_key.clone_key())
|
||||||
.expect("invalid client key or certificate"),
|
.expect("invalid client key or certificate"),
|
||||||
TlsKeys::Null => client_config.with_no_client_auth(),
|
TlsKeys::Null => client_config.with_no_client_auth(),
|
||||||
TlsKeys::Resolver(_) => unimplemented!(),
|
TlsKeys::Resolver(_) => unimplemented!(),
|
||||||
|
@ -257,15 +255,17 @@ fn add_alpn(client: &mut ClientConfig, socket_use: SocketUse) {
|
||||||
|
|
||||||
pub fn load_certs(
|
pub fn load_certs(
|
||||||
reader: &mut dyn BufRead,
|
reader: &mut dyn BufRead,
|
||||||
) -> Result<Vec<Certificate>, AnyError> {
|
) -> Result<Vec<CertificateDer<'static>>, AnyError> {
|
||||||
let certs = certs(reader)
|
let certs: Result<Vec<_>, _> = certs(reader).collect();
|
||||||
|
|
||||||
|
let certs = certs
|
||||||
.map_err(|_| custom_error("InvalidData", "Unable to decode certificate"))?;
|
.map_err(|_| custom_error("InvalidData", "Unable to decode certificate"))?;
|
||||||
|
|
||||||
if certs.is_empty() {
|
if certs.is_empty() {
|
||||||
return Err(cert_not_found_err());
|
return Err(cert_not_found_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(certs.into_iter().map(rustls::Certificate).collect())
|
Ok(certs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_decode_err() -> AnyError {
|
fn key_decode_err() -> AnyError {
|
||||||
|
@ -281,21 +281,32 @@ fn cert_not_found_err() -> AnyError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts with -----BEGIN RSA PRIVATE KEY-----
|
/// Starts with -----BEGIN RSA PRIVATE KEY-----
|
||||||
fn load_rsa_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
|
fn load_rsa_keys(
|
||||||
let keys = rsa_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
|
mut bytes: &[u8],
|
||||||
Ok(keys.into_iter().map(rustls::PrivateKey).collect())
|
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
|
||||||
|
let keys: Result<Vec<_>, _> = rsa_private_keys(&mut bytes).collect();
|
||||||
|
let keys = keys.map_err(|_| key_decode_err())?;
|
||||||
|
Ok(keys.into_iter().map(PrivateKeyDer::Pkcs1).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts with -----BEGIN EC PRIVATE KEY-----
|
/// Starts with -----BEGIN EC PRIVATE KEY-----
|
||||||
fn load_ec_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
|
fn load_ec_keys(
|
||||||
let keys = ec_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
|
mut bytes: &[u8],
|
||||||
Ok(keys.into_iter().map(rustls::PrivateKey).collect())
|
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
|
||||||
|
let keys: Result<Vec<_>, std::io::Error> =
|
||||||
|
ec_private_keys(&mut bytes).collect();
|
||||||
|
let keys2 = keys.map_err(|_| key_decode_err())?;
|
||||||
|
Ok(keys2.into_iter().map(PrivateKeyDer::Sec1).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts with -----BEGIN PRIVATE KEY-----
|
/// Starts with -----BEGIN PRIVATE KEY-----
|
||||||
fn load_pkcs8_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
|
fn load_pkcs8_keys(
|
||||||
let keys = pkcs8_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
|
mut bytes: &[u8],
|
||||||
Ok(keys.into_iter().map(rustls::PrivateKey).collect())
|
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
|
||||||
|
let keys: Result<Vec<_>, std::io::Error> =
|
||||||
|
pkcs8_private_keys(&mut bytes).collect();
|
||||||
|
let keys2 = keys.map_err(|_| key_decode_err())?;
|
||||||
|
Ok(keys2.into_iter().map(PrivateKeyDer::Pkcs8).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_invalid_encoding_err(
|
fn filter_invalid_encoding_err(
|
||||||
|
@ -309,7 +320,9 @@ fn filter_invalid_encoding_err(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_private_keys(bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
|
pub fn load_private_keys(
|
||||||
|
bytes: &[u8],
|
||||||
|
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
|
||||||
let mut keys = load_rsa_keys(bytes)?;
|
let mut keys = load_rsa_keys(bytes)?;
|
||||||
|
|
||||||
if keys.is_empty() {
|
if keys.is_empty() {
|
||||||
|
|
4
ext/tls/testdata/README
vendored
Normal file
4
ext/tls/testdata/README
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
openssl req -x509 -newkey rsa:2048 -nodes -keyout example2_prikey.pem -out example2_cert.der -subj "/C=US/ST=State/L=Locality/O=Organization/CN=example2.com" -outform der
|
||||||
|
|
||||||
|
openssl pkey -in example2_prikey.pem -out example2_prikey.der -outform der
|
BIN
ext/tls/testdata/example1_cert.der
vendored
Normal file
BIN
ext/tls/testdata/example1_cert.der
vendored
Normal file
Binary file not shown.
BIN
ext/tls/testdata/example1_prikey.der
vendored
Normal file
BIN
ext/tls/testdata/example1_prikey.der
vendored
Normal file
Binary file not shown.
BIN
ext/tls/testdata/example2_cert.der
vendored
Normal file
BIN
ext/tls/testdata/example2_cert.der
vendored
Normal file
Binary file not shown.
BIN
ext/tls/testdata/example2_prikey.der
vendored
Normal file
BIN
ext/tls/testdata/example2_prikey.der
vendored
Normal file
Binary file not shown.
|
@ -11,8 +11,6 @@
|
||||||
//! key lookup can handle closing one end of the pair, in which case they will just
|
//! key lookup can handle closing one end of the pair, in which case they will just
|
||||||
//! attempt to clean up the associated resources.
|
//! attempt to clean up the associated resources.
|
||||||
|
|
||||||
use crate::Certificate;
|
|
||||||
use crate::PrivateKey;
|
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future::poll_fn;
|
use deno_core::futures::future::poll_fn;
|
||||||
|
@ -32,12 +30,21 @@ use std::sync::Arc;
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
use webpki::types::CertificateDer;
|
||||||
|
use webpki::types::PrivateKeyDer;
|
||||||
|
|
||||||
type ErrorType = Rc<AnyError>;
|
type ErrorType = Rc<AnyError>;
|
||||||
|
|
||||||
/// A TLS certificate/private key pair.
|
/// A TLS certificate/private key pair.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
/// see https://docs.rs/rustls-pki-types/latest/rustls_pki_types/#cloning-private-keys
|
||||||
pub struct TlsKey(pub Vec<Certificate>, pub PrivateKey);
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct TlsKey(pub Vec<CertificateDer<'static>>, pub PrivateKeyDer<'static>);
|
||||||
|
|
||||||
|
impl Clone for TlsKey {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self(self.0.clone(), self.1.clone_key())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub enum TlsKeys {
|
pub enum TlsKeys {
|
||||||
|
@ -111,9 +118,8 @@ impl TlsKeyResolver {
|
||||||
let key = self.resolve(sni).await?;
|
let key = self.resolve(sni).await?;
|
||||||
|
|
||||||
let mut tls_config = ServerConfig::builder()
|
let mut tls_config = ServerConfig::builder()
|
||||||
.with_safe_defaults()
|
|
||||||
.with_no_client_auth()
|
.with_no_client_auth()
|
||||||
.with_single_cert(key.0, key.1)?;
|
.with_single_cert(key.0, key.1.clone_key())?;
|
||||||
tls_config.alpn_protocols = alpn;
|
tls_config.alpn_protocols = alpn;
|
||||||
Ok(tls_config.into())
|
Ok(tls_config.into())
|
||||||
}
|
}
|
||||||
|
@ -255,14 +261,18 @@ impl TlsKeyLookup {
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use deno_core::unsync::spawn;
|
use deno_core::unsync::spawn;
|
||||||
use rustls::Certificate;
|
|
||||||
use rustls::PrivateKey;
|
|
||||||
|
|
||||||
fn tls_key_for_test(sni: &str) -> TlsKey {
|
fn tls_key_for_test(sni: &str) -> TlsKey {
|
||||||
TlsKey(
|
let manifest_dir =
|
||||||
vec![Certificate(format!("{sni}-cert").into_bytes())],
|
std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||||
PrivateKey(format!("{sni}-key").into_bytes()),
|
let sni = sni.replace(".com", "");
|
||||||
)
|
let cert_file = manifest_dir.join(format!("testdata/{}_cert.der", sni));
|
||||||
|
let prikey_file = manifest_dir.join(format!("testdata/{}_prikey.der", sni));
|
||||||
|
let cert = std::fs::read(cert_file).unwrap();
|
||||||
|
let prikey = std::fs::read(prikey_file).unwrap();
|
||||||
|
let cert = CertificateDer::from(cert);
|
||||||
|
let prikey = PrivateKeyDer::try_from(prikey).unwrap();
|
||||||
|
TlsKey(vec![cert], prikey)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -274,8 +284,8 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let key = resolver.resolve("example.com".to_owned()).await.unwrap();
|
let key = resolver.resolve("example1.com".to_owned()).await.unwrap();
|
||||||
assert_eq!(tls_key_for_test("example.com"), key);
|
assert_eq!(tls_key_for_test("example1.com"), key);
|
||||||
drop(resolver);
|
drop(resolver);
|
||||||
|
|
||||||
task.await.unwrap();
|
task.await.unwrap();
|
||||||
|
@ -290,13 +300,13 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let f1 = resolver.resolve("example.com".to_owned());
|
let f1 = resolver.resolve("example1.com".to_owned());
|
||||||
let f2 = resolver.resolve("example.com".to_owned());
|
let f2 = resolver.resolve("example1.com".to_owned());
|
||||||
|
|
||||||
let key = f1.await.unwrap();
|
let key = f1.await.unwrap();
|
||||||
assert_eq!(tls_key_for_test("example.com"), key);
|
assert_eq!(tls_key_for_test("example1.com"), key);
|
||||||
let key = f2.await.unwrap();
|
let key = f2.await.unwrap();
|
||||||
assert_eq!(tls_key_for_test("example.com"), key);
|
assert_eq!(tls_key_for_test("example1.com"), key);
|
||||||
drop(resolver);
|
drop(resolver);
|
||||||
|
|
||||||
task.await.unwrap();
|
task.await.unwrap();
|
||||||
|
|
|
@ -36,14 +36,13 @@ use http::Request;
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
use http::Uri;
|
use http::Uri;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use rustls_tokio_stream::rustls::pki_types::ServerName;
|
||||||
use rustls_tokio_stream::rustls::RootCertStore;
|
use rustls_tokio_stream::rustls::RootCertStore;
|
||||||
use rustls_tokio_stream::rustls::ServerName;
|
|
||||||
use rustls_tokio_stream::TlsStream;
|
use rustls_tokio_stream::TlsStream;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
@ -245,8 +244,8 @@ async fn handshake_http1_wss(
|
||||||
) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
|
) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
|
||||||
let tcp_socket = TcpStream::connect(addr).await?;
|
let tcp_socket = TcpStream::connect(addr).await?;
|
||||||
let tls_config = create_ws_client_config(state, SocketUse::Http1Only)?;
|
let tls_config = create_ws_client_config(state, SocketUse::Http1Only)?;
|
||||||
let dnsname =
|
let dnsname = ServerName::try_from(domain.to_string())
|
||||||
ServerName::try_from(domain).map_err(|_| invalid_hostname(domain))?;
|
.map_err(|_| invalid_hostname(domain))?;
|
||||||
let mut tls_connector = TlsStream::new_client_side(
|
let mut tls_connector = TlsStream::new_client_side(
|
||||||
tcp_socket,
|
tcp_socket,
|
||||||
ClientConnection::new(tls_config.into(), dnsname)?,
|
ClientConnection::new(tls_config.into(), dnsname)?,
|
||||||
|
@ -270,8 +269,8 @@ async fn handshake_http2_wss(
|
||||||
) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
|
) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
|
||||||
let tcp_socket = TcpStream::connect(addr).await?;
|
let tcp_socket = TcpStream::connect(addr).await?;
|
||||||
let tls_config = create_ws_client_config(state, SocketUse::Http2Only)?;
|
let tls_config = create_ws_client_config(state, SocketUse::Http2Only)?;
|
||||||
let dnsname =
|
let dnsname = ServerName::try_from(domain.to_string())
|
||||||
ServerName::try_from(domain).map_err(|_| invalid_hostname(domain))?;
|
.map_err(|_| invalid_hostname(domain))?;
|
||||||
// We need to better expose the underlying errors here
|
// We need to better expose the underlying errors here
|
||||||
let mut tls_connector = TlsStream::new_client_side(
|
let mut tls_connector = TlsStream::new_client_side(
|
||||||
tcp_socket,
|
tcp_socket,
|
||||||
|
|
|
@ -5303,17 +5303,19 @@ async fn listen_tls_alpn() {
|
||||||
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
||||||
"../testdata/tls/RootCA.crt"
|
"../testdata/tls/RootCA.crt"
|
||||||
)));
|
)));
|
||||||
let certs = rustls_pemfile::certs(&mut reader).unwrap();
|
let certs = rustls_pemfile::certs(&mut reader)
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.unwrap();
|
||||||
let mut root_store = rustls::RootCertStore::empty();
|
let mut root_store = rustls::RootCertStore::empty();
|
||||||
root_store.add_parsable_certificates(&certs);
|
root_store.add_parsable_certificates(certs);
|
||||||
let mut cfg = rustls::ClientConfig::builder()
|
let mut cfg = rustls::ClientConfig::builder()
|
||||||
.with_safe_defaults()
|
|
||||||
.with_root_certificates(root_store)
|
.with_root_certificates(root_store)
|
||||||
.with_no_client_auth();
|
.with_no_client_auth();
|
||||||
cfg.alpn_protocols.push(b"foobar".to_vec());
|
cfg.alpn_protocols.push(b"foobar".to_vec());
|
||||||
let cfg = Arc::new(cfg);
|
let cfg = Arc::new(cfg);
|
||||||
|
|
||||||
let hostname = rustls::ServerName::try_from("localhost").unwrap();
|
let hostname =
|
||||||
|
rustls::pki_types::ServerName::try_from("localhost".to_string()).unwrap();
|
||||||
|
|
||||||
let tcp_stream = tokio::net::TcpStream::connect("localhost:4504")
|
let tcp_stream = tokio::net::TcpStream::connect("localhost:4504")
|
||||||
.await
|
.await
|
||||||
|
@ -5355,17 +5357,18 @@ async fn listen_tls_alpn_fail() {
|
||||||
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
|
||||||
"../testdata/tls/RootCA.crt"
|
"../testdata/tls/RootCA.crt"
|
||||||
)));
|
)));
|
||||||
let certs = rustls_pemfile::certs(&mut reader).unwrap();
|
let certs = rustls_pemfile::certs(&mut reader)
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.unwrap();
|
||||||
let mut root_store = rustls::RootCertStore::empty();
|
let mut root_store = rustls::RootCertStore::empty();
|
||||||
root_store.add_parsable_certificates(&certs);
|
root_store.add_parsable_certificates(certs);
|
||||||
let mut cfg = rustls::ClientConfig::builder()
|
let mut cfg = rustls::ClientConfig::builder()
|
||||||
.with_safe_defaults()
|
|
||||||
.with_root_certificates(root_store)
|
.with_root_certificates(root_store)
|
||||||
.with_no_client_auth();
|
.with_no_client_auth();
|
||||||
cfg.alpn_protocols.push(b"boofar".to_vec());
|
cfg.alpn_protocols.push(b"boofar".to_vec());
|
||||||
let cfg = Arc::new(cfg);
|
let cfg = Arc::new(cfg);
|
||||||
|
|
||||||
let hostname = rustls::ServerName::try_from("localhost").unwrap();
|
let hostname = rustls::pki_types::ServerName::try_from("localhost").unwrap();
|
||||||
|
|
||||||
let tcp_stream = tokio::net::TcpStream::connect("localhost:4505")
|
let tcp_stream = tokio::net::TcpStream::connect("localhost:4505")
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -394,14 +394,8 @@
|
||||||
// "test-http-outgoing-message-inheritance.js",
|
// "test-http-outgoing-message-inheritance.js",
|
||||||
"test-http-outgoing-renderHeaders.js",
|
"test-http-outgoing-renderHeaders.js",
|
||||||
"test-http-outgoing-settimeout.js",
|
"test-http-outgoing-settimeout.js",
|
||||||
"test-http-url.parse-auth-with-header-in-request.js",
|
|
||||||
"test-http-url.parse-auth.js",
|
|
||||||
"test-http-url.parse-basic.js",
|
|
||||||
"test-http-url.parse-https.request.js",
|
"test-http-url.parse-https.request.js",
|
||||||
"test-http-url.parse-only-support-http-https-protocol.js",
|
"test-http-url.parse-only-support-http-https-protocol.js",
|
||||||
"test-http-url.parse-path.js",
|
|
||||||
"test-http-url.parse-post.js",
|
|
||||||
"test-http-url.parse-search.js",
|
|
||||||
"test-net-access-byteswritten.js",
|
"test-net-access-byteswritten.js",
|
||||||
"test-net-better-error-messages-listen-path.js",
|
"test-net-better-error-messages-listen-path.js",
|
||||||
"test-net-better-error-messages-path.js",
|
"test-net-better-error-messages-path.js",
|
||||||
|
|
|
@ -1307,6 +1307,12 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co
|
||||||
- [parallel/test-http-upgrade-reconsume-stream.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-reconsume-stream.js)
|
- [parallel/test-http-upgrade-reconsume-stream.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-reconsume-stream.js)
|
||||||
- [parallel/test-http-upgrade-server.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server.js)
|
- [parallel/test-http-upgrade-server.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server.js)
|
||||||
- [parallel/test-http-upgrade-server2.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server2.js)
|
- [parallel/test-http-upgrade-server2.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server2.js)
|
||||||
|
- [parallel/test-http-url.parse-auth-with-header-in-request.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-auth-with-header-in-request.js)
|
||||||
|
- [parallel/test-http-url.parse-auth.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-auth.js)
|
||||||
|
- [parallel/test-http-url.parse-basic.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-basic.js)
|
||||||
|
- [parallel/test-http-url.parse-path.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-path.js)
|
||||||
|
- [parallel/test-http-url.parse-post.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-post.js)
|
||||||
|
- [parallel/test-http-url.parse-search.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-search.js)
|
||||||
- [parallel/test-http-wget.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-wget.js)
|
- [parallel/test-http-wget.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-wget.js)
|
||||||
- [parallel/test-http-writable-true-after-close.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-writable-true-after-close.js)
|
- [parallel/test-http-writable-true-after-close.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-writable-true-after-close.js)
|
||||||
- [parallel/test-http-write-callbacks.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-write-callbacks.js)
|
- [parallel/test-http-write-callbacks.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-write-callbacks.js)
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
// deno-fmt-ignore-file
|
|
||||||
// deno-lint-ignore-file
|
|
||||||
|
|
||||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
|
||||||
// Taken from Node 18.12.1
|
|
||||||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
|
|
||||||
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
function check(request) {
|
|
||||||
// The correct authorization header is be passed
|
|
||||||
assert.strictEqual(request.headers.authorization, 'NoAuthForYOU');
|
|
||||||
}
|
|
||||||
|
|
||||||
const server = http.createServer(function(request, response) {
|
|
||||||
// Run the check function
|
|
||||||
check(request);
|
|
||||||
response.writeHead(200, {});
|
|
||||||
response.end('ok');
|
|
||||||
server.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(0, function() {
|
|
||||||
const testURL =
|
|
||||||
url.parse(`http://asdf:qwer@localhost:${this.address().port}`);
|
|
||||||
// The test here is if you set a specific authorization header in the
|
|
||||||
// request we should not override that with basic auth
|
|
||||||
testURL.headers = {
|
|
||||||
Authorization: 'NoAuthForYOU'
|
|
||||||
};
|
|
||||||
|
|
||||||
// make the request
|
|
||||||
http.request(testURL).end();
|
|
||||||
});
|
|
|
@ -1,55 +0,0 @@
|
||||||
// deno-fmt-ignore-file
|
|
||||||
// deno-lint-ignore-file
|
|
||||||
|
|
||||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
|
||||||
// Taken from Node 18.12.1
|
|
||||||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
|
|
||||||
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
function check(request) {
|
|
||||||
// The correct authorization header is be passed
|
|
||||||
assert.strictEqual(request.headers.authorization, 'Basic dXNlcjpwYXNzOg==');
|
|
||||||
}
|
|
||||||
|
|
||||||
const server = http.createServer(function(request, response) {
|
|
||||||
// Run the check function
|
|
||||||
check(request);
|
|
||||||
response.writeHead(200, {});
|
|
||||||
response.end('ok');
|
|
||||||
server.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(0, function() {
|
|
||||||
const port = this.address().port;
|
|
||||||
// username = "user", password = "pass:"
|
|
||||||
const testURL = url.parse(`http://user:pass%3A@localhost:${port}`);
|
|
||||||
|
|
||||||
// make the request
|
|
||||||
http.request(testURL).end();
|
|
||||||
});
|
|
|
@ -1,65 +0,0 @@
|
||||||
// deno-fmt-ignore-file
|
|
||||||
// deno-lint-ignore-file
|
|
||||||
|
|
||||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
|
||||||
// Taken from Node 18.12.1
|
|
||||||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
|
|
||||||
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
let testURL;
|
|
||||||
|
|
||||||
// Make sure the basics work
|
|
||||||
function check(request) {
|
|
||||||
// Default method should still be 'GET'
|
|
||||||
assert.strictEqual(request.method, 'GET');
|
|
||||||
// There are no URL params, so you should not see any
|
|
||||||
assert.strictEqual(request.url, '/');
|
|
||||||
// The host header should use the url.parse.hostname
|
|
||||||
assert.strictEqual(request.headers.host,
|
|
||||||
`${testURL.hostname}:${testURL.port}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const server = http.createServer(function(request, response) {
|
|
||||||
// Run the check function
|
|
||||||
check(request);
|
|
||||||
response.writeHead(200, {});
|
|
||||||
response.end('ok');
|
|
||||||
server.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(0, function() {
|
|
||||||
testURL = url.parse(`http://localhost:${this.address().port}`);
|
|
||||||
|
|
||||||
// make the request
|
|
||||||
const clientRequest = http.request(testURL);
|
|
||||||
// Since there is a little magic with the agent
|
|
||||||
// make sure that an http request uses the http.Agent
|
|
||||||
assert.ok(clientRequest.agent instanceof http.Agent);
|
|
||||||
clientRequest.end();
|
|
||||||
});
|
|
|
@ -1,53 +0,0 @@
|
||||||
// deno-fmt-ignore-file
|
|
||||||
// deno-lint-ignore-file
|
|
||||||
|
|
||||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
|
||||||
// Taken from Node 18.12.1
|
|
||||||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
|
|
||||||
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
function check(request) {
|
|
||||||
// A path should come over
|
|
||||||
assert.strictEqual(request.url, '/asdf');
|
|
||||||
}
|
|
||||||
|
|
||||||
const server = http.createServer(function(request, response) {
|
|
||||||
// Run the check function
|
|
||||||
check(request);
|
|
||||||
response.writeHead(200, {});
|
|
||||||
response.end('ok');
|
|
||||||
server.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(0, function() {
|
|
||||||
const testURL = url.parse(`http://localhost:${this.address().port}/asdf`);
|
|
||||||
|
|
||||||
// make the request
|
|
||||||
http.request(testURL).end();
|
|
||||||
});
|
|
|
@ -1,61 +0,0 @@
|
||||||
// deno-fmt-ignore-file
|
|
||||||
// deno-lint-ignore-file
|
|
||||||
|
|
||||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
|
||||||
// Taken from Node 18.12.1
|
|
||||||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
|
|
||||||
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
let testURL;
|
|
||||||
|
|
||||||
function check(request) {
|
|
||||||
// url.parse should not mess with the method
|
|
||||||
assert.strictEqual(request.method, 'POST');
|
|
||||||
// Everything else should be right
|
|
||||||
assert.strictEqual(request.url, '/asdf?qwer=zxcv');
|
|
||||||
// The host header should use the url.parse.hostname
|
|
||||||
assert.strictEqual(request.headers.host,
|
|
||||||
`${testURL.hostname}:${testURL.port}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const server = http.createServer(function(request, response) {
|
|
||||||
// Run the check function
|
|
||||||
check(request);
|
|
||||||
response.writeHead(200, {});
|
|
||||||
response.end('ok');
|
|
||||||
server.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(0, function() {
|
|
||||||
testURL = url.parse(`http://localhost:${this.address().port}/asdf?qwer=zxcv`);
|
|
||||||
testURL.method = 'POST';
|
|
||||||
|
|
||||||
// make the request
|
|
||||||
http.request(testURL).end();
|
|
||||||
});
|
|
|
@ -1,54 +0,0 @@
|
||||||
// deno-fmt-ignore-file
|
|
||||||
// deno-lint-ignore-file
|
|
||||||
|
|
||||||
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
|
||||||
// Taken from Node 18.12.1
|
|
||||||
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
|
|
||||||
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const http = require('http');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
function check(request) {
|
|
||||||
// A path should come over with params
|
|
||||||
assert.strictEqual(request.url, '/asdf?qwer=zxcv');
|
|
||||||
}
|
|
||||||
|
|
||||||
const server = http.createServer(function(request, response) {
|
|
||||||
// Run the check function
|
|
||||||
check(request);
|
|
||||||
response.writeHead(200, {});
|
|
||||||
response.end('ok');
|
|
||||||
server.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
server.listen(0, function() {
|
|
||||||
const port = this.address().port;
|
|
||||||
const testURL = url.parse(`http://localhost:${port}/asdf?qwer=zxcv`);
|
|
||||||
|
|
||||||
// make the request
|
|
||||||
http.request(testURL).end();
|
|
||||||
});
|
|
|
@ -1,3 +1,3 @@
|
||||||
DANGER: TLS certificate validation is disabled for: deno.land
|
DANGER: TLS certificate validation is disabled for: deno.land
|
||||||
error: Import 'https://localhost:5545/subdir/mod2.ts' failed: error sending request for url (https://localhost:5545/subdir/mod2.ts): error trying to connect: invalid peer certificate: UnknownIssuer
|
error: Import 'https://localhost:5545/subdir/mod2.ts' failed: error sending request for url (https://localhost:5545/subdir/mod2.ts)
|
||||||
at file:///[WILDCARD]/cafile_url_imports.ts:[WILDCARD]
|
at file:///[WILDCARD]/cafile_url_imports.ts:[WILDCARD]
|
||||||
|
|
|
@ -67,7 +67,7 @@ Deno.test(
|
||||||
await fetch(`http://localhost:${port}`);
|
await fetch(`http://localhost:${port}`);
|
||||||
},
|
},
|
||||||
TypeError,
|
TypeError,
|
||||||
"error trying to connect",
|
"error sending request for url",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -80,7 +80,7 @@ Deno.test(
|
||||||
await fetch("http://nil/");
|
await fetch("http://nil/");
|
||||||
},
|
},
|
||||||
TypeError,
|
TypeError,
|
||||||
"error trying to connect",
|
"error sending request for url",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1824,7 +1824,7 @@ Deno.test(
|
||||||
await fetch(`http://${addr}/`);
|
await fetch(`http://${addr}/`);
|
||||||
},
|
},
|
||||||
TypeError,
|
TypeError,
|
||||||
"invalid content-length parsed",
|
"error sending request",
|
||||||
);
|
);
|
||||||
|
|
||||||
listener.close();
|
listener.close();
|
||||||
|
@ -1880,7 +1880,7 @@ Deno.test(
|
||||||
await response.arrayBuffer();
|
await response.arrayBuffer();
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
"end of file before message length reached",
|
"error decoding response body",
|
||||||
);
|
);
|
||||||
|
|
||||||
listener.close();
|
listener.close();
|
||||||
|
|
|
@ -2574,7 +2574,7 @@ for (const compression of [true, false]) {
|
||||||
assertEquals(result.value, new Uint8Array([65]));
|
assertEquals(result.value, new Uint8Array([65]));
|
||||||
const err = await assertRejects(() => reader.read());
|
const err = await assertRejects(() => reader.read());
|
||||||
assert(err instanceof TypeError);
|
assert(err instanceof TypeError);
|
||||||
assert(err.message.includes("unexpected EOF"));
|
assert(err.message.includes("error decoding response body"));
|
||||||
|
|
||||||
const httpConn = await server;
|
const httpConn = await server;
|
||||||
httpConn.close();
|
httpConn.close();
|
||||||
|
@ -2610,7 +2610,7 @@ for (const compression of [true, false]) {
|
||||||
assertEquals(result.value, new Uint8Array([65]));
|
assertEquals(result.value, new Uint8Array([65]));
|
||||||
const err = await assertRejects(() => reader.read());
|
const err = await assertRejects(() => reader.read());
|
||||||
assert(err instanceof TypeError);
|
assert(err instanceof TypeError);
|
||||||
assert(err.message.includes("unexpected internal error encountered"));
|
assert(err.message.includes("error decoding response body"));
|
||||||
|
|
||||||
const httpConn = await server;
|
const httpConn = await server;
|
||||||
httpConn.close();
|
httpConn.close();
|
||||||
|
|
|
@ -3522,11 +3522,7 @@ Deno.test(
|
||||||
fail();
|
fail();
|
||||||
} catch (clientError) {
|
} catch (clientError) {
|
||||||
assert(clientError instanceof TypeError);
|
assert(clientError instanceof TypeError);
|
||||||
assert(
|
assert(clientError.message.includes("error sending request for url"));
|
||||||
clientError.message.endsWith(
|
|
||||||
"connection closed before message completed",
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
ac.abort();
|
ac.abort();
|
||||||
await server.finished;
|
await server.finished;
|
||||||
|
@ -3574,11 +3570,7 @@ Deno.test({
|
||||||
fail();
|
fail();
|
||||||
} catch (clientError) {
|
} catch (clientError) {
|
||||||
assert(clientError instanceof TypeError);
|
assert(clientError instanceof TypeError);
|
||||||
assert(
|
assert(clientError.message.includes("error sending request for url"));
|
||||||
clientError.message.endsWith(
|
|
||||||
"connection closed before message completed",
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
ac.abort();
|
ac.abort();
|
||||||
await server.finished;
|
await server.finished;
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use rustls::Certificate;
|
|
||||||
use rustls::PrivateKey;
|
|
||||||
use rustls_tokio_stream::rustls;
|
use rustls_tokio_stream::rustls;
|
||||||
|
use rustls_tokio_stream::rustls::pki_types::CertificateDer;
|
||||||
|
use rustls_tokio_stream::rustls::pki_types::PrivateKeyDer;
|
||||||
use rustls_tokio_stream::TlsStream;
|
use rustls_tokio_stream::TlsStream;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
@ -68,30 +68,30 @@ pub fn get_tls_config(
|
||||||
let key_file = std::fs::File::open(key_path)?;
|
let key_file = std::fs::File::open(key_path)?;
|
||||||
let ca_file = std::fs::File::open(ca_path)?;
|
let ca_file = std::fs::File::open(ca_path)?;
|
||||||
|
|
||||||
let certs: Vec<Certificate> = {
|
let certs_result: Result<Vec<CertificateDer<'static>>, io::Error> = {
|
||||||
let mut cert_reader = io::BufReader::new(cert_file);
|
let mut cert_reader = io::BufReader::new(cert_file);
|
||||||
rustls_pemfile::certs(&mut cert_reader)
|
rustls_pemfile::certs(&mut cert_reader).collect()
|
||||||
.unwrap()
|
|
||||||
.into_iter()
|
|
||||||
.map(Certificate)
|
|
||||||
.collect()
|
|
||||||
};
|
};
|
||||||
|
let certs = certs_result?;
|
||||||
|
|
||||||
let mut ca_cert_reader = io::BufReader::new(ca_file);
|
let mut ca_cert_reader = io::BufReader::new(ca_file);
|
||||||
let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader)
|
let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader)
|
||||||
.expect("Cannot load CA certificate")
|
.collect::<Vec<_>>()
|
||||||
.remove(0);
|
.remove(0)?;
|
||||||
|
|
||||||
let mut key_reader = io::BufReader::new(key_file);
|
let mut key_reader = io::BufReader::new(key_file);
|
||||||
let key = {
|
let key = {
|
||||||
let pkcs8_key = rustls_pemfile::pkcs8_private_keys(&mut key_reader)
|
let pkcs8_keys = rustls_pemfile::pkcs8_private_keys(&mut key_reader)
|
||||||
.expect("Cannot load key file");
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let rsa_key = rustls_pemfile::rsa_private_keys(&mut key_reader)
|
let rsa_keys = rustls_pemfile::rsa_private_keys(&mut key_reader)
|
||||||
.expect("Cannot load key file");
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
if !pkcs8_key.is_empty() {
|
|
||||||
Some(pkcs8_key[0].clone())
|
if !pkcs8_keys.is_empty() {
|
||||||
} else if !rsa_key.is_empty() {
|
let key = pkcs8_keys[0].clone_key();
|
||||||
Some(rsa_key[0].clone())
|
Some(PrivateKeyDer::from(key))
|
||||||
|
} else if !rsa_keys.is_empty() {
|
||||||
|
let key = rsa_keys[0].clone_key();
|
||||||
|
Some(PrivateKeyDer::from(key))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -100,18 +100,19 @@ pub fn get_tls_config(
|
||||||
match key {
|
match key {
|
||||||
Some(key) => {
|
Some(key) => {
|
||||||
let mut root_cert_store = rustls::RootCertStore::empty();
|
let mut root_cert_store = rustls::RootCertStore::empty();
|
||||||
root_cert_store.add(&rustls::Certificate(ca_cert)).unwrap();
|
root_cert_store.add(ca_cert).unwrap();
|
||||||
|
|
||||||
// Allow (but do not require) client authentication.
|
// Allow (but do not require) client authentication.
|
||||||
|
let client_verifier = rustls::server::WebPkiClientVerifier::builder(
|
||||||
|
Arc::new(root_cert_store),
|
||||||
|
)
|
||||||
|
.allow_unauthenticated()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut config = rustls::ServerConfig::builder()
|
let mut config = rustls::ServerConfig::builder()
|
||||||
.with_safe_defaults()
|
.with_client_cert_verifier(client_verifier)
|
||||||
.with_client_cert_verifier(Arc::new(
|
.with_single_cert(certs, key)
|
||||||
rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(
|
|
||||||
root_cert_store,
|
|
||||||
),
|
|
||||||
))
|
|
||||||
.with_single_cert(certs, PrivateKey(key))
|
|
||||||
.map_err(|e| anyhow!("Error setting cert: {:?}", e))
|
.map_err(|e| anyhow!("Error setting cert: {:?}", e))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue