From 8ff00783cba1cd0c61be49b3a73d5f0ad749c6b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= <biwanczuk@gmail.com>
Date: Tue, 2 Jul 2024 01:09:47 +0100
Subject: [PATCH] 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.
---
 Cargo.lock                                    | 167 +++++++++------
 Cargo.toml                                    |  23 +-
 cli/args/mod.rs                               |  18 +-
 cli/http_util.rs                              |   2 +-
 ext/fetch/Cargo.toml                          |   2 +-
 ext/fetch/fs_fetch_handler.rs                 |   2 +-
 ext/fetch/lib.rs                              |  13 +-
 ext/kv/Cargo.toml                             |   2 +
 ext/kv/remote.rs                              |  44 +++-
 ext/net/ops_tls.rs                            |  28 +--
 ext/node/Cargo.toml                           |   4 +-
 ext/node/ops/http2.rs                         |  14 +-
 ext/tls/Cargo.toml                            |   4 +-
 ext/tls/lib.rs                                | 201 ++++++++++--------
 ext/tls/testdata/README                       |   4 +
 ext/tls/testdata/example1_cert.der            | Bin 0 -> 929 bytes
 ext/tls/testdata/example1_prikey.der          | Bin 0 -> 1190 bytes
 ext/tls/testdata/example2_cert.der            | Bin 0 -> 929 bytes
 ext/tls/testdata/example2_prikey.der          | Bin 0 -> 1191 bytes
 ext/tls/tls_key.rs                            |  46 ++--
 ext/websocket/lib.rs                          |  11 +-
 tests/integration/run_tests.rs                |  19 +-
 tests/node_compat/config.jsonc                |   6 -
 tests/node_compat/runner/TODO.md              |   6 +
 ...p-url.parse-auth-with-header-in-request.js |  59 -----
 .../test/parallel/test-http-url.parse-auth.js |  55 -----
 .../parallel/test-http-url.parse-basic.js     |  65 ------
 .../test/parallel/test-http-url.parse-path.js |  53 -----
 .../test/parallel/test-http-url.parse-post.js |  61 ------
 .../parallel/test-http-url.parse-search.js    |  54 -----
 .../localhost_unsafe_ssl.ts.out               |   2 +-
 tests/unit/fetch_test.ts                      |   8 +-
 tests/unit/http_test.ts                       |   4 +-
 tests/unit/serve_test.ts                      |  12 +-
 tests/util/server/src/https.rs                |  53 ++---
 35 files changed, 391 insertions(+), 651 deletions(-)
 create mode 100644 ext/tls/testdata/README
 create mode 100644 ext/tls/testdata/example1_cert.der
 create mode 100644 ext/tls/testdata/example1_prikey.der
 create mode 100644 ext/tls/testdata/example2_cert.der
 create mode 100644 ext/tls/testdata/example2_prikey.der
 delete mode 100644 tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js
 delete mode 100644 tests/node_compat/test/parallel/test-http-url.parse-auth.js
 delete mode 100644 tests/node_compat/test/parallel/test-http-url.parse-basic.js
 delete mode 100644 tests/node_compat/test/parallel/test-http-url.parse-path.js
 delete mode 100644 tests/node_compat/test/parallel/test-http-url.parse-post.js
 delete mode 100644 tests/node_compat/test/parallel/test-http-url.parse-search.js

diff --git a/Cargo.lock b/Cargo.lock
index 5aea422a35a888..7afafcb95dc4f4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -736,7 +736,7 @@ dependencies = [
  "flaky_test",
  "http 1.1.0",
  "http-body-util",
- "hyper 1.1.0",
+ "hyper 1.4.0",
  "hyper-util",
  "nix 0.26.2",
  "once_cell",
@@ -1467,7 +1467,7 @@ dependencies = [
  "deno_permissions",
  "deno_tls",
  "dyn-clone",
- "http 0.2.12",
+ "http 1.1.0",
  "reqwest",
  "serde",
  "serde_json",
@@ -1561,7 +1561,7 @@ dependencies = [
  "http-body-util",
  "httparse",
  "hyper 0.14.28",
- "hyper 1.1.0",
+ "hyper 1.4.0",
  "hyper-util",
  "itertools",
  "memmem",
@@ -1604,6 +1604,7 @@ dependencies = [
  "anyhow",
  "async-trait",
  "base64 0.21.7",
+ "bytes",
  "chrono",
  "deno_core",
  "deno_fetch",
@@ -1614,6 +1615,7 @@ dependencies = [
  "denokv_remote",
  "denokv_sqlite",
  "faster-hex",
+ "http 1.1.0",
  "log",
  "num-bigint",
  "prost",
@@ -1674,9 +1676,9 @@ dependencies = [
 
 [[package]]
 name = "deno_native_certs"
-version = "0.2.0"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4785d0bdc13819b665b71e4fb7e119d859568471e4c245ec5610857e70c9345"
+checksum = "c867603d2a5dfea31f55cecebb572554caa395437786d058faa9a2814c8d6eb9"
 dependencies = [
  "dlopen2",
  "dlopen2_derive",
@@ -1729,10 +1731,10 @@ dependencies = [
  "elliptic-curve",
  "errno 0.2.8",
  "faster-hex",
- "h2 0.3.26",
+ "h2 0.4.4",
  "hkdf",
  "home",
- "http 0.2.12",
+ "http 1.1.0",
  "idna 0.3.0",
  "indexmap",
  "ipnetwork",
@@ -1863,7 +1865,7 @@ dependencies = [
  "http 1.1.0",
  "http-body-util",
  "hyper 0.14.28",
- "hyper 1.1.0",
+ "hyper 1.4.0",
  "hyper-util",
  "libc",
  "log",
@@ -2017,7 +2019,7 @@ dependencies = [
  "h2 0.4.4",
  "http 1.1.0",
  "http-body-util",
- "hyper 1.1.0",
+ "hyper 1.4.0",
  "hyper-util",
  "once_cell",
  "rustls-tokio-stream",
@@ -2046,9 +2048,9 @@ dependencies = [
 
 [[package]]
 name = "denokv_proto"
-version = "0.7.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd644ad038e7b6e8453463e96c278ba378e8bdc9f557959d511ac830ea0ec969"
+checksum = "114538d2cacd2b219f05faa753d80950f95416e47c77904c7452d5f41e157059"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -2056,16 +2058,15 @@ dependencies = [
  "futures",
  "num-bigint",
  "prost",
- "prost-build",
  "serde",
  "uuid",
 ]
 
 [[package]]
 name = "denokv_remote"
-version = "0.7.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23cfa4786f9c609711aab89ce173232ceda0617167881e58fd5e0b78868a6932"
+checksum = "d57717b5123e8d1ec5f52973a67f98e3621274d362d18b245038967b402082df"
 dependencies = [
  "anyhow",
  "async-stream",
@@ -2074,10 +2075,10 @@ dependencies = [
  "chrono",
  "denokv_proto",
  "futures",
+ "http 1.1.0",
  "log",
  "prost",
  "rand",
- "reqwest",
  "serde",
  "serde_json",
  "tokio",
@@ -2088,9 +2089,9 @@ dependencies = [
 
 [[package]]
 name = "denokv_sqlite"
-version = "0.7.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f36c1c54cda2de93d0f4ded0392d0b6917bcd9b1d13c056dd7c309668aa43e17"
+checksum = "188b792af19082cbfc7b666e71979775300482877d8b80601f4a5a86a80098a3"
 dependencies = [
  "anyhow",
  "async-stream",
@@ -2659,7 +2660,7 @@ checksum = "f63dd7b57f9b33b1741fa631c9522eb35d43e96dcca4a6a91d5e4ca7c93acdc1"
 dependencies = [
  "base64 0.21.7",
  "http-body-util",
- "hyper 1.1.0",
+ "hyper 1.4.0",
  "hyper-util",
  "pin-project",
  "rand",
@@ -3409,9 +3410,9 @@ dependencies = [
 
 [[package]]
 name = "hyper"
-version = "1.1.0"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75"
+checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -3423,39 +3424,45 @@ dependencies = [
  "httpdate",
  "itoa",
  "pin-project-lite",
+ "smallvec",
  "tokio",
  "want",
 ]
 
 [[package]]
 name = "hyper-rustls"
-version = "0.24.2"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
+checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
 dependencies = [
  "futures-util",
- "http 0.2.12",
- "hyper 0.14.28",
+ "http 1.1.0",
+ "hyper 1.4.0",
+ "hyper-util",
  "rustls",
+ "rustls-pki-types",
  "tokio",
  "tokio-rustls",
+ "tower-service",
 ]
 
 [[package]]
 name = "hyper-util"
-version = "0.1.2"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67"
+checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956"
 dependencies = [
  "bytes",
  "futures-channel",
  "futures-util",
  "http 1.1.0",
  "http-body 1.0.0",
- "hyper 1.1.0",
+ "hyper 1.4.0",
  "pin-project-lite",
  "socket2",
  "tokio",
+ "tower",
+ "tower-service",
  "tracing",
 ]
 
@@ -3594,7 +3601,7 @@ dependencies = [
  "socket2",
  "widestring",
  "windows-sys 0.48.0",
- "winreg",
+ "winreg 0.50.0",
 ]
 
 [[package]]
@@ -5304,21 +5311,22 @@ checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc"
 
 [[package]]
 name = "reqwest"
-version = "0.11.20"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
+checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
 dependencies = [
  "async-compression",
- "base64 0.21.7",
+ "base64 0.22.1",
  "bytes",
- "encoding_rs",
  "futures-core",
  "futures-util",
- "h2 0.3.26",
- "http 0.2.12",
- "http-body 0.4.6",
- "hyper 0.14.28",
+ "h2 0.4.4",
+ "http 1.1.0",
+ "http-body 1.0.0",
+ "http-body-util",
+ "hyper 1.4.0",
  "hyper-rustls",
+ "hyper-util",
  "ipnet",
  "js-sys",
  "log",
@@ -5328,9 +5336,11 @@ dependencies = [
  "pin-project-lite",
  "rustls",
  "rustls-pemfile",
+ "rustls-pki-types",
  "serde",
  "serde_json",
  "serde_urlencoded",
+ "sync_wrapper",
  "tokio",
  "tokio-rustls",
  "tokio-socks",
@@ -5342,7 +5352,7 @@ dependencies = [
  "wasm-streams",
  "web-sys",
  "webpki-roots",
- "winreg",
+ "winreg 0.52.0",
 ]
 
 [[package]]
@@ -5512,42 +5522,52 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.21.11"
+version = "0.22.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
+checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
 dependencies = [
  "log",
  "ring",
+ "rustls-pki-types",
  "rustls-webpki",
- "sct",
+ "subtle",
+ "zeroize",
 ]
 
 [[package]]
 name = "rustls-native-certs"
-version = "0.6.3"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
+checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
 dependencies = [
  "openssl-probe",
  "rustls-pemfile",
+ "rustls-pki-types",
  "schannel",
  "security-framework",
 ]
 
 [[package]]
 name = "rustls-pemfile"
-version = "1.0.4"
+version = "2.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
 dependencies = [
- "base64 0.21.7",
+ "base64 0.22.1",
+ "rustls-pki-types",
 ]
 
+[[package]]
+name = "rustls-pki-types"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
+
 [[package]]
 name = "rustls-tokio-stream"
-version = "0.2.24"
+version = "0.2.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd707225bb670bcd2876886bb571753d1ce03a9cedfa2e629a79984ca9a93cfb"
+checksum = "c478c030dfd68498e6c59168d9eec4f8bead33152a5f3095ad4bdbdcea09d466"
 dependencies = [
  "futures",
  "rustls",
@@ -5557,11 +5577,12 @@ dependencies = [
 
 [[package]]
 name = "rustls-webpki"
-version = "0.101.7"
+version = "0.102.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
+checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
 dependencies = [
  "ring",
+ "rustls-pki-types",
  "untrusted",
 ]
 
@@ -5677,16 +5698,6 @@ dependencies = [
  "sha2",
 ]
 
-[[package]]
-name = "sct"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
-dependencies = [
- "ring",
- "untrusted",
-]
-
 [[package]]
 name = "sec1"
 version = "0.7.3"
@@ -6655,6 +6666,12 @@ dependencies = [
  "unicode-ident",
 ]
 
+[[package]]
+name = "sync_wrapper"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
+
 [[package]]
 name = "synstructure"
 version = "0.12.6"
@@ -6771,7 +6788,7 @@ dependencies = [
  "h2 0.4.4",
  "http 1.1.0",
  "http-body-util",
- "hyper 1.1.0",
+ "hyper 1.4.0",
  "hyper-util",
  "jsonc-parser",
  "lazy-regex",
@@ -6937,11 +6954,12 @@ dependencies = [
 
 [[package]]
 name = "tokio-rustls"
-version = "0.24.1"
+version = "0.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
+checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
 dependencies = [
  "rustls",
+ "rustls-pki-types",
  "tokio",
 ]
 
@@ -6978,7 +6996,10 @@ dependencies = [
  "futures-core",
  "futures-io",
  "futures-sink",
+ "futures-util",
+ "hashbrown",
  "pin-project-lite",
+ "slab",
  "tokio",
  "tracing",
 ]
@@ -7036,6 +7057,7 @@ dependencies = [
  "futures-util",
  "pin-project",
  "pin-project-lite",
+ "tokio",
  "tower-layer",
  "tower-service",
 ]
@@ -7611,9 +7633,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
 
 [[package]]
 name = "wasm-streams"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7"
+checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
 dependencies = [
  "futures-util",
  "js-sys",
@@ -7634,9 +7656,12 @@ dependencies = [
 
 [[package]]
 name = "webpki-roots"
-version = "0.25.4"
+version = "0.26.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
+checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
+dependencies = [
+ "rustls-pki-types",
+]
 
 [[package]]
 name = "wgpu-core"
@@ -7973,6 +7998,16 @@ dependencies = [
  "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]]
 name = "winres"
 version = "0.1.12"
diff --git a/Cargo.toml b/Cargo.toml
index 293d6b440c9863..dc4fa13027f016 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -55,10 +55,10 @@ deno_terminal = "0.1.1"
 napi_sym = { version = "0.88.0", path = "./cli/napi/sym" }
 test_util = { package = "test_server", path = "./tests/util/server" }
 
-denokv_proto = "0.7.0"
-denokv_remote = "0.7.0"
+denokv_proto = "0.8.1"
+denokv_remote = "0.8.1"
 # 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
 deno_broadcast_channel = { version = "0.152.0", path = "./ext/broadcast_channel" }
@@ -118,8 +118,8 @@ http = "1.0"
 http-body-util = "0.1"
 http_v02 = { package = "http", version = "0.2.9" }
 httparse = "1.8.0"
-hyper = { version = "=1.1.0", features = ["full"] }
-hyper-util = { version = "=0.1.2", features = ["tokio", "server", "server-auto"] }
+hyper = { version = "=1.4.0", features = ["full"] }
+hyper-util = { version = "=0.1.6", features = ["tokio", "server", "server-auto"] }
 hyper_v014 = { package = "hyper", version = "0.14.26", features = ["runtime", "http1"] }
 indexmap = { version = "2", features = ["serde"] }
 jsonc-parser = { version = "=0.23.0", features = ["serde"] }
@@ -146,14 +146,13 @@ prost = "0.11"
 prost-build = "0.11"
 rand = "=0.8.5"
 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"
 rusqlite = { version = "=0.29.0", features = ["unlock_notify", "bundled"] }
-# pinned because it was causing issues on cargo publish
-rustls = "=0.21.11"
-rustls-pemfile = "1.0.0"
-rustls-tokio-stream = "=0.2.24"
-rustls-webpki = "0.101.4"
+rustls = "0.22.4"
+rustls-pemfile = "2"
+rustls-tokio-stream = "=0.2.23"
+rustls-webpki = "0.102"
 rustyline = "=13.0.0"
 saffron = "=0.1.0"
 scopeguard = "1.2.0"
@@ -180,7 +179,7 @@ twox-hash = "=1.6.3"
 # Upgrading past 2.4.1 may cause WPT failures
 url = { version = "< 2.5.0", features = ["serde", "expose_internals"] }
 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"] }
 zstd = "=0.12.4"
 
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index 187304d5d5c099..e1e6f9510fe135 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -705,21 +705,13 @@ pub fn get_root_cert_store(
   for store in ca_stores.iter() {
     match store.as_str() {
       "mozilla" => {
-        root_cert_store.add_trust_anchors(
-          webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
-            rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
-              ta.subject,
-              ta.spki,
-              ta.name_constraints,
-            )
-          }),
-        );
+        root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.to_vec());
       }
       "system" => {
         let roots = load_native_certs().expect("could not load platform certs");
         for root in roots {
           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");
         }
       }
@@ -743,17 +735,17 @@ pub fn get_root_cert_store(
           RootCertStoreLoadError::CaFileOpenError(err.to_string())
         })?;
         let mut reader = BufReader::new(certfile);
-        rustls_pemfile::certs(&mut reader)
+        rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>()
       }
       CaData::Bytes(data) => {
         let mut reader = BufReader::new(Cursor::new(data));
-        rustls_pemfile::certs(&mut reader)
+        rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>()
       }
     };
 
     match result {
       Ok(certs) => {
-        root_cert_store.add_parsable_certificates(&certs);
+        root_cert_store.add_parsable_certificates(certs);
       }
       Err(e) => {
         return Err(RootCertStoreLoadError::FailedAddPemFile(e.to_string()));
diff --git a/cli/http_util.rs b/cli/http_util.rs
index 7fcce616b4d438..18c0687bdb746e 100644
--- a/cli/http_util.rs
+++ b/cli/http_util.rs
@@ -587,7 +587,7 @@ mod test {
   use std::collections::HashSet;
   use std::hash::RandomState;
 
-  use deno_runtime::deno_tls::RootCertStore;
+  use deno_runtime::deno_tls::rustls::RootCertStore;
 
   use crate::version;
 
diff --git a/ext/fetch/Cargo.toml b/ext/fetch/Cargo.toml
index 20b6e9bc3b1913..7a60a6c6410b5d 100644
--- a/ext/fetch/Cargo.toml
+++ b/ext/fetch/Cargo.toml
@@ -20,7 +20,7 @@ deno_core.workspace = true
 deno_permissions.workspace = true
 deno_tls.workspace = true
 dyn-clone = "1"
-http_v02.workspace = true
+http.workspace = true
 reqwest.workspace = true
 serde.workspace = true
 serde_json.workspace = true
diff --git a/ext/fetch/fs_fetch_handler.rs b/ext/fetch/fs_fetch_handler.rs
index 8f83cef882d5b7..29bad5992b6663 100644
--- a/ext/fetch/fs_fetch_handler.rs
+++ b/ext/fetch/fs_fetch_handler.rs
@@ -31,7 +31,7 @@ impl FetchHandler for FsFetchHandler {
       let file = tokio::fs::File::open(path).map_err(|_| ()).await?;
       let stream = ReaderStream::new(file);
       let body = reqwest::Body::wrap_stream(stream);
-      let response = http_v02::Response::builder()
+      let response = http::Response::builder()
         .status(StatusCode::OK)
         .body(body)
         .map_err(|_| ())?
diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs
index 066f1685b04d50..75ceb86d996626 100644
--- a/ext/fetch/lib.rs
+++ b/ext/fetch/lib.rs
@@ -47,8 +47,8 @@ use data_url::DataUrl;
 use deno_tls::TlsKey;
 use deno_tls::TlsKeys;
 use deno_tls::TlsKeysHolder;
-use http_v02::header::CONTENT_LENGTH;
-use http_v02::Uri;
+use http::header::CONTENT_LENGTH;
+use http::Uri;
 use reqwest::header::HeaderMap;
 use reqwest::header::HeaderName;
 use reqwest::header::HeaderValue;
@@ -449,12 +449,9 @@ where
         .decode_to_vec()
         .map_err(|e| type_error(format!("{e:?}")))?;
 
-      let response = http_v02::Response::builder()
-        .status(http_v02::StatusCode::OK)
-        .header(
-          http_v02::header::CONTENT_TYPE,
-          data_url.mime_type().to_string(),
-        )
+      let response = http::Response::builder()
+        .status(http::StatusCode::OK)
+        .header(http::header::CONTENT_TYPE, data_url.mime_type().to_string())
         .body(reqwest::Body::from(body))?;
 
       let fut = async move { Ok(Ok(Response::from(response))) };
diff --git a/ext/kv/Cargo.toml b/ext/kv/Cargo.toml
index 46c4a4ac4c7e57..4bb5d20eb0484f 100644
--- a/ext/kv/Cargo.toml
+++ b/ext/kv/Cargo.toml
@@ -17,6 +17,7 @@ path = "lib.rs"
 anyhow.workspace = true
 async-trait.workspace = true
 base64.workspace = true
+bytes.workspace = true
 chrono = { workspace = true, features = ["now"] }
 deno_core.workspace = true
 deno_fetch.workspace = true
@@ -27,6 +28,7 @@ denokv_proto.workspace = true
 denokv_remote.workspace = true
 denokv_sqlite.workspace = true
 faster-hex.workspace = true
+http.workspace = true
 log.workspace = true
 num-bigint.workspace = true
 prost.workspace = true
diff --git a/ext/kv/remote.rs b/ext/kv/remote.rs
index a1273e78b8db91..7541b5a06a8fa0 100644
--- a/ext/kv/remote.rs
+++ b/ext/kv/remote.rs
@@ -8,10 +8,14 @@ use std::sync::Arc;
 use crate::DatabaseHandler;
 use anyhow::Context;
 use async_trait::async_trait;
+use bytes::Bytes;
 use deno_core::error::type_error;
 use deno_core::error::AnyError;
+use deno_core::futures::Stream;
+use deno_core::futures::TryStreamExt as _;
 use deno_core::OpState;
 use deno_fetch::create_http_client;
+use deno_fetch::reqwest;
 use deno_fetch::CreateHttpClientOptions;
 use deno_tls::rustls::RootCertStore;
 use deno_tls::Proxy;
@@ -19,6 +23,8 @@ use deno_tls::RootCertStoreProvider;
 use deno_tls::TlsKeys;
 use denokv_remote::MetadataEndpoint;
 use denokv_remote::Remote;
+use denokv_remote::RemoteResponse;
+use denokv_remote::RemoteTransport;
 use url::Url;
 
 #[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)]
 impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
   for RemoteDbHandler<P>
 {
-  type DB = Remote<PermissionChecker<P>>;
+  type DB = Remote<PermissionChecker<P>, ReqwestClient>;
 
   async fn open(
     &self,
@@ -162,13 +201,14 @@ impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
         http2: true,
       },
     )?;
+    let reqwest_client = ReqwestClient(client);
 
     let permissions = PermissionChecker {
       state: state.clone(),
       _permissions: PhantomData,
     };
 
-    let remote = Remote::new(client, permissions, metadata_endpoint);
+    let remote = Remote::new(reqwest_client, permissions, metadata_endpoint);
 
     Ok(remote)
   }
diff --git a/ext/net/ops_tls.rs b/ext/net/ops_tls.rs
index adfa8224c262cd..a2a27c4adf1a88 100644
--- a/ext/net/ops_tls.rs
+++ b/ext/net/ops_tls.rs
@@ -31,11 +31,11 @@ use deno_tls::create_client_config;
 use deno_tls::load_certs;
 use deno_tls::load_private_keys;
 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::PrivateKey;
 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::SocketUse;
 use deno_tls::TlsKey;
@@ -48,7 +48,6 @@ use serde::Deserialize;
 use std::borrow::Cow;
 use std::cell::RefCell;
 use std::convert::From;
-use std::convert::TryFrom;
 use std::fs::File;
 use std::io::BufReader;
 use std::io::ErrorKind;
@@ -294,14 +293,14 @@ where
 {
   let rid = args.rid;
   let hostname = match &*args.hostname {
-    "" => "localhost",
-    n => n,
+    "" => "localhost".to_string(),
+    n => n.to_string(),
   };
 
   {
     let mut s = state.borrow_mut();
     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
@@ -310,8 +309,8 @@ where
     .map(|s| s.into_bytes())
     .collect::<Vec<_>>();
 
-  let hostname_dns =
-    ServerName::try_from(hostname).map_err(|_| invalid_hostname(hostname))?;
+  let hostname_dns = ServerName::try_from(hostname.to_string())
+    .map_err(|_| invalid_hostname(&hostname))?;
 
   let unsafely_ignore_certificate_errors = state
     .borrow()
@@ -412,9 +411,9 @@ where
     .borrow::<DefaultTlsOptions>()
     .root_cert_store()?;
   let hostname_dns = if let Some(server_name) = args.server_name {
-    ServerName::try_from(server_name.as_str())
+    ServerName::try_from(server_name)
   } else {
-    ServerName::try_from(&*addr.hostname)
+    ServerName::try_from(addr.hostname.clone())
   }
   .map_err(|_| invalid_hostname(&addr.hostname))?;
   let connect_addr = resolve_addr(&addr.hostname, addr.port)
@@ -456,7 +455,9 @@ where
   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 reader = &mut BufReader::new(cert_file);
   load_certs(reader)
@@ -464,7 +465,7 @@ fn load_certs_from_file(path: &str) -> Result<Vec<Certificate>, AnyError> {
 
 fn load_private_keys_from_file(
   path: &str,
-) -> Result<Vec<PrivateKey>, AnyError> {
+) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
   let key_bytes = std::fs::read(path)?;
   load_private_keys(&key_bytes)
 }
@@ -513,7 +514,6 @@ where
     TlsKeys::Null => Err(anyhow!("Deno.listenTls requires a key")),
     TlsKeys::Static(TlsKey(cert, key)) => {
       let mut tls_config = ServerConfig::builder()
-        .with_safe_defaults()
         .with_no_client_auth()
         .with_single_cert(cert, key)
         .map_err(|e| anyhow!(e))?;
diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml
index 425364792440c5..b1d40756bd8bba 100644
--- a/ext/node/Cargo.toml
+++ b/ext/node/Cargo.toml
@@ -38,10 +38,10 @@ ecb.workspace = true
 elliptic-curve.workspace = true
 errno = "0.2.8"
 faster-hex.workspace = true
-h2 = { version = "0.3.26", features = ["unstable"] }
+h2.workspace = true
 hkdf.workspace = true
 home = "0.5.9"
-http_v02.workspace = true
+http.workspace = true
 idna = "0.3.0"
 indexmap.workspace = true
 ipnetwork = "0.20.0"
diff --git a/ext/node/ops/http2.rs b/ext/node/ops/http2.rs
index abf7eae5d885b6..d12e108e669f73 100644
--- a/ext/node/ops/http2.rs
+++ b/ext/node/ops/http2.rs
@@ -26,11 +26,11 @@ use deno_net::raw::NetworkStream;
 use h2;
 use h2::Reason;
 use h2::RecvStream;
-use http_v02;
-use http_v02::request::Parts;
-use http_v02::HeaderMap;
-use http_v02::Response;
-use http_v02::StatusCode;
+use http;
+use http::request::Parts;
+use http::HeaderMap;
+use http::Response;
+use http::StatusCode;
 use reqwest::header::HeaderName;
 use reqwest::header::HeaderValue;
 use url::Url;
@@ -311,7 +311,7 @@ pub async fn op_http2_client_request(
 
   let url = url.join(&pseudo_path)?;
 
-  let mut req = http_v02::Request::builder()
+  let mut req = http::Request::builder()
     .uri(url.as_str())
     .method(pseudo_method.as_str());
 
@@ -383,7 +383,7 @@ pub async fn op_http2_client_send_trailers(
     .get::<Http2ClientStream>(stream_rid)?;
   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 {
     trailers_map.insert(
       HeaderName::from_bytes(&name).unwrap(),
diff --git a/ext/tls/Cargo.toml b/ext/tls/Cargo.toml
index 579f90ce2105de..0eddee5eaef62b 100644
--- a/ext/tls/Cargo.toml
+++ b/ext/tls/Cargo.toml
@@ -15,8 +15,8 @@ path = "lib.rs"
 
 [dependencies]
 deno_core.workspace = true
-deno_native_certs = "0.2.0"
-rustls = { workspace = true, features = ["dangerous_configuration"] }
+deno_native_certs = "0.3.0"
+rustls.workspace = true
 rustls-pemfile.workspace = true
 rustls-tokio-stream.workspace = true
 rustls-webpki.workspace = true
diff --git a/ext/tls/lib.rs b/ext/tls/lib.rs
index 5122264bf179ec..c4d548ccf21dd8 100644
--- a/ext/tls/lib.rs
+++ b/ext/tls/lib.rs
@@ -1,7 +1,9 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-
 pub use deno_native_certs;
 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_tokio_stream::*;
 pub use webpki;
@@ -11,14 +13,14 @@ use deno_core::anyhow::anyhow;
 use deno_core::error::custom_error;
 use deno_core::error::AnyError;
 
-use rustls::client::HandshakeSignatureValid;
-use rustls::client::ServerCertVerified;
-use rustls::client::ServerCertVerifier;
-use rustls::client::WebPkiVerifier;
+use rustls::client::danger::HandshakeSignatureValid;
+use rustls::client::danger::ServerCertVerified;
+use rustls::client::danger::ServerCertVerifier;
+use rustls::client::WebPkiServerVerifier;
 use rustls::ClientConfig;
 use rustls::DigitallySignedStruct;
 use rustls::Error;
-use rustls::ServerName;
+use rustls::RootCertStore;
 use rustls_pemfile::certs;
 use rustls_pemfile::ec_private_keys;
 use rustls_pemfile::pkcs8_private_keys;
@@ -27,16 +29,12 @@ use serde::Deserialize;
 use std::io::BufRead;
 use std::io::BufReader;
 use std::io::Cursor;
+use std::net::IpAddr;
 use std::sync::Arc;
-use std::time::SystemTime;
 
 mod 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.
 ///
 /// 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.
 deno_core::extension!(deno_tls);
 
-struct DefaultSignatureVerification;
+#[derive(Debug)]
+pub struct NoCertificateVerification {
+  pub ic_allowlist: Vec<String>,
+  default_verifier: Arc<WebPkiServerVerifier>,
+}
 
-impl ServerCertVerifier for DefaultSignatureVerification {
-  fn verify_server_cert(
-    &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()))
+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(),
+    }
   }
 }
 
-pub struct NoCertificateVerification(pub Vec<String>);
-
 impl ServerCertVerifier for NoCertificateVerification {
+  fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
+    self.default_verifier.supported_verify_schemes()
+  }
+
   fn verify_server_cert(
     &self,
-    end_entity: &Certificate,
-    intermediates: &[Certificate],
-    server_name: &ServerName,
-    scts: &mut dyn Iterator<Item = &[u8]>,
+    end_entity: &rustls::pki_types::CertificateDer<'_>,
+    intermediates: &[rustls::pki_types::CertificateDer<'_>],
+    server_name: &rustls::pki_types::ServerName<'_>,
     ocsp_response: &[u8],
-    now: SystemTime,
+    now: rustls::pki_types::UnixTime,
   ) -> Result<ServerCertVerified, Error> {
-    if self.0.is_empty() {
+    if self.ic_allowlist.is_empty() {
       return Ok(ServerCertVerified::assertion());
     }
     let dns_name_or_ip_address = match server_name {
       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
         // so we have this catch all errors here.
         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())
     } else {
-      let root_store = create_default_root_cert_store();
-      let verifier = WebPkiVerifier::new(root_store, None);
-      verifier.verify_server_cert(
+      self.default_verifier.verify_server_cert(
         end_entity,
         intermediates,
         server_name,
-        scts,
         ocsp_response,
         now,
       )
@@ -107,28 +108,32 @@ impl ServerCertVerifier for NoCertificateVerification {
   fn verify_tls12_signature(
     &self,
     message: &[u8],
-    cert: &rustls::Certificate,
+    cert: &rustls::pki_types::CertificateDer,
     dss: &DigitallySignedStruct,
   ) -> Result<HandshakeSignatureValid, Error> {
-    if self.0.is_empty() {
+    if self.ic_allowlist.is_empty() {
       return Ok(HandshakeSignatureValid::assertion());
     }
     filter_invalid_encoding_err(
-      DefaultSignatureVerification.verify_tls12_signature(message, cert, dss),
+      self
+        .default_verifier
+        .verify_tls12_signature(message, cert, dss),
     )
   }
 
   fn verify_tls13_signature(
     &self,
     message: &[u8],
-    cert: &rustls::Certificate,
+    cert: &rustls::pki_types::CertificateDer,
     dss: &DigitallySignedStruct,
   ) -> Result<HandshakeSignatureValid, Error> {
-    if self.0.is_empty() {
+    if self.ic_allowlist.is_empty() {
       return Ok(HandshakeSignatureValid::assertion());
     }
     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 {
-  let mut root_cert_store = RootCertStore::empty();
-  // TODO(@justinmchase): Consider also loading the system keychain here
-  root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(
-    |ta| {
-      rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
-        ta.subject,
-        ta.spki,
-        ta.name_constraints,
-      )
-    },
-  ));
+  let root_cert_store = rustls::RootCertStore {
+    roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(),
+  };
+  debug_assert!(!root_cert_store.is_empty());
   root_cert_store
 }
 
@@ -183,10 +181,10 @@ pub fn create_client_config(
 ) -> Result<ClientConfig, AnyError> {
   if let Some(ic_allowlist) = unsafely_ignore_certificate_errors {
     let client_config = ClientConfig::builder()
-      .with_safe_defaults()
-      .with_custom_certificate_verifier(Arc::new(NoCertificateVerification(
-        ic_allowlist,
-      )));
+      .dangerous()
+      .with_custom_certificate_verifier(Arc::new(
+        NoCertificateVerification::new(ic_allowlist),
+      ));
 
     // 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
@@ -194,7 +192,7 @@ pub fn create_client_config(
     // or client cert".
     let mut client = match maybe_cert_chain_and_key {
       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"),
       TlsKeys::Null => client_config.with_no_client_auth(),
       TlsKeys::Resolver(_) => unimplemented!(),
@@ -204,33 +202,33 @@ pub fn create_client_config(
     return Ok(client);
   }
 
-  let client_config = ClientConfig::builder()
-    .with_safe_defaults()
-    .with_root_certificates({
-      let mut root_cert_store =
-        root_cert_store.unwrap_or_else(create_default_root_cert_store);
-      // If custom certs are specified, add them to the store
-      for cert in ca_certs {
-        let reader = &mut BufReader::new(Cursor::new(cert));
-        // This function does not return specific errors, if it fails give a generic message.
-        match rustls_pemfile::certs(reader) {
-          Ok(certs) => {
-            root_cert_store.add_parsable_certificates(&certs);
-          }
-          Err(e) => {
-            return Err(anyhow!(
-              "Unable to add pem file to certificate store: {}",
-              e
-            ));
-          }
+  let mut root_cert_store =
+    root_cert_store.unwrap_or_else(create_default_root_cert_store);
+  // If custom certs are specified, add them to the store
+  for cert in ca_certs {
+    let reader = &mut BufReader::new(Cursor::new(cert));
+    // This function does not return specific errors, if it fails give a generic message.
+    for r in rustls_pemfile::certs(reader) {
+      match r {
+        Ok(cert) => {
+          root_cert_store.add(cert)?;
+        }
+        Err(e) => {
+          return Err(anyhow!(
+            "Unable to add pem file to certificate store: {}",
+            e
+          ));
         }
       }
-      root_cert_store
-    });
+    }
+  }
+
+  let client_config =
+    ClientConfig::builder().with_root_certificates(root_cert_store);
 
   let mut client = match maybe_cert_chain_and_key {
     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"),
     TlsKeys::Null => client_config.with_no_client_auth(),
     TlsKeys::Resolver(_) => unimplemented!(),
@@ -257,15 +255,17 @@ fn add_alpn(client: &mut ClientConfig, socket_use: SocketUse) {
 
 pub fn load_certs(
   reader: &mut dyn BufRead,
-) -> Result<Vec<Certificate>, AnyError> {
-  let certs = certs(reader)
+) -> Result<Vec<CertificateDer<'static>>, AnyError> {
+  let certs: Result<Vec<_>, _> = certs(reader).collect();
+
+  let certs = certs
     .map_err(|_| custom_error("InvalidData", "Unable to decode certificate"))?;
 
   if certs.is_empty() {
     return Err(cert_not_found_err());
   }
 
-  Ok(certs.into_iter().map(rustls::Certificate).collect())
+  Ok(certs)
 }
 
 fn key_decode_err() -> AnyError {
@@ -281,21 +281,32 @@ fn cert_not_found_err() -> AnyError {
 }
 
 /// Starts with -----BEGIN RSA PRIVATE KEY-----
-fn load_rsa_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
-  let keys = rsa_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
-  Ok(keys.into_iter().map(rustls::PrivateKey).collect())
+fn load_rsa_keys(
+  mut bytes: &[u8],
+) -> 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-----
-fn load_ec_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
-  let keys = ec_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
-  Ok(keys.into_iter().map(rustls::PrivateKey).collect())
+fn load_ec_keys(
+  mut bytes: &[u8],
+) -> 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-----
-fn load_pkcs8_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
-  let keys = pkcs8_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
-  Ok(keys.into_iter().map(rustls::PrivateKey).collect())
+fn load_pkcs8_keys(
+  mut bytes: &[u8],
+) -> 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(
@@ -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)?;
 
   if keys.is_empty() {
diff --git a/ext/tls/testdata/README b/ext/tls/testdata/README
new file mode 100644
index 00000000000000..12046561c244e7
--- /dev/null
+++ b/ext/tls/testdata/README
@@ -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
diff --git a/ext/tls/testdata/example1_cert.der b/ext/tls/testdata/example1_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..fb1b2e64b2510fb1028bd4ecaeaebb29e3ac0ad8
GIT binary patch
literal 929
zcmXqLVxDWz#MHWgnTe5!NyM|i;{MjIT`H#6f4+I0cUj@=*ZGePc-c6$+C196^D;7W
zvoaXO8FCwNvN4CUun9AT1{?Aj@PIfRJgmVbi6yCqf(HB`K06PGPkwS@PG(7^p{Ri{
zNQjGv$G<2&F)y<!u_QA;4<^ja!;@N(m|KvOYN(f-pKBl|&TC|1U}j)qXlP_;ViE=B
zn!~v?x4(%|3E9hxtPIRejQk7+O^jSjO^l2T+gkn1cvl_OsZ{k0m0n}0sN#P%dG1}!
zWKG?owHNOG&s?tmRJ!Efk4MKRp4b$?Wqk2ReM8#adgWXBHH)M8t*!><L`=xfoFTOI
zfc1~hML!(>W~+7mQHj6);z;<GzE)HAWh?j^<$h1w@TqPp2iL!ouCgUlIhNikI`;2~
z*zpp@Q+(R<-g5?jSZl0v_syo46@Cp%UIe*uTr_5xCZ3Yw^3;ayN~-E+4&95rFHS~P
zn(VRr`qw>T>7M|l8TGp=*={+1<DanZS=(3cxJ7*5!)7g=cRhXe({lbxmv@`~k6$1<
z`NqLtDqAFr(>3PVMfbAS6<fc%dh*XgU!E)FoZ&Bw{ccX1G((b!nUR5Uaj-$4fh;gq
zW%*ddSVU(1{e8H-{Upm@<!|@5FMY^y)vB=1KprHm%pzeR)_`3BD51y-Gcx{XVKra|
zQpmv$OliPiXJpVkB(hx1B59}RyvsKiKTuRJQjJ(%+EDW^ZRPv)JAp5>Cr_K2e=#Q^
z?9u|SuC^(xdOsJL$vyO0VmE)2MceX;yO#c5oxnN2o2%wjN63Q>-H!aL9a%nm^$A9{
z-O$cW*WR{d!$kjdsTy<M|CWM{;f7|4BESC5kSMMC5b(re{q552V)>Gn=9U{Cn3t;k
z`Pl9)rKfY;ZX|~UI34|OxIe;v{(++Z%#(J8_ts3>{%BuNbyMRd$9reu<Ic*&UTNFI
znK|!7S@c{dqxNeYs<L|L%i2U<37@;&<X_x<(J;m6_2T@fqDA)Ivt?bkN?m5N)?L|`
Y8QypBxIx5$Q^ywFxxx`Jeepp}08o%?_5c6?

literal 0
HcmV?d00001

diff --git a/ext/tls/testdata/example1_prikey.der b/ext/tls/testdata/example1_prikey.der
new file mode 100644
index 0000000000000000000000000000000000000000..1cf7ef1d2f3ea9453ca0543d05e07821d7c93ede
GIT binary patch
literal 1190
zcmV;X1X=qqf&`)h0RRGm0RaHEg-$jNs>LjMB}r8qtT7=ZPt9YU-6>-!Epn~U-T!H)
zFXbC_{`lg@k;t-83Nz98e}HD)e<Rv&e4|<qI@M8ZSdedNm=dMHJNWZ*_(A<^CW`zd
zU)SiwSG10WH3z1s4uKx~may`El?V#{$weJ>l?bKUa>o9|7RPiU$_^`@?+H`zturj$
z?6T>2PJpE7Qbq{TGX$0wWMo9;JO<QdC9?=E(T(WIT6r|QKK1=aSf%_>BA9==c?Q};
z_79M*=7#kPUZM{7R+^=r*JrEccMsCjyEXq`pcRwY!TKb$8FObSo<3WR1%7io?$ycs
zp-l|bcL`VMGfvr-l9(9+0|5X50)hbmAPq@YhcIKeLtpoxg+E9VVw%hS@F74g9CT51
z@*buIa`|6zqN+;aB0M<b4OqEQXk*or+SWp#&z`c~^cpx1I4D+D=2LM5-~9L^B44x6
z@uA;Z*L7$}ML>k1*@YfHmpKyFGRC{~ouh=g&y(Le1h~#Wx7?eO?lSb;F*(;FXd_pm
zohRl>jw$(9suxlie6X2Fu#V<SktR&LNGS-@{6&C@1Di4$_&w6H0H6-WV&1OupJ66X
zuG<c8D=q7G<_Uy`sQqUql!E@AJ-u6-jX=(VKhQx+V}-QGXOtE@kk}jn-KN;^MSQ;m
zsxcg}mSui#ATO9biXC>pD!o`u0)c@5?K%9Or@kYVCQkw3c};T-E3Pm<@w?JJ8|Lc5
z+@$1sR&-t%Sk(WBRQ;3T1}|k-`_hvby_?TCa#p_7iA)B|SN`OXA10@jz{F+hX1WGI
zh&R&Ov&yMz0RdXG6$lx!<l%~kA<h%xSz-D+x>ozsXfNM4P#8!{vSo!Ax#sm{0)c@5
z#P<eJVL)*S?{b&_hd73OzByBC`F@^A5iI5kHlWxGqF21dZi$kQekL{HyG%pzx<IBN
zJ+j~f_FA%6>jG-oGzt%%fugCcq~m9l&<K25ZzIk)kXda~Y|yL>$ZkzD^YC)uh~Ym=
z^dMH3McLF~BKEq<HG7U*H{+kBh6L870)c>jsCqAdVlIDR&&V=KV8^fBg@`X}@|z-)
zb}SpzP?^Y+##h4X68A_X5UbYqMRE6%^>89Wf*}@zJ-ct9%ALv$_JXubU5FNyu!gm(
z8DV2B7nv2g?$?`0WFNQ#->OjXkykV&A#qM+=)nO9(T;59aKPR;er|&_0j?P5;on^X
zfq-VMFNtqy9E3$;!-3t0#q;@Q0P5tR@cKBJ<3Xpusb5Du-IhL0Q7xolUhPq;EHN`0
z$bUX6r9|t4)I6xN73nOCq9Dr)bkL-TH&X~Nq(iWDMd*&VPnrxztElcnG1JF#tuP0x
z1V|tEORR_~N#NtzBL0qQ-iHR)jy=a?c2NR>fJ<o@W0<>E<~2U)9YWPa1ARRkYgUcd
zEjs3P$sz4CM*VNN!#j?F-exnB*PK{r9+tZVP&3%|7{X4Hjp!fz%XD;%d_H9e;WEu%
zw#TyOE}5$fpDMeL6|x432Z}@LITLt{Z;d&DR38shQ#D;WT6lDV<TZ?`z&e?IY`+#K
E`!Q`mvH$=8

literal 0
HcmV?d00001

diff --git a/ext/tls/testdata/example2_cert.der b/ext/tls/testdata/example2_cert.der
new file mode 100644
index 0000000000000000000000000000000000000000..4428f3f6b079d67a21aa00b22593d26242011913
GIT binary patch
literal 929
zcmXqLVxDWz#MHWgnTe5!NyJ6@X3K1G#{ad9Qa_><O}^!)1*;qIvT<s)d9;1!Wn|=L
zWiW^{<Tl`BV-96u6J`nxHsmwl0dY8ZSc6LvOHvI54fsKPb{-C&{N%)(%#un&Q3GL+
z5El=Re^Gj3US?HdNoIZ?OqiL6C$%Cmw;(6gNG~}**Fa93*T}@c%)rFZ(Ae12C<@Fq
zhjVFee-on;vX>cI8JL?G`56qF7`d357#SH3a2DO+%B<4(rye=)n*2Hb?*B5IS2gSX
zvioOtv}5axx|81Fp=Z4Q9of5U<xN42xHFy+s!8>goS*xYwx!HCaDL1AOApRjonoDv
z$)=I)8@X@Qc>~VuM|;a%GE`>!F6v%7d4@PkpV)mjGe-m6nu$-NK3<o67Iw6*^4sD2
zZQsr~f84VB(f=jKkGw0i$`X2gBqOh&Y>HTtNl(6`gvRtGKiJH}4^4Gqn<{ME|8D2p
zPfH4QZvUIPsH;lnKv&<Rs!Ds_g_?V3eY~D}uIswDOv{`1pN)-V<vQX&yuVv;_secQ
z@l#LFGH-j4xAMr6Z`D5vRb-Ev|4I$~@!5T&?BWiQjsJt6i2Y|`W@KPo9BdG1APbCD
zSw0pq7Lm}I`*f$>yCflT)-Yh2-m|zB2}ceY$b+PnStJa^8n7z>B@|g<M#ldvtOm?L
z3OU$;DGeCxj127Nj$ZCM%kPz~oXfWFmaEc{zzM;>wn=l8efF?v-n2{e@``zl4vW`&
zZ{-xctm<pA(!rztt#<ACl8|~81KCp?o;DJdFRT4pZeG#9?`B_nmc{jKc=Dt*F2^QG
z?cT&ZzpidVnCqSi4Qn3UbyZKe(3Loud*h)B&K0cbLSl9kW#0;2nEhN*$wP)m?!4@w
zH7vh$9_BI`vTgN#x845kF?Xh~H9^O=|E^ghP@v)<<Co_Xl(27Id^3|v;(zwfsy|wu
z`g8Q~X3w5~=;i5m=d_cX<vu%f8;EBu+4-++%H_8k>u$Qs-Dz>sknLW0_t>Ll&u{i$
YV&a~=g{Lg4egDjYk8hQ>c|QmO0O~1ZSO5S3

literal 0
HcmV?d00001

diff --git a/ext/tls/testdata/example2_prikey.der b/ext/tls/testdata/example2_prikey.der
new file mode 100644
index 0000000000000000000000000000000000000000..8bdef8df382c4577b4a9ed68410926cf15866533
GIT binary patch
literal 1191
zcmV;Y1X%kpf&`-i0RRGm0RaHO33A*DX?iIBCt04>AI=Yp{~WWbgD(0${x-#kwU~a%
zOIKCQO8&&Xx~bU_C|=A-SS4bAc?t85BDQ3hz|XYL(%{ZI$_1Ti1}I}qS-z^zFbQko
zy>~=tB%4j5i=~s87X*$L-$ph;FfDwM<y!IA8Rk~SetGu8--h<gL-Dk`;{T+_#O`rA
zY7*<jXl`(Jlonz%jBi00D3_%81~*s2l|lxU6Fraaxt;Q)aV*>ZnWBn%EWnD6;(B>M
z4WTK$n(^0V&WhJd9E9xe^D{CX9*AG?@7-|S^t&z>%H_=iw&-rD#H99n_;Dm1#W(t8
zQTX#mu^pp`6tVwP<QD$|0|5X50)hbmE%}uo4E7hI{KeYz<@%FQv5Alii-iD~G{BR{
zQsj2;)2&bGV3CW^`a@VMd8-<h`S3b(3}vJCMNbwln@WA}q1mvkZt}9pZoOow@p#PV
z1J_bY8|;)rGE<>K!s&nLhyLomLC21Ls=25NEW4&WL+urEEV2yk0TbY{@li_ZIpPXh
zY{t|L)H?<R-2Ka&5H3S{k5pNNibgWOq)$=za#~WyQiAAL<l&F<)r7Na`?LA&6|gjo
zujeEr#bPyoKgxtFHmf4$Olqa5!?}$|IMUKh@o&BPZS!`^8?_&2sTNhrsd09c*Xc-I
zNRByfE?NFv-d_%Y62Bx-YhSUE0)c@5<d<B`AwP_!4(fnh7(8~Jn8l_?acT!*NVl~i
z7%!BztU^%kQQ|5a<Z|pv{Bxd(AVT@x@PCl%Jp9cOVJd*KveTpszV?YZ&~WSTWnnV=
zuyE9i=CU%ICo`Dm0m>2W5kSl3X(-~oOVwOY%|{iR8F`=n$SOC}#t)<xJbcs@0)c@5
z*ANT0|MC$8p>s22ALJ_7wh87yqLt6<icnQ@(zIRe1ZkqD5}}j&hrx<<1qfG#;}Rnu
zAf*=EF;Nk~S1M5EZFX1-<QBV!!P~<34!O&^F(13v<rDC>$DCMSV~C&n3w?=;QW)nb
zc;}~1XvcMnl<+}R;k+ZM^9$1uzMvn&0)c=tm1vH0?np`O(Zn}|44C7^X3V${g3-CZ
z86BCUK#_TibH|yG2F_#7@RS?#&JTBZJw)%PE7C&Ql3t)rVeR_mS=R~!gw(*KCFe)=
zgR-KNRZ`JoG|@1t?)%XlSwSRIAz>k!(rh3#ZKqHs&7`%2Q7Y!Hy1+18;E1uW;-_T-
zfq)v*o|2j~sM*Q|<G?nSFrE#+7+|rdJY!};brv|FRU;0p+N3&{yDY*eYfJ-=vC}%L
z^@N#z-ew~txUnQ|Ti+6bbE7a7f!P9HmS|Z9<{8+m+p?#bpej734FmxfcGW8X!rO%>
zBo>iYTrpI#q`&`}B%L7lW&e5@+<-SXBp(8SfdI{1XoFy7BAIQA=`-tJr&L#tJ2W=%
zKmPNjt%O4NTBoTsDkaF?d?d$iqt&QGLj*^<e@%%fRFJxS={&ZxIXb_|mIq>2&J0FQ
zQg-g6Ej2#E+!j~IKha4mGC=p~kqxg^$u601`cH)WP_JL#T^-N%(n$M`iXkswoY(MV
Fq87UwR!jf@

literal 0
HcmV?d00001

diff --git a/ext/tls/tls_key.rs b/ext/tls/tls_key.rs
index 47a8e0e5707d4e..66fac86f87f9c1 100644
--- a/ext/tls/tls_key.rs
+++ b/ext/tls/tls_key.rs
@@ -11,8 +11,6 @@
 //! key lookup can handle closing one end of the pair, in which case they will just
 //! attempt to clean up the associated resources.
 
-use crate::Certificate;
-use crate::PrivateKey;
 use deno_core::anyhow::anyhow;
 use deno_core::error::AnyError;
 use deno_core::futures::future::poll_fn;
@@ -32,12 +30,21 @@ use std::sync::Arc;
 use tokio::sync::broadcast;
 use tokio::sync::mpsc;
 use tokio::sync::oneshot;
+use webpki::types::CertificateDer;
+use webpki::types::PrivateKeyDer;
 
 type ErrorType = Rc<AnyError>;
 
 /// A TLS certificate/private key pair.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct TlsKey(pub Vec<Certificate>, pub PrivateKey);
+/// see https://docs.rs/rustls-pki-types/latest/rustls_pki_types/#cloning-private-keys
+#[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)]
 pub enum TlsKeys {
@@ -111,9 +118,8 @@ impl TlsKeyResolver {
     let key = self.resolve(sni).await?;
 
     let mut tls_config = ServerConfig::builder()
-      .with_safe_defaults()
       .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;
     Ok(tls_config.into())
   }
@@ -255,14 +261,18 @@ impl TlsKeyLookup {
 pub mod tests {
   use super::*;
   use deno_core::unsync::spawn;
-  use rustls::Certificate;
-  use rustls::PrivateKey;
 
   fn tls_key_for_test(sni: &str) -> TlsKey {
-    TlsKey(
-      vec![Certificate(format!("{sni}-cert").into_bytes())],
-      PrivateKey(format!("{sni}-key").into_bytes()),
-    )
+    let manifest_dir =
+      std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
+    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]
@@ -274,8 +284,8 @@ pub mod tests {
       }
     });
 
-    let key = resolver.resolve("example.com".to_owned()).await.unwrap();
-    assert_eq!(tls_key_for_test("example.com"), key);
+    let key = resolver.resolve("example1.com".to_owned()).await.unwrap();
+    assert_eq!(tls_key_for_test("example1.com"), key);
     drop(resolver);
 
     task.await.unwrap();
@@ -290,13 +300,13 @@ pub mod tests {
       }
     });
 
-    let f1 = resolver.resolve("example.com".to_owned());
-    let f2 = resolver.resolve("example.com".to_owned());
+    let f1 = resolver.resolve("example1.com".to_owned());
+    let f2 = resolver.resolve("example1.com".to_owned());
 
     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();
-    assert_eq!(tls_key_for_test("example.com"), key);
+    assert_eq!(tls_key_for_test("example1.com"), key);
     drop(resolver);
 
     task.await.unwrap();
diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs
index 5c3e8d7b1b2498..9e320040b99556 100644
--- a/ext/websocket/lib.rs
+++ b/ext/websocket/lib.rs
@@ -36,14 +36,13 @@ use http::Request;
 use http::StatusCode;
 use http::Uri;
 use once_cell::sync::Lazy;
+use rustls_tokio_stream::rustls::pki_types::ServerName;
 use rustls_tokio_stream::rustls::RootCertStore;
-use rustls_tokio_stream::rustls::ServerName;
 use rustls_tokio_stream::TlsStream;
 use serde::Serialize;
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::cell::RefCell;
-use std::convert::TryFrom;
 use std::fmt;
 use std::future::Future;
 use std::num::NonZeroUsize;
@@ -245,8 +244,8 @@ async fn handshake_http1_wss(
 ) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
   let tcp_socket = TcpStream::connect(addr).await?;
   let tls_config = create_ws_client_config(state, SocketUse::Http1Only)?;
-  let dnsname =
-    ServerName::try_from(domain).map_err(|_| invalid_hostname(domain))?;
+  let dnsname = ServerName::try_from(domain.to_string())
+    .map_err(|_| invalid_hostname(domain))?;
   let mut tls_connector = TlsStream::new_client_side(
     tcp_socket,
     ClientConnection::new(tls_config.into(), dnsname)?,
@@ -270,8 +269,8 @@ async fn handshake_http2_wss(
 ) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
   let tcp_socket = TcpStream::connect(addr).await?;
   let tls_config = create_ws_client_config(state, SocketUse::Http2Only)?;
-  let dnsname =
-    ServerName::try_from(domain).map_err(|_| invalid_hostname(domain))?;
+  let dnsname = ServerName::try_from(domain.to_string())
+    .map_err(|_| invalid_hostname(domain))?;
   // We need to better expose the underlying errors here
   let mut tls_connector = TlsStream::new_client_side(
     tcp_socket,
diff --git a/tests/integration/run_tests.rs b/tests/integration/run_tests.rs
index 5bd0de60cea71b..b8263be29118f1 100644
--- a/tests/integration/run_tests.rs
+++ b/tests/integration/run_tests.rs
@@ -5303,17 +5303,19 @@ async fn listen_tls_alpn() {
   let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
     "../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();
-  root_store.add_parsable_certificates(&certs);
+  root_store.add_parsable_certificates(certs);
   let mut cfg = rustls::ClientConfig::builder()
-    .with_safe_defaults()
     .with_root_certificates(root_store)
     .with_no_client_auth();
   cfg.alpn_protocols.push(b"foobar".to_vec());
   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")
     .await
@@ -5355,17 +5357,18 @@ async fn listen_tls_alpn_fail() {
   let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
     "../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();
-  root_store.add_parsable_certificates(&certs);
+  root_store.add_parsable_certificates(certs);
   let mut cfg = rustls::ClientConfig::builder()
-    .with_safe_defaults()
     .with_root_certificates(root_store)
     .with_no_client_auth();
   cfg.alpn_protocols.push(b"boofar".to_vec());
   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")
     .await
diff --git a/tests/node_compat/config.jsonc b/tests/node_compat/config.jsonc
index 638af89c845b2f..8321173df0d136 100644
--- a/tests/node_compat/config.jsonc
+++ b/tests/node_compat/config.jsonc
@@ -394,14 +394,8 @@
       // "test-http-outgoing-message-inheritance.js",
       "test-http-outgoing-renderHeaders.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-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-better-error-messages-listen-path.js",
       "test-net-better-error-messages-path.js",
diff --git a/tests/node_compat/runner/TODO.md b/tests/node_compat/runner/TODO.md
index 0a68b810f82580..571e3ed66b7fe4 100644
--- a/tests/node_compat/runner/TODO.md
+++ b/tests/node_compat/runner/TODO.md
@@ -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-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-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-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)
diff --git a/tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js b/tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js
deleted file mode 100644
index eaa63bab73af09..00000000000000
--- a/tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js
+++ /dev/null
@@ -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();
-});
diff --git a/tests/node_compat/test/parallel/test-http-url.parse-auth.js b/tests/node_compat/test/parallel/test-http-url.parse-auth.js
deleted file mode 100644
index 3bf3242c970c93..00000000000000
--- a/tests/node_compat/test/parallel/test-http-url.parse-auth.js
+++ /dev/null
@@ -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();
-});
diff --git a/tests/node_compat/test/parallel/test-http-url.parse-basic.js b/tests/node_compat/test/parallel/test-http-url.parse-basic.js
deleted file mode 100644
index 7018cd41097b10..00000000000000
--- a/tests/node_compat/test/parallel/test-http-url.parse-basic.js
+++ /dev/null
@@ -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();
-});
diff --git a/tests/node_compat/test/parallel/test-http-url.parse-path.js b/tests/node_compat/test/parallel/test-http-url.parse-path.js
deleted file mode 100644
index f0c07887f2d6c2..00000000000000
--- a/tests/node_compat/test/parallel/test-http-url.parse-path.js
+++ /dev/null
@@ -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();
-});
diff --git a/tests/node_compat/test/parallel/test-http-url.parse-post.js b/tests/node_compat/test/parallel/test-http-url.parse-post.js
deleted file mode 100644
index c591146035f957..00000000000000
--- a/tests/node_compat/test/parallel/test-http-url.parse-post.js
+++ /dev/null
@@ -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();
-});
diff --git a/tests/node_compat/test/parallel/test-http-url.parse-search.js b/tests/node_compat/test/parallel/test-http-url.parse-search.js
deleted file mode 100644
index 8725331618c15a..00000000000000
--- a/tests/node_compat/test/parallel/test-http-url.parse-search.js
+++ /dev/null
@@ -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();
-});
diff --git a/tests/specs/cert/localhost_unsafe_ssl/localhost_unsafe_ssl.ts.out b/tests/specs/cert/localhost_unsafe_ssl/localhost_unsafe_ssl.ts.out
index 81e490c1cd9ebb..3067fffae2edad 100644
--- a/tests/specs/cert/localhost_unsafe_ssl/localhost_unsafe_ssl.ts.out
+++ b/tests/specs/cert/localhost_unsafe_ssl/localhost_unsafe_ssl.ts.out
@@ -1,3 +1,3 @@
 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]
diff --git a/tests/unit/fetch_test.ts b/tests/unit/fetch_test.ts
index 4176f39ace218a..b549be9a438a87 100644
--- a/tests/unit/fetch_test.ts
+++ b/tests/unit/fetch_test.ts
@@ -67,7 +67,7 @@ Deno.test(
         await fetch(`http://localhost:${port}`);
       },
       TypeError,
-      "error trying to connect",
+      "error sending request for url",
     );
   },
 );
@@ -80,7 +80,7 @@ Deno.test(
         await fetch("http://nil/");
       },
       TypeError,
-      "error trying to connect",
+      "error sending request for url",
     );
   },
 );
@@ -1824,7 +1824,7 @@ Deno.test(
         await fetch(`http://${addr}/`);
       },
       TypeError,
-      "invalid content-length parsed",
+      "error sending request",
     );
 
     listener.close();
@@ -1880,7 +1880,7 @@ Deno.test(
         await response.arrayBuffer();
       },
       Error,
-      "end of file before message length reached",
+      "error decoding response body",
     );
 
     listener.close();
diff --git a/tests/unit/http_test.ts b/tests/unit/http_test.ts
index 6968c6f8809dcc..eddb1520b460aa 100644
--- a/tests/unit/http_test.ts
+++ b/tests/unit/http_test.ts
@@ -2574,7 +2574,7 @@ for (const compression of [true, false]) {
       assertEquals(result.value, new Uint8Array([65]));
       const err = await assertRejects(() => reader.read());
       assert(err instanceof TypeError);
-      assert(err.message.includes("unexpected EOF"));
+      assert(err.message.includes("error decoding response body"));
 
       const httpConn = await server;
       httpConn.close();
@@ -2610,7 +2610,7 @@ for (const compression of [true, false]) {
       assertEquals(result.value, new Uint8Array([65]));
       const err = await assertRejects(() => reader.read());
       assert(err instanceof TypeError);
-      assert(err.message.includes("unexpected internal error encountered"));
+      assert(err.message.includes("error decoding response body"));
 
       const httpConn = await server;
       httpConn.close();
diff --git a/tests/unit/serve_test.ts b/tests/unit/serve_test.ts
index ff77578e613a76..36366706610ba7 100644
--- a/tests/unit/serve_test.ts
+++ b/tests/unit/serve_test.ts
@@ -3522,11 +3522,7 @@ Deno.test(
       fail();
     } catch (clientError) {
       assert(clientError instanceof TypeError);
-      assert(
-        clientError.message.endsWith(
-          "connection closed before message completed",
-        ),
-      );
+      assert(clientError.message.includes("error sending request for url"));
     } finally {
       ac.abort();
       await server.finished;
@@ -3574,11 +3570,7 @@ Deno.test({
       fail();
     } catch (clientError) {
       assert(clientError instanceof TypeError);
-      assert(
-        clientError.message.endsWith(
-          "connection closed before message completed",
-        ),
-      );
+      assert(clientError.message.includes("error sending request for url"));
     } finally {
       ac.abort();
       await server.finished;
diff --git a/tests/util/server/src/https.rs b/tests/util/server/src/https.rs
index 8a2524dca9622d..617fd5cae29d44 100644
--- a/tests/util/server/src/https.rs
+++ b/tests/util/server/src/https.rs
@@ -2,9 +2,9 @@
 use anyhow::anyhow;
 use futures::Stream;
 use futures::StreamExt;
-use rustls::Certificate;
-use rustls::PrivateKey;
 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 std::io;
 use std::num::NonZeroUsize;
@@ -68,30 +68,30 @@ pub fn get_tls_config(
   let key_file = std::fs::File::open(key_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);
-    rustls_pemfile::certs(&mut cert_reader)
-      .unwrap()
-      .into_iter()
-      .map(Certificate)
-      .collect()
+    rustls_pemfile::certs(&mut cert_reader).collect()
   };
+  let certs = certs_result?;
 
   let mut ca_cert_reader = io::BufReader::new(ca_file);
   let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader)
-    .expect("Cannot load CA certificate")
-    .remove(0);
+    .collect::<Vec<_>>()
+    .remove(0)?;
 
   let mut key_reader = io::BufReader::new(key_file);
   let key = {
-    let pkcs8_key = rustls_pemfile::pkcs8_private_keys(&mut key_reader)
-      .expect("Cannot load key file");
-    let rsa_key = rustls_pemfile::rsa_private_keys(&mut key_reader)
-      .expect("Cannot load key file");
-    if !pkcs8_key.is_empty() {
-      Some(pkcs8_key[0].clone())
-    } else if !rsa_key.is_empty() {
-      Some(rsa_key[0].clone())
+    let pkcs8_keys = rustls_pemfile::pkcs8_private_keys(&mut key_reader)
+      .collect::<Result<Vec<_>, _>>()?;
+    let rsa_keys = rustls_pemfile::rsa_private_keys(&mut key_reader)
+      .collect::<Result<Vec<_>, _>>()?;
+
+    if !pkcs8_keys.is_empty() {
+      let key = pkcs8_keys[0].clone_key();
+      Some(PrivateKeyDer::from(key))
+    } else if !rsa_keys.is_empty() {
+      let key = rsa_keys[0].clone_key();
+      Some(PrivateKeyDer::from(key))
     } else {
       None
     }
@@ -100,18 +100,19 @@ pub fn get_tls_config(
   match key {
     Some(key) => {
       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.
+      let client_verifier = rustls::server::WebPkiClientVerifier::builder(
+        Arc::new(root_cert_store),
+      )
+      .allow_unauthenticated()
+      .build()
+      .unwrap();
 
       let mut config = rustls::ServerConfig::builder()
-        .with_safe_defaults()
-        .with_client_cert_verifier(Arc::new(
-          rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(
-            root_cert_store,
-          ),
-        ))
-        .with_single_cert(certs, PrivateKey(key))
+        .with_client_cert_verifier(client_verifier)
+        .with_single_cert(certs, key)
         .map_err(|e| anyhow!("Error setting cert: {:?}", e))
         .unwrap();