From e22a5c0a4a003cae4c5c75f071dcaf79c90a32b6 Mon Sep 17 00:00:00 2001 From: rucciva Date: Thu, 17 Oct 2024 17:16:58 +0700 Subject: [PATCH] feat(transport): add http2 transport (#392) --- .github/workflows/release.yml | 2 +- .github/workflows/rust.yml | 6 +- Cargo.lock | 981 +++++++++++++++---------- Cargo.toml | 28 + README.md | 8 +- src/client.rs | 11 + src/config.rs | 10 + src/server.rs | 11 + src/transport/http2.rs | 417 +++++++++++ src/transport/maybe_tls.rs | 84 +++ src/transport/mod.rs | 13 + src/transport/native_tls.rs | 2 +- src/transport/rustls.rs | 1 + src/transport/websocket.rs | 95 +-- tests/for_tcp/http2_tls_transport.toml | 33 + tests/for_tcp/http2_transport.toml | 27 + tests/for_udp/http2_tls_transport.toml | 37 + tests/for_udp/http2_transport.toml | 31 + tests/integration_test.rs | 14 +- 19 files changed, 1343 insertions(+), 468 deletions(-) mode change 100644 => 100755 Cargo.lock mode change 100644 => 100755 Cargo.toml mode change 100644 => 100755 src/config.rs create mode 100755 src/transport/http2.rs create mode 100644 src/transport/maybe_tls.rs mode change 100644 => 100755 src/transport/mod.rs create mode 100644 tests/for_tcp/http2_tls_transport.toml create mode 100644 tests/for_tcp/http2_transport.toml create mode 100644 tests/for_udp/http2_tls_transport.toml create mode 100644 tests/for_udp/http2_transport.toml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 48a60cb3..f33e2e09 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -128,7 +128,7 @@ jobs: version: v4.0.2 files: target/${{ matrix.target }}/release/${{ matrix.exe }} args: -q --best --lzma - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: rathole-${{ matrix.target }} path: target/${{ matrix.target }}/release/${{ matrix.exe }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 916c0edf..1334c059 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -34,7 +34,7 @@ jobs: - name: Check all features run: > cargo hack check --feature-powerset --no-dev-deps - --mutually-exclusive-features default,native-tls,websocket-native-tls,rustls,websocket-rustls + --mutually-exclusive-features default,native-tls,websocket-native-tls,http2-native-tls,rustls,websocket-rustls,http2-rustls build: name: Build for ${{ matrix.target }} @@ -67,8 +67,8 @@ jobs: - name: Run tests with native-tls run: cargo test --verbose - name: Run tests with rustls - run: cargo test --verbose --no-default-features --features server,client,rustls,noise,websocket-rustls,hot-reload - - uses: actions/upload-artifact@v2 + run: cargo test --verbose --no-default-features --features server,client,rustls,noise,websocket-rustls,http2-rustls,hot-reload + - uses: actions/upload-artifact@v4 with: name: rathole-${{ matrix.target }} path: target/debug/${{ matrix.exe }} diff --git a/Cargo.lock b/Cargo.lock old mode 100644 new mode 100755 index 95fb8ac4..0af6a244 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -54,18 +54,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "async-http-proxy" @@ -92,15 +92,21 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atty" version = "0.2.14" @@ -114,9 +120,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" @@ -129,9 +135,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.31", "itoa", "matchit", "memchr", @@ -155,8 +161,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -179,17 +185,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -200,9 +206,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bincode" @@ -221,9 +227,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "blake2" @@ -254,15 +260,15 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" dependencies = [ "serde", ] @@ -278,12 +284,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -405,9 +412,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -415,46 +422,42 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -478,15 +481,14 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -494,20 +496,20 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "deranged" @@ -540,28 +542,28 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "enum-iterator" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] @@ -572,30 +574,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdlimit" @@ -608,27 +599,27 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.1" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", - "redox_syscall", - "windows-sys 0.48.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -657,9 +648,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -675,9 +666,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -689,9 +680,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -699,44 +690,44 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-macro", @@ -759,9 +750,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -770,21 +761,21 @@ dependencies = [ [[package]] name = "getset" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +checksum = "f636605b743120a8d32ed92fc27b6cde1a769f8f936c065151eb66f88ded513c" dependencies = [ - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.79", ] [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -792,9 +783,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git2" @@ -811,17 +802,36 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 2.2.3", + "http 0.2.12", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -836,17 +846,17 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "hdrhistogram" -version = "7.5.2" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", "byteorder", "flate2", "nom", @@ -870,9 +880,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -891,9 +901,20 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -902,20 +923,43 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -931,45 +975,85 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.5.7", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-timeout" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.31", "pin-project-lite", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.5.0", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -987,12 +1071,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.15.0", ] [[package]] @@ -1027,9 +1111,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -1045,15 +1129,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -1080,15 +1164,15 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "f0b21006cd1874ae9e650973c565615676dc4a274c965bb0a73796dac838ce4f" [[package]] name = "libgit2-sys" @@ -1102,11 +1186,22 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall", +] + [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -1116,15 +1211,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1132,9 +1227,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "matchers" @@ -1153,9 +1248,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -1171,18 +1266,18 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", @@ -1190,13 +1285,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi", + "windows-sys 0.52.0", +] + [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1231,7 +1337,7 @@ dependencies = [ "inotify", "kqueue", "libc", - "mio", + "mio 0.8.11", "walkdir", "windows-sys 0.45.0", ] @@ -1254,51 +1360,41 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.3", - "libc", -] - [[package]] name = "object" -version = "0.32.1" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -1315,7 +1411,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] @@ -1326,18 +1422,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.1+3.3.1" +version = "300.3.2+3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -1348,9 +1444,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.1" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "overload" @@ -1377,9 +1473,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1387,48 +1483,48 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1438,15 +1534,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "platforms" -version = "3.1.2" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "poly1305" @@ -1461,9 +1551,9 @@ dependencies = [ [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -1479,9 +1569,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro-error" @@ -1507,11 +1600,33 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -1550,9 +1665,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1606,6 +1721,10 @@ dependencies = [ "futures-core", "futures-sink", "hex", + "http 1.1.0", + "http-body-util", + "hyper 1.5.0", + "hyper-util", "lazy_static", "notify", "openssl", @@ -1616,13 +1735,14 @@ dependencies = [ "serde", "sha2", "snowstorm", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "tokio-native-tls", "tokio-rustls", "tokio-tungstenite", "tokio-util", "toml", + "tower-service", "tracing", "tracing-subscriber", "url", @@ -1640,23 +1760,23 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.9.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.9", - "regex-syntax 0.7.5", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -1670,13 +1790,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.9" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.5", ] [[package]] @@ -1687,57 +1807,58 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.15" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.22.2" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring", @@ -1749,9 +1870,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -1762,25 +1883,24 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.21.4", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.3.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048a63e5b3ac996d78d402940b5fa47973d2d080c6c6fffa1d0f19c4445310b7" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -1789,15 +1909,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1810,11 +1930,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -1825,11 +1945,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -1838,9 +1958,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -1848,37 +1968,38 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.19" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1907,18 +2028,24 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b21f559e07218024e7e9f90f96f601825397de0e25420135f7f952453fed0b" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -1934,9 +2061,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snow" @@ -1970,9 +2097,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -1980,12 +2107,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2002,9 +2129,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -2019,9 +2146,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -2036,57 +2163,57 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "termcolor" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "textwrap" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -2125,9 +2252,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2140,22 +2267,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", - "mio", - "num_cpus", + "mio 1.0.2", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.7", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2170,13 +2296,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] @@ -2202,9 +2328,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -2225,16 +2351,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -2254,14 +2379,14 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.4", + "base64 0.21.7", "bytes", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.31", "hyper-timeout", "percent-encoding", "pin-project", @@ -2296,23 +2421,22 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2320,20 +2444,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.79", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -2341,20 +2465,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", @@ -2371,9 +2495,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" @@ -2384,7 +2508,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", "httparse", "log", "rand", @@ -2402,21 +2526,21 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -2439,9 +2563,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -2485,15 +2609,15 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -2532,11 +2656,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -2563,6 +2687,24 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -2593,6 +2735,22 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -2605,6 +2763,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -2617,6 +2781,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -2629,6 +2799,18 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -2641,6 +2823,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -2653,6 +2841,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -2665,6 +2859,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -2677,14 +2877,41 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "yasna" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml old mode 100644 new mode 100755 index e7a944ec..fa66adaf --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ default = [ "native-tls", "noise", "websocket-native-tls", + "http2-native-tls", "hot-reload", ] @@ -53,6 +54,28 @@ websocket-rustls = [ "rustls", ] +# HTTP2 support +http2-native-tls = [ + "hyper", + "hyper-util", + "http", + "http-body-util", + "futures-core", + "tokio-util", + "tower-service", + "native-tls", +] +http2-rustls = [ + "hyper", + "hyper-util", + "http", + "http-body-util", + "futures-core", + "tokio-util", + "tower-service", + "rustls", +] + # Configuration hot-reload support hot-reload = ["notify"] @@ -117,6 +140,11 @@ async-http-proxy = { version = "1.2", features = [ async-socks5 = "0.5" url = { version = "2.2", features = ["serde"] } tokio-tungstenite = { version = "0.20.1", optional = true } +http = { version = "1.1.0", optional = true } +hyper = { version = "1.4.1", optional = true , features = ["client","server","http2"] } +hyper-util = { version = "0.1.9", optional = true , features = ["full"]} +http-body-util = { version = "0.1.2", optional = true } +tower-service = { version = "0.3.3", optional = true } tokio-util = { version = "0.7.9", optional = true, features = ["io"] } futures-core = { version = "0.3.28", optional = true } futures-sink = { version = "0.3.28", optional = true } diff --git a/README.md b/README.md index 25cf97f1..0c854b48 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ heartbeat_timeout = 40 # Optional. Set to 0 to disable the application-layer hea retry_interval = 1 # Optional. The interval between retry to connect to the server. Default: 1 second [client.transport] # The whole block is optional. Specify which transport to use -type = "tcp" # Optional. Possible values: ["tcp", "tls", "noise"]. Default: "tcp" +type = "tcp" # Optional. Possible values: ["tcp", "tls", "noise", "websocket", "http2"]. Default: "tcp" [client.transport.tcp] # Optional. Also affects `noise` and `tls` proxy = "socks5://user:passwd@127.0.0.1:1080" # Optional. The proxy used to connect to the server. `http` and `socks5` is supported. @@ -131,6 +131,9 @@ remote_public_key = "key_encoded_in_base64" # Optional [client.transport.websocket] # Necessary if `type` is "websocket" tls = true # If `true` then it will use settings in `client.transport.tls` +[client.transport.http2] # Necessary if `type` is "http2" +tls = true # If `true` then it will use settings in `client.transport.tls` + [client.services.service1] # A service that needs forwarding. The name `service1` can change arbitrarily, as long as identical to the name in the server's configuration type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp" token = "whatever" # Necessary if `client.default_token` not set @@ -166,6 +169,9 @@ remote_public_key = "key_encoded_in_base64" [server.transport.websocket] # Necessary if `type` is "websocket" tls = true # If `true` then it will use settings in `server.transport.tls` +[server.transport.http2] # Necessary if `type` is "http2" +tls = true # If `true` then it will use settings in `server.transport.tls` + [server.services.service1] # The service name must be identical to the client side type = "tcp" # Optional. Same as the client `[client.services.X.type] token = "whatever" # Necessary if `server.default_token` not set diff --git a/src/client.rs b/src/client.rs index 2564869c..e376a5c3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -21,6 +21,8 @@ use tokio::sync::{broadcast, mpsc, oneshot, RwLock}; use tokio::time::{self, Duration, Instant}; use tracing::{debug, error, info, instrument, trace, warn, Instrument, Span}; +#[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] +use crate::transport::HTTP2Transport; #[cfg(feature = "noise")] use crate::transport::NoiseTransport; #[cfg(any(feature = "native-tls", feature = "rustls"))] @@ -74,6 +76,15 @@ pub async fn run_client( #[cfg(not(any(feature = "websocket-native-tls", feature = "websocket-rustls")))] crate::helper::feature_neither_compile("websocket-native-tls", "websocket-rustls") } + TransportType::HTTP2 => { + #[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] + { + let mut client = Client::::from(config).await?; + client.run(shutdown_rx, update_rx).await + } + #[cfg(not(any(feature = "http2-native-tls", feature = "http2-rustls")))] + crate::helper::feature_neither_compile("http2-native-tls", "http2-rustls") + } } } diff --git a/src/config.rs b/src/config.rs old mode 100644 new mode 100755 index ca85fc20..5a7116cc --- a/src/config.rs +++ b/src/config.rs @@ -51,6 +51,8 @@ pub enum TransportType { Noise, #[serde(rename = "websocket")] Websocket, + #[serde(rename = "http2")] + HTTP2, } /// Per service config @@ -141,6 +143,12 @@ pub struct WebsocketConfig { pub tls: bool, } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +#[serde(deny_unknown_fields)] +pub struct HTTP2Config { + pub tls: bool, +} + fn default_nodelay() -> bool { DEFAULT_NODELAY } @@ -186,6 +194,7 @@ pub struct TransportConfig { pub tls: Option, pub noise: Option, pub websocket: Option, + pub http2: Option, } fn default_heartbeat_timeout() -> u64 { @@ -320,6 +329,7 @@ impl Config { Ok(()) } TransportType::Websocket => Ok(()), + TransportType::HTTP2 => Ok(()), } } diff --git a/src/server.rs b/src/server.rs index a4c49482..a65bf977 100644 --- a/src/server.rs +++ b/src/server.rs @@ -23,6 +23,8 @@ use tokio::sync::{broadcast, mpsc, RwLock}; use tokio::time; use tracing::{debug, error, info, info_span, instrument, warn, Instrument, Span}; +#[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] +use crate::transport::HTTP2Transport; #[cfg(feature = "noise")] use crate::transport::NoiseTransport; #[cfg(any(feature = "native-tls", feature = "rustls"))] @@ -83,6 +85,15 @@ pub async fn run_server( #[cfg(not(any(feature = "websocket-native-tls", feature = "websocket-rustls")))] crate::helper::feature_neither_compile("websocket-native-tls", "websocket-rustls") } + TransportType::HTTP2 => { + #[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] + { + let mut server = Server::::from(config).await?; + server.run(shutdown_rx, update_rx).await?; + } + #[cfg(not(any(feature = "http2-native-tls", feature = "http2-rustls")))] + crate::helper::feature_neither_compile("http2-native-tls", "http2-rustls") + } } Ok(()) diff --git a/src/transport/http2.rs b/src/transport/http2.rs new file mode 100755 index 00000000..3508eaf9 --- /dev/null +++ b/src/transport/http2.rs @@ -0,0 +1,417 @@ +use core::result::Result; +use std::future::Future; +use std::net::SocketAddr; +use std::pin::Pin; +use std::sync::Arc; +use std::task::{self, Context, Poll}; + +use anyhow::anyhow; +use async_trait::async_trait; +use bytes::{Buf, Bytes}; +use futures_core::Stream; +use http::{Method, Request, Response, Uri}; +use http_body_util::StreamBody; +use hyper::body::{Body, Incoming}; +use hyper::server::conn::http2 as Server; +use hyper::service::Service; +use hyper_util::client::legacy::connect::{Connected, Connection}; +use hyper_util::client::legacy::Client; +use hyper_util::rt::tokio::TokioExecutor; +use hyper_util::rt::tokio::TokioIo; +use tokio::io::{self, AsyncRead, AsyncWrite, ReadBuf, ReadHalf, SimplexStream, WriteHalf}; +use tokio::net::{TcpListener, ToSocketAddrs}; +use tokio::select; +use tokio::sync::Mutex; +use tokio::sync::{broadcast, mpsc}; +use tokio_util::io::ReaderStream; + +use super::maybe_tls::{MaybeTLSStream, MaybeTLSTransport}; +use super::{AddrMaybeCached, SocketOpts, Transport}; +use crate::config::TransportConfig; + +#[derive(Debug)] +struct IncomingHyper { + inner: hyper::body::Incoming, + current_chunk: Option, +} + +impl AsyncRead for IncomingHyper { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + loop { + if let Some(chunk) = &mut self.current_chunk { + let len = std::cmp::min(chunk.len(), buf.remaining()); + buf.put_slice(&chunk[..len]); + + chunk.advance(len); + if !chunk.has_remaining() { + self.current_chunk = None; + } + + return Poll::Ready(Ok(())); + } + + match Pin::new(&mut self.inner).poll_frame(cx) { + Poll::Pending => return Poll::Pending, + Poll::Ready(None) => return Poll::Ready(Ok(())), + Poll::Ready(Some(Err(err))) => { + return Poll::Ready(Err(io::Error::new(io::ErrorKind::Other, err))) + } + Poll::Ready(Some(Ok(frame))) => match frame.into_data() { + Err(_) => { + return Poll::Ready(Err(io::Error::new( + io::ErrorKind::Other, + "non data frame received", + ))) + } + Ok(data) => { + self.current_chunk = Some(data); + continue; + } + }, + } + } + } +} + +#[derive(Debug)] +pub struct HTTP2Stream { + send: WriteHalf, + recv: IncomingHyper, +} + +impl AsyncRead for HTTP2Stream { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.get_mut().recv).poll_read(cx, buf) + } +} + +impl AsyncWrite for HTTP2Stream { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.get_mut().send).poll_write(cx, buf) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.get_mut().send).poll_flush(cx) + } + + fn poll_shutdown( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + Pin::new(&mut self.get_mut().send).poll_shutdown(cx) + } +} + +#[derive(Debug)] +pub struct OutgoingSimplex { + inner: ReaderStream>, +} + +impl Stream for OutgoingSimplex { + type Item = Result, io::Error>; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match Pin::new(&mut self.get_mut().inner).poll_next(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(None) => Poll::Ready(None), + Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(err))), + Poll::Ready(Some(Ok(data))) => Poll::Ready(Some(Ok(hyper::body::Frame::data(data)))), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +#[derive(Debug)] +struct Svc { + req_sender: mpsc::Sender)>>, + addr: SocketAddr, +} + +impl Service> for Svc { + type Response = Response>; + type Error = anyhow::Error; + type Future = Pin> + Send>>; + + fn call(&self, req: Request) -> Self::Future { + let req_sender = self.req_sender.clone(); + let addr = self.addr; + + let future = async move { + let (res_sender, mut res_receiver) = mpsc::channel::(1); + if let Err(err) = req_sender + .send(Ok((addr, req.into_body(), res_sender))) + .await + { + return Err(anyhow!(err.to_string())); + } + + match res_receiver.recv().await { + None => Err(anyhow!("Channel closed")), + Some(body) => Ok(Response::new(http_body_util::StreamBody::new(body))), + } + }; + + Box::pin(future) // Return the boxed future + } +} + +async fn start_http_server( + listener: TcpListener, + transport: Arc, + req_sender: mpsc::Sender)>>, + stop_receiver: broadcast::Receiver<()>, +) -> anyhow::Result<()> { + loop { + let mut stop_receiver = stop_receiver.resubscribe(); + let conn = async { + match transport.as_ref() { + MaybeTLSTransport::No(t) => { + let (conn, addr) = t.accept(&listener).await?; + let stream = t.handshake(conn).await?; + Ok((MaybeTLSStream::No(stream), addr)) + } + MaybeTLSTransport::Yes(t) => { + let (conn, addr) = t.accept(&listener).await?; + let stream = t.handshake(conn).await?; + Ok((MaybeTLSStream::Yes(stream), addr)) + } + } + }; + select! { + _ = stop_receiver.recv() => { + return Ok(()); + } + + conn = conn => { + if let Err(err) = conn { + if let Err(err)= req_sender.send(Err(err)).await { + eprintln!("Error sending error message: {}", err); + } + continue + } + + let (socket, addr) = conn.unwrap(); + let io = TokioIo::new(socket); + let svc = Svc { + req_sender: req_sender.clone(), + addr, + }; + let req_sender= req_sender.clone(); + tokio::spawn(async move { + let mut conn = Server::Builder::new(TokioExecutor::new()) + .serve_connection(io, svc); + select! { + _ = stop_receiver.recv() => { + Pin::new(&mut conn).graceful_shutdown(); + } + + res = &mut conn => { + if let Err(err) = res { + if let Err(err)= req_sender.send(Err(anyhow!(err.to_string()))).await { + eprintln!("Error sending error message: {}", err); + } + } + } + } + }); + } + } + } +} + +impl Connection for MaybeTLSStream { + fn connected(&self) -> Connected { + let connected = Connected::new(); + if let (Ok(remote_addr), Ok(local_addr)) = ( + self.get_tcpstream().peer_addr(), + self.get_tcpstream().local_addr(), + ) { + connected.extra((remote_addr, local_addr)) + } else { + connected + } + } +} + +#[derive(Clone)] +struct MaybeTLSConnector { + sub: Arc, +} + +impl tower_service::Service for MaybeTLSConnector { + type Response = TokioIo; + type Error = anyhow::Error; + type Future = Pin> + Send>>; + + fn poll_ready(&mut self, _: &mut task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, u: Uri) -> Self::Future { + let sub = self.sub.clone(); + let future = async move { + let addr = match (u.host(), u.port()) { + (Some(host), Some(port)) => format!("{}:{}", host, port), + _ => String::from(""), + }; + let addr = AddrMaybeCached::new(addr.as_str()); + match sub.as_ref() { + MaybeTLSTransport::No(t) => match t.connect(&addr).await { + Err(err) => Err(err), + Ok(s) => Ok(TokioIo::new(MaybeTLSStream::No(s))), + }, + MaybeTLSTransport::Yes(t) => match t.connect(&addr).await { + Err(err) => Err(err), + Ok(s) => Ok(TokioIo::new(MaybeTLSStream::Yes(s))), + }, + } + }; + Box::pin(future) + } +} + +#[derive(Debug)] +pub struct HTTP2Transport { + sub_transport: Arc, + client: Client>, + + stop_sender: broadcast::Sender<()>, + stop_receiver: broadcast::Receiver<()>, +} + +#[async_trait] +impl Transport for HTTP2Transport { + type Acceptor = Arc< + Mutex< + mpsc::Receiver)>>, + >, + >; + type RawStream = (Incoming, mpsc::Sender); + type Stream = HTTP2Stream; + + fn new(config: &TransportConfig) -> anyhow::Result { + let cfg = config + .http2 + .as_ref() + .ok_or_else(|| anyhow!("Missing http2 config"))?; + + let (stop_sender, stop_receiver) = broadcast::channel(1); + let sub_transport = Arc::new(MaybeTLSTransport::new(cfg.tls, config)?); + let client = Client::builder(TokioExecutor::new()) + .http2_only(true) + .build(MaybeTLSConnector { + sub: sub_transport.clone(), + }); + + Ok(HTTP2Transport { + sub_transport, + client, + stop_sender, + stop_receiver, + }) + } + + fn hint(_: &Self::Stream, _: SocketOpts) {} + + async fn bind( + &self, + addr: A, + ) -> anyhow::Result { + let listener = TcpListener::bind(addr).await?; + + let (req_sender, req_receiver) = mpsc::channel::< + anyhow::Result<(SocketAddr, Incoming, mpsc::Sender)>, + >(1); + let req_receiver = Arc::new(Mutex::new(req_receiver)); + let sub_transport = self.sub_transport.clone(); + let stop_receiver = self.stop_receiver.resubscribe(); + tokio::spawn(start_http_server( + listener, + sub_transport, + req_sender, + stop_receiver, + )); + Ok(req_receiver) + } + + async fn accept(&self, a: &Self::Acceptor) -> anyhow::Result<(Self::RawStream, SocketAddr)> { + let mut receiver = a.lock().await; + match receiver.recv().await { + None => Err(anyhow!("Channel closed")), + Some(Err(err)) => Err(err), + Some(Ok((addr, incoming, res_sender))) => Ok(((incoming, res_sender), addr)), + } + } + + async fn handshake(&self, conn: Self::RawStream) -> anyhow::Result { + let (incoming, res_sender) = conn; + + let (sread, swrite) = io::simplex(4096); + if let Err(err) = res_sender + .send(OutgoingSimplex { + inner: ReaderStream::with_capacity(sread, 4096), + }) + .await + { + return Err(anyhow!(err.to_string())); + } + + Ok(HTTP2Stream { + recv: IncomingHyper { + inner: incoming, + current_chunk: None, + }, + send: swrite, + }) + } + + async fn connect(&self, addr: &AddrMaybeCached) -> anyhow::Result { + let client = self.client.clone(); + let (sread, swrite) = io::simplex(4096); + let body = http_body_util::StreamBody::new(OutgoingSimplex { + inner: ReaderStream::with_capacity(sread, 4096), + }); + let req = Request::builder() + .method(Method::POST) + .uri(format!("http://{}", &addr.addr.as_str())) + .body(body) + .expect("request builder"); + let res = client.request(req).await; + if let Err(err) = res { + return Err(anyhow!("Error: {}", err)); + } + + let res = res.unwrap(); + if !res.status().is_success() { + return Err(anyhow!("Bad status code: {}", res.status())); + } + Ok(HTTP2Stream { + recv: IncomingHyper { + inner: res.into_body(), + current_chunk: None, + }, + send: swrite, + }) + } +} + +impl Drop for HTTP2Transport { + fn drop(&mut self) { + let _ = self.stop_sender.send(()); + } +} diff --git a/src/transport/maybe_tls.rs b/src/transport/maybe_tls.rs new file mode 100644 index 00000000..65eebdfa --- /dev/null +++ b/src/transport/maybe_tls.rs @@ -0,0 +1,84 @@ +use std::pin::Pin; +use std::task::{Context, Poll}; + +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use tokio::net::TcpStream; + +use super::tls::get_tcpstream; +use super::tls::TlsStream; +use super::TlsTransport; +use super::{TcpTransport, Transport}; +use crate::config::TransportConfig; + +#[derive(Debug)] +pub(super) enum MaybeTLSStream { + No(TcpStream), + Yes(TlsStream), +} + +impl MaybeTLSStream { + pub(super) fn get_tcpstream(&self) -> &TcpStream { + match self { + MaybeTLSStream::No(s) => s, + MaybeTLSStream::Yes(s) => get_tcpstream(s), + } + } +} + +impl AsyncRead for MaybeTLSStream { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + match self.get_mut() { + MaybeTLSStream::No(s) => Pin::new(s).poll_read(cx, buf), + MaybeTLSStream::Yes(s) => Pin::new(s).poll_read(cx, buf), + } + } +} + +impl AsyncWrite for MaybeTLSStream { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + match self.get_mut() { + MaybeTLSStream::No(s) => Pin::new(s).poll_write(cx, buf), + MaybeTLSStream::Yes(s) => Pin::new(s).poll_write(cx, buf), + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.get_mut() { + MaybeTLSStream::No(s) => Pin::new(s).poll_flush(cx), + MaybeTLSStream::Yes(s) => Pin::new(s).poll_flush(cx), + } + } + + fn poll_shutdown( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + match self.get_mut() { + MaybeTLSStream::No(s) => Pin::new(s).poll_shutdown(cx), + MaybeTLSStream::Yes(s) => Pin::new(s).poll_shutdown(cx), + } + } +} + +#[derive(Debug)] +pub(super) enum MaybeTLSTransport { + Yes(TlsTransport), + No(TcpTransport), +} + +impl MaybeTLSTransport { + pub(super) fn new(tls: bool, tconfig: &TransportConfig) -> anyhow::Result { + match tls { + true => Ok(MaybeTLSTransport::Yes(TlsTransport::new(tconfig)?)), + false => Ok(MaybeTLSTransport::No(TcpTransport::new(tconfig)?)), + } + } +} diff --git a/src/transport/mod.rs b/src/transport/mod.rs old mode 100644 new mode 100755 index 26d357fb..241267fe --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -85,6 +85,14 @@ use rustls as tls; #[cfg(any(feature = "native-tls", feature = "rustls"))] pub(crate) use tls::TlsTransport; +#[cfg(any( + feature = "websocket-native-tls", + feature = "http2-native-tls", + feature = "websocket-rustls", + feature = "http2-rustls" +))] +mod maybe_tls; + #[cfg(feature = "noise")] mod noise; #[cfg(feature = "noise")] @@ -95,6 +103,11 @@ mod websocket; #[cfg(any(feature = "websocket-native-tls", feature = "websocket-rustls"))] pub use websocket::WebsocketTransport; +#[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] +mod http2; +#[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] +pub use http2::HTTP2Transport; + #[derive(Debug, Clone, Copy)] struct Keepalive { // tcp_keepalive_time if the underlying protocol is TCP diff --git a/src/transport/native_tls.rs b/src/transport/native_tls.rs index 40afd50b..4d0ed213 100644 --- a/src/transport/native_tls.rs +++ b/src/transport/native_tls.rs @@ -110,7 +110,7 @@ impl Transport for TlsTransport { } } -#[cfg(feature = "websocket-native-tls")] +#[cfg(any(feature = "websocket-native-tls", feature = "http2-native-tls"))] pub(crate) fn get_tcpstream(s: &TlsStream) -> &TcpStream { s.get_ref().get_ref().get_ref() } diff --git a/src/transport/rustls.rs b/src/transport/rustls.rs index 3ca4704e..b3dbda0a 100644 --- a/src/transport/rustls.rs +++ b/src/transport/rustls.rs @@ -151,6 +151,7 @@ impl Transport for TlsTransport { } } +#[cfg(any(feature = "websocket-rustls", feature = "http2-rustls"))] pub(crate) fn get_tcpstream(s: &TlsStream) -> &TcpStream { &s.get_ref().0 } diff --git a/src/transport/websocket.rs b/src/transport/websocket.rs index 228eff70..13742d84 100644 --- a/src/transport/websocket.rs +++ b/src/transport/websocket.rs @@ -4,8 +4,6 @@ use std::net::SocketAddr; use std::pin::Pin; use std::task::{ready, Context, Poll}; -use super::{AddrMaybeCached, SocketOpts, TcpTransport, TlsTransport, Transport}; -use crate::config::TransportConfig; use anyhow::anyhow; use async_trait::async_trait; use bytes::Bytes; @@ -13,78 +11,18 @@ use futures_core::stream::Stream; use futures_sink::Sink; use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf}; use tokio::net::{TcpListener, TcpStream, ToSocketAddrs}; - -#[cfg(any(feature = "native-tls", feature = "rustls"))] -use super::tls::get_tcpstream; -#[cfg(any(feature = "native-tls", feature = "rustls"))] -use super::tls::TlsStream; - use tokio_tungstenite::tungstenite::protocol::{Message, WebSocketConfig}; use tokio_tungstenite::{accept_async_with_config, client_async_with_config, WebSocketStream}; use tokio_util::io::StreamReader; use url::Url; -#[derive(Debug)] -enum TransportStream { - Insecure(TcpStream), - Secure(TlsStream), -} - -impl TransportStream { - fn get_tcpstream(&self) -> &TcpStream { - match self { - TransportStream::Insecure(s) => s, - TransportStream::Secure(s) => get_tcpstream(s), - } - } -} - -impl AsyncRead for TransportStream { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut ReadBuf<'_>, - ) -> Poll> { - match self.get_mut() { - TransportStream::Insecure(s) => Pin::new(s).poll_read(cx, buf), - TransportStream::Secure(s) => Pin::new(s).poll_read(cx, buf), - } - } -} - -impl AsyncWrite for TransportStream { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - match self.get_mut() { - TransportStream::Insecure(s) => Pin::new(s).poll_write(cx, buf), - TransportStream::Secure(s) => Pin::new(s).poll_write(cx, buf), - } - } - - fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.get_mut() { - TransportStream::Insecure(s) => Pin::new(s).poll_flush(cx), - TransportStream::Secure(s) => Pin::new(s).poll_flush(cx), - } - } - - fn poll_shutdown( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - match self.get_mut() { - TransportStream::Insecure(s) => Pin::new(s).poll_shutdown(cx), - TransportStream::Secure(s) => Pin::new(s).poll_shutdown(cx), - } - } -} +use super::maybe_tls::{MaybeTLSStream, MaybeTLSTransport}; +use super::{AddrMaybeCached, SocketOpts, Transport}; +use crate::config::TransportConfig; #[derive(Debug)] struct StreamWrapper { - inner: WebSocketStream, + inner: WebSocketStream, } impl Stream for StreamWrapper { @@ -170,15 +108,9 @@ impl AsyncWrite for WebsocketTunnel { } } -#[derive(Debug)] -enum SubTransport { - Secure(TlsTransport), - Insecure(TcpTransport), -} - #[derive(Debug)] pub struct WebsocketTransport { - sub: SubTransport, + sub: MaybeTLSTransport, conf: WebSocketConfig, } @@ -198,10 +130,7 @@ impl Transport for WebsocketTransport { write_buffer_size: 0, ..WebSocketConfig::default() }; - let sub = match wsconfig.tls { - true => SubTransport::Secure(TlsTransport::new(config)?), - false => SubTransport::Insecure(TcpTransport::new(config)?), - }; + let sub = MaybeTLSTransport::new(wsconfig.tls, config)?; Ok(WebsocketTransport { sub, conf }) } @@ -218,16 +147,16 @@ impl Transport for WebsocketTransport { async fn accept(&self, a: &Self::Acceptor) -> anyhow::Result<(Self::RawStream, SocketAddr)> { let (s, addr) = match &self.sub { - SubTransport::Insecure(t) => t.accept(a).await?, - SubTransport::Secure(t) => t.accept(a).await?, + MaybeTLSTransport::No(t) => t.accept(a).await?, + MaybeTLSTransport::Yes(t) => t.accept(a).await?, }; Ok((s, addr)) } async fn handshake(&self, conn: Self::RawStream) -> anyhow::Result { let tsream = match &self.sub { - SubTransport::Insecure(t) => TransportStream::Insecure(t.handshake(conn).await?), - SubTransport::Secure(t) => TransportStream::Secure(t.handshake(conn).await?), + MaybeTLSTransport::No(t) => MaybeTLSStream::No(t.handshake(conn).await?), + MaybeTLSTransport::Yes(t) => MaybeTLSStream::Yes(t.handshake(conn).await?), }; let wsstream = accept_async_with_config(tsream, Some(self.conf)).await?; let tun = WebsocketTunnel { @@ -240,8 +169,8 @@ impl Transport for WebsocketTransport { let u = format!("ws://{}", &addr.addr.as_str()); let url = Url::parse(&u).unwrap(); let tstream = match &self.sub { - SubTransport::Insecure(t) => TransportStream::Insecure(t.connect(addr).await?), - SubTransport::Secure(t) => TransportStream::Secure(t.connect(addr).await?), + MaybeTLSTransport::No(t) => MaybeTLSStream::No(t.connect(addr).await?), + MaybeTLSTransport::Yes(t) => MaybeTLSStream::Yes(t.connect(addr).await?), }; let (wsstream, _) = client_async_with_config(url, tstream, Some(self.conf)) .await diff --git a/tests/for_tcp/http2_tls_transport.toml b/tests/for_tcp/http2_tls_transport.toml new file mode 100644 index 00000000..c5de8a19 --- /dev/null +++ b/tests/for_tcp/http2_tls_transport.toml @@ -0,0 +1,33 @@ +[client] +remote_addr = "127.0.0.1:2333" +default_token = "default_token_if_not_specify" + +[client.transport] +type = "http2" +[client.transport.tls] +trusted_root = "examples/tls/rootCA.crt" +hostname = "localhost" +[client.transport.http2] +tls = true + +[client.services.echo] +local_addr = "127.0.0.1:8080" +[client.services.pingpong] +local_addr = "127.0.0.1:8081" + +[server] +bind_addr = "0.0.0.0:2333" +default_token = "default_token_if_not_specify" + +[server.transport] +type = "http2" +[server.transport.tls] +pkcs12 = "examples/tls/identity.pfx" +pkcs12_password = "1234" +[server.transport.http2] +tls = true + +[server.services.echo] +bind_addr = "0.0.0.0:2334" +[server.services.pingpong] +bind_addr = "0.0.0.0:2335" diff --git a/tests/for_tcp/http2_transport.toml b/tests/for_tcp/http2_transport.toml new file mode 100644 index 00000000..705e51bd --- /dev/null +++ b/tests/for_tcp/http2_transport.toml @@ -0,0 +1,27 @@ +[client] +remote_addr = "127.0.0.1:2333" +default_token = "default_token_if_not_specify" + +[client.transport] +type = "http2" +[client.transport.http2] +tls = false + +[client.services.echo] +local_addr = "127.0.0.1:8080" +[client.services.pingpong] +local_addr = "127.0.0.1:8081" + +[server] +bind_addr = "0.0.0.0:2333" +default_token = "default_token_if_not_specify" + +[server.transport] +type = "http2" +[server.transport.http2] +tls = false + +[server.services.echo] +bind_addr = "0.0.0.0:2334" +[server.services.pingpong] +bind_addr = "0.0.0.0:2335" diff --git a/tests/for_udp/http2_tls_transport.toml b/tests/for_udp/http2_tls_transport.toml new file mode 100644 index 00000000..6fd13090 --- /dev/null +++ b/tests/for_udp/http2_tls_transport.toml @@ -0,0 +1,37 @@ +[client] +remote_addr = "127.0.0.1:2332" +default_token = "default_token_if_not_specify" + +[client.transport] +type = "http2" +[client.transport.tls] +trusted_root = "examples/tls/rootCA.crt" +hostname = "localhost" +[client.transport.http2] +tls = true + +[client.services.echo] +type = "udp" +local_addr = "127.0.0.1:8080" +[client.services.pingpong] +type = "udp" +local_addr = "127.0.0.1:8081" + +[server] +bind_addr = "0.0.0.0:2332" +default_token = "default_token_if_not_specify" + +[server.transport] +type = "http2" +[server.transport.tls] +pkcs12 = "examples/tls/identity.pfx" +pkcs12_password = "1234" +[server.transport.http2] +tls = true + +[server.services.echo] +type = "udp" +bind_addr = "0.0.0.0:2334" +[server.services.pingpong] +type = "udp" +bind_addr = "0.0.0.0:2335" diff --git a/tests/for_udp/http2_transport.toml b/tests/for_udp/http2_transport.toml new file mode 100644 index 00000000..e34b4254 --- /dev/null +++ b/tests/for_udp/http2_transport.toml @@ -0,0 +1,31 @@ +[client] +remote_addr = "127.0.0.1:2332" +default_token = "default_token_if_not_specify" + +[client.transport] +type = "http2" +[client.transport.http2] +tls = false + +[client.services.echo] +type = "udp" +local_addr = "127.0.0.1:8080" +[client.services.pingpong] +type = "udp" +local_addr = "127.0.0.1:8081" + +[server] +bind_addr = "0.0.0.0:2332" +default_token = "default_token_if_not_specify" + +[server.transport] +type = "http2" +[server.transport.http2] +tls = false + +[server.services.echo] +type = "udp" +bind_addr = "0.0.0.0:2334" +[server.services.pingpong] +type = "udp" +bind_addr = "0.0.0.0:2335" diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 7b5d408d..a6cb3c9c 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -65,11 +65,16 @@ async fn tcp() -> Result<()> { #[cfg(any(feature = "websocket-native-tls", feature = "websocket-rustls"))] test("tests/for_tcp/websocket_transport.toml", Type::Tcp).await?; - #[cfg(not(target_os = "macos"))] #[cfg(any(feature = "websocket-native-tls", feature = "websocket-rustls"))] test("tests/for_tcp/websocket_tls_transport.toml", Type::Tcp).await?; + #[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] + test("tests/for_tcp/http2_transport.toml", Type::Tcp).await?; + #[cfg(not(target_os = "macos"))] + #[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] + test("tests/for_tcp/http2_tls_transport.toml", Type::Tcp).await?; + Ok(()) } @@ -102,11 +107,16 @@ async fn udp() -> Result<()> { #[cfg(any(feature = "websocket-native-tls", feature = "websocket-rustls"))] test("tests/for_udp/websocket_transport.toml", Type::Udp).await?; - #[cfg(not(target_os = "macos"))] #[cfg(any(feature = "websocket-native-tls", feature = "websocket-rustls"))] test("tests/for_udp/websocket_tls_transport.toml", Type::Udp).await?; + #[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] + test("tests/for_udp/http2_transport.toml", Type::Udp).await?; + #[cfg(not(target_os = "macos"))] + #[cfg(any(feature = "http2-native-tls", feature = "http2-rustls"))] + test("tests/for_udp/http2_tls_transport.toml", Type::Udp).await?; + Ok(()) }