From 376feedce790009b76328f142fafbf58d9ddcd60 Mon Sep 17 00:00:00 2001 From: Trevor McMaster Date: Wed, 31 Jul 2024 15:18:08 -0700 Subject: [PATCH] Updated hyper and http (#237) * Updated cargo lock file to latest versions * Fixed clippy warnings * Updated dashmap to new release * Updated hyper and http in test_common - Major changes. Many of the utility functions have been moved to the new hyper-util - See https://hyper.rs/guides/1/upgrading/ * Updated root Cargo.toml to latest hyper and http - Broken build. Still more to go. * Updated root Cargo.toml to latest hyper and http - Broken build. Still more to go. * Updated code to handle hyper v1 and http v1 * Ignore clippy warning that breaks code if fixed as suggested * Updated hyper, http, and lock file to latest - Removed minor version constraint on hyper and http - Added approved license BSD-2 Clause to the deny.toml * Cleaned up code - Removed unneeded dependencies - Removed commented out code - Cleaned up BoxBody type in test_common --- Cargo.lock | 253 ++++++++++++++++++++++---------- Cargo.toml | 8 +- deny.toml | 1 + lib/config/Cargo.toml | 2 +- lib/test_common/Cargo.toml | 7 +- lib/test_common/test_common.rs | 58 +++++--- src/bin/test_server.rs | 2 +- src/lib.rs | 20 ++- src/request.rs | 35 +++-- src/request/request_maker.rs | 34 ++--- src/request/response_handler.rs | 9 +- src/util.rs | 1 + tests/integration.rs | 2 +- 13 files changed, 286 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10dc7ac7..72f3036d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,7 +33,7 @@ dependencies = [ "getrandom", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -83,9 +83,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -98,33 +98,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -136,6 +136,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.3.0" @@ -229,15 +235,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" [[package]] name = "cc" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" [[package]] name = "cfg-if" @@ -281,9 +287,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.9" +version = "4.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" +checksum = "c53aa12ec67affac065e7c7dd20a42fa2a4094921b655711d5d3107bb3d52bed" dependencies = [ "clap_builder", "clap_derive", @@ -291,9 +297,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.9" +version = "4.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" +checksum = "efbdf2dd5fe10889e0c61942ff5d948aaf12fd0b4504408ab0cbb1916c2cffa9" dependencies = [ "anstyle", "clap_lex", @@ -302,9 +308,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.8" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" dependencies = [ "heck", "proc-macro2", @@ -314,15 +320,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "concurrent-queue" @@ -520,9 +526,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", "regex", @@ -539,9 +545,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -775,15 +781,15 @@ checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "h2" -version = "0.3.26" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", "indexmap", "slab", @@ -850,9 +856,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "http" -version = "0.2.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -861,12 +867,24 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", +] + +[[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", + "http-body", "pin-project-lite", ] @@ -890,13 +908,12 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", "http", @@ -905,24 +922,45 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -970,9 +1008,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -1115,13 +1153,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1181,21 +1220,11 @@ 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", - "libc", -] - [[package]] name = "object" -version = "0.36.1" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ "memchr", ] @@ -1353,15 +1382,17 @@ dependencies = [ "config", "csv", "ctrlc", - "env_logger 0.11.3", + "env_logger 0.11.5", "ether", "for_each_parallel", "futures", "futures-timer", "hdrhistogram", "http", + "http-body-util", "hyper", "hyper-tls", + "hyper-util", "itertools", "json_env_logger", "log", @@ -1384,6 +1415,26 @@ dependencies = [ "zip_all", ] +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1404,9 +1455,12 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +dependencies = [ + "zerocopy 0.6.6", +] [[package]] name = "proc-macro2" @@ -1612,12 +1666,13 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "indexmap", "itoa", + "memchr", "ryu", "serde", ] @@ -1747,9 +1802,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.71" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -1782,10 +1837,13 @@ dependencies = [ name = "test_common" version = "0.1.0" dependencies = [ + "bytes", "futures", "futures-timer", "http", + "http-body-util", "hyper", + "hyper-util", "log", "parking_lot", "tokio", @@ -1829,28 +1887,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.1" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", @@ -1892,6 +1949,27 @@ dependencies = [ "tokio", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2029,9 +2107,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[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 = "want" @@ -2288,13 +2366,34 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +[[package]] +name = "zerocopy" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive 0.6.6", +] + [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5ad4cb0f..86e9ae06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,9 +32,11 @@ for_each_parallel = { path = "./lib/for_each_parallel" } futures = "0.3" futures-timer = "3" hdrhistogram = "7" -http = "0.2" -hyper = { version = "0.14", features = ["client", "http1", "http2", "stream"] } -hyper-tls = "0.5" +http = "1" +hyper = { version = "1", features = ["client", "http1", "http2"] } +hyper-tls = "0.6" +hyper-util = { version = "0.1", features = ["tokio", "client", "http1", "http2"] } +http-body-util = "0.1" itertools = "0.13" mod_interval = { path = "./lib/mod_interval" } native-tls = "0.2" diff --git a/deny.toml b/deny.toml index 8133f462..0d1290cc 100644 --- a/deny.toml +++ b/deny.toml @@ -23,6 +23,7 @@ private = { ignore = true } version = 2 allow = [ "Apache-2.0", + "BSD-2-Clause", "BSD-3-Clause", "MIT", "Unicode-DFS-2016", diff --git a/lib/config/Cargo.toml b/lib/config/Cargo.toml index a2f98c13..1c8a3613 100644 --- a/lib/config/Cargo.toml +++ b/lib/config/Cargo.toml @@ -12,7 +12,7 @@ doctest = false base64 = "0.22" ether = { path = "../either" } futures = "0.3" -http = "0.2" +http = "1" itertools = "0.13" jsonpath_lib = "0.3.0" percent-encoding = "2" diff --git a/lib/test_common/Cargo.toml b/lib/test_common/Cargo.toml index c6697fca..c7cf8760 100644 --- a/lib/test_common/Cargo.toml +++ b/lib/test_common/Cargo.toml @@ -10,10 +10,13 @@ doctest = false path = "test_common.rs" [dependencies] +bytes = "1" futures = "0.3" futures-timer = "3" -hyper = { version = "0.14", features = ["server"] } -http = "0.2" +hyper = { version = "1", features = ["http1", "http2"] } +hyper-util = { version = "0.1", features = ["tokio", "server", "http1", "http2"] } +http = "1" +http-body-util = "0.1" parking_lot = "0.12" tokio = { version = "1", features = ["full"] } url = "2" diff --git a/lib/test_common/test_common.rs b/lib/test_common/test_common.rs index 885949f0..1fb0a036 100644 --- a/lib/test_common/test_common.rs +++ b/lib/test_common/test_common.rs @@ -1,18 +1,23 @@ use log::{debug, info}; -use std::{future::Future, io, str::FromStr, sync::Arc, time::Duration}; +use std::{future::Future, io, net::SocketAddr, str::FromStr, sync::Arc, time::Duration}; +use tokio::net::TcpListener; +use bytes::Bytes; use futures::{channel::oneshot, future::select, FutureExt}; use futures_timer::Delay; use http::{header, StatusCode}; -use hyper::{ - server::conn::AddrStream, - service::{make_service_fn, service_fn}, - Body, Error, Request, Response, Server, +use http_body_util::{BodyExt, Empty}; +use hyper::{body::Incoming as Body, service::service_fn, Error, Request, Response}; +use hyper_util::{ + rt::{TokioExecutor, TokioIo}, + server::conn::auto::Builder as HyperBuilder, }; use parking_lot::Mutex; use url::Url; -async fn echo_route(req: Request) -> Response { +type HyperBody = http_body_util::combinators::BoxBody; + +async fn echo_route(req: Request) -> Response { let headers = req.headers(); let content_type = headers .get(header::CONTENT_TYPE) @@ -36,24 +41,24 @@ async fn echo_route(req: Request) -> Response { if echo.is_some() { debug!("Echo Body = {}", echo.clone().unwrap_or_default()); } - let mut response = match (req.method(), echo) { + let mut response: Response = match (req.method(), echo) { (&http::Method::GET, Some(b)) => Response::builder() .status(StatusCode::OK) .header(header::CONTENT_TYPE, content_type) - .body(b.into()) + .body(b.map_err(|never| match never {}).boxed()) .unwrap(), (&http::Method::POST, _) | (&http::Method::PUT, _) => Response::builder() .status(StatusCode::OK) .header(header::CONTENT_TYPE, content_type) - .body(req.into_body()) + .body(req.into_body().boxed()) .unwrap(), _ => Response::builder() .status(StatusCode::NO_CONTENT) - .body(Body::empty()) + .body(empty()) .unwrap(), }; let ms = wait.and_then(|c| FromStr::from_str(&c).ok()).unwrap_or(0); - let old_body = std::mem::replace(response.body_mut(), Body::empty()); + let old_body = std::mem::replace(response.body_mut(), empty()); if ms > 0 { debug!("waiting {} ms", ms); } @@ -62,13 +67,22 @@ async fn echo_route(req: Request) -> Response { response } -pub fn start_test_server( +fn empty() -> HyperBody { + Empty::::new() + .map_err(|never| match never {}) + .boxed() +} + +pub async fn start_test_server( port: Option, ) -> (u16, oneshot::Sender<()>, impl Future) { let port = port.unwrap_or(0); - let address = ([127, 0, 0, 1], port).into(); + let address: SocketAddr = ([127, 0, 0, 1], port).into(); + + let listener = TcpListener::bind(address).await.unwrap(); + let local_addr = listener.local_addr().unwrap(); - let make_svc = make_service_fn(|_: &AddrStream| async { + let server = tokio::spawn(async move { let service = service_fn(|req: Request| async { debug!("{:?}", req); let method = req.method().to_string(); @@ -78,7 +92,7 @@ pub fn start_test_server( "/" => echo_route(req).await, _ => Response::builder() .status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(empty()) .unwrap(), }; debug!("{:?}", response); @@ -92,14 +106,20 @@ pub fn start_test_server( ); Ok::<_, Error>(response) }); - Ok::<_, Error>(service) + + loop { + let (stream, _) = listener.accept().await.unwrap(); + let stream = TokioIo::new(stream); + tokio::task::spawn(async move { + let builder = HyperBuilder::new(TokioExecutor::new()); + builder.serve_connection(stream, service).await.unwrap(); + }); + } }); let (tx, rx) = oneshot::channel(); - let server = Server::bind(&address).serve(make_svc); - - let port = server.local_addr().port(); + let port = local_addr.port(); let future = select(server, rx); diff --git a/src/bin/test_server.rs b/src/bin/test_server.rs index 86f58fcd..65278eac 100644 --- a/src/bin/test_server.rs +++ b/src/bin/test_server.rs @@ -8,7 +8,7 @@ fn main() { rt.block_on(async { let port = std::env::var("PORT").ok().and_then(|s| s.parse().ok()); debug!("port = {}", port.unwrap_or_default()); - let (port, rx, handle) = start_test_server(port); + let (port, rx, handle) = start_test_server(port).await; println!("Listening on port {port}"); diff --git a/src/lib.rs b/src/lib.rs index 7c1235b0..f7251590 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,8 +26,15 @@ use futures::{ stream, FutureExt, Stream, StreamExt, }; use futures_timer::Delay; -use hyper::{client::HttpConnector, Body, Client}; +use http_body_util::combinators::BoxBody; use hyper_tls::HttpsConnector; +use hyper_util::{ + client::legacy::{ + connect::{dns::GaiResolver, HttpConnector}, + Client, + }, + rt::TokioExecutor, +}; use itertools::Itertools; use line_writer::{blocking_writer, MsgType}; use log::{debug, error, info, warn}; @@ -57,6 +64,8 @@ use std::{ time::{Duration, Instant}, }; +type Body = BoxBody; + struct Endpoints { // yaml index of the endpoint, (endpoint tags, builder) inner: Vec<( @@ -1139,16 +1148,15 @@ fn create_load_test_future( pub(crate) fn create_http_client( keepalive: Duration, -) -> Result< - Client>>, - TestError, -> { +) -> Result>, Body>, TestError> { let mut http = HttpConnector::new(); http.set_keepalive(Some(keepalive)); http.set_reuse_address(true); http.enforce_http(false); let https = HttpsConnector::from((http, TlsConnector::new()?.into())); - Ok(Client::builder().set_host(false).build::<_, Body>(https)) + Ok(Client::builder(TokioExecutor::new()) + .set_host(false) + .build::<_, Body>(https)) } type ProvidersResult = Result<(BTreeMap, BTreeSet), TestError>; diff --git a/src/request.rs b/src/request.rs index 2fe60f44..a254d7ac 100644 --- a/src/request.rs +++ b/src/request.rs @@ -18,12 +18,16 @@ use futures::{ sink::SinkExt, stream, FutureExt, Stream, StreamExt, TryFutureExt, TryStreamExt, }; +use http_body_util::{combinators::BoxBody, BodyExt, StreamBody}; use hyper::{ - client::HttpConnector, header::{Entry as HeaderEntry, HeaderName, HeaderValue, CONTENT_DISPOSITION}, - Body as HyperBody, Client, Method, Response, + Method, Response, }; use hyper_tls::HttpsConnector; +use hyper_util::client::legacy::{ + connect::{dns::GaiResolver, HttpConnector}, + Client, +}; use rand::distributions::{Alphanumeric, Distribution}; use select_any::select_any; use serde_json as json; @@ -55,6 +59,8 @@ use std::{ time::{Duration, Instant}, }; +type HyperBody = BoxBody; + #[derive(Clone)] pub struct AutoReturn { send_option: EndpointProvidesSendOptions, @@ -203,8 +209,7 @@ pub struct BuilderContext { #[allow(dead_code)] pub config_path: PathBuf, // the http client - pub client: - Arc>>>, + pub client: Arc>, HyperBody>>, // a mapping of names to their prospective providers pub providers: Arc>, // a mapping of names to their prospective loggers @@ -498,7 +503,7 @@ fn multipart_body_as_hyper_body( let piece_stream = future::ok(Bytes::from(piece_data)).into_stream(); tweak_path(&mut body, &multipart_body.path); let a = create_file_hyper_body(body).map_ok(move |(bytes, body)| { - let stream = piece_stream.chain(body).a(); + let stream = piece_stream.chain(body.into_data_stream()).a(); (bytes + piece_data_bytes, stream) }); Either::A(a) @@ -539,7 +544,9 @@ fn multipart_body_as_hyper_body( .flatten() .chain(stream::once(future::ok(closing_boundary))); - (bytes, HyperBody::wrap_stream(stream)) + let body: HyperBody = + BodyExt::boxed(StreamBody::new(stream.map_ok(hyper::body::Frame::data))); + (bytes, body) }); Ok(ret) } @@ -569,7 +576,9 @@ async fn create_file_hyper_body(filename: String) -> Result<(u64, HyperBody), Te } }); - let body = HyperBody::wrap_stream(stream); + let body: HyperBody = BodyExt::boxed(StreamBody::new( + stream.map_ok(|x| hyper::body::Frame::data(x.into())), + )); Ok((bytes, body)) } @@ -592,7 +601,7 @@ fn body_template_as_hyper_body( ); return Either3::A(future::ready(r).and_then(|x| x)); } - BodyTemplate::None => return Either3::B(future::ok((0, HyperBody::empty()))), + BodyTemplate::None => return Either3::B(future::ok((0, BoxBody::default()))), BodyTemplate::String(t) => t, }; let mut body = match template.evaluate(Cow::Borrowed(template_values.as_json()), None) { @@ -609,7 +618,10 @@ fn body_template_as_hyper_body( if copy_body_value { *body_value = Some(body.clone()); } - Either3::B(future::ok((body.as_bytes().len() as u64, body.into()))) + Either3::B(future::ok(( + body.as_bytes().len() as u64, + body.map_err(|never| match never {}).boxed(), + ))) } } @@ -622,7 +634,7 @@ pub type StatsTx = futures_channel::UnboundedSender; pub struct Endpoint { body: BodyTemplate, - client: Arc>>>, + client: Arc>, HyperBody>>, headers: Vec<(String, Template)>, max_parallel_requests: Option, method: Method, @@ -919,7 +931,8 @@ mod tests { let (_, body) = create_file_hyper_body("tests/test.jpg".to_string()) .await .unwrap(); - body.map(|b| stream::iter(b.unwrap())) + body.into_data_stream() + .map(|b| stream::iter(b.unwrap())) .flatten() .collect::>() .await diff --git a/src/request/request_maker.rs b/src/request/request_maker.rs index c3ad7369..764654cf 100644 --- a/src/request/request_maker.rs +++ b/src/request/request_maker.rs @@ -11,12 +11,16 @@ use futures::{ FutureExt, TryFutureExt, }; use futures_timer::Delay; +use http_body_util::{combinators::BoxBody, BodyExt}; use hyper::{ - client::HttpConnector, header::{HeaderMap, HeaderName, HeaderValue, CONTENT_LENGTH, CONTENT_TYPE, HOST}, - Client, Method, Request, + Method, Request, }; use hyper_tls::HttpsConnector; +use hyper_util::client::legacy::{ + connect::{dns::GaiResolver, HttpConnector}, + Client, +}; use log::{debug, info}; use serde_json as json; @@ -41,8 +45,9 @@ pub(super) struct RequestMaker { pub(super) headers: Vec<(String, Template)>, pub(super) body: BodyTemplate, pub(super) rr_providers: u16, - pub(super) client: - Arc>>>, + pub(super) client: Arc< + Client>, BoxBody>, + >, pub(super) stats_tx: StatsTx, pub(super) no_auto_returns: bool, pub(super) outgoing: Arc>, @@ -279,21 +284,7 @@ impl RequestMaker { request.headers_mut().extend(headers); let mut response_future = client.request(request).map_err(|e| { - let err: Arc = if let Some(io_error_maybe) = e.source() - { - if io_error_maybe.downcast_ref::().is_some() { - let io_error = e.into_cause().expect("should have a cause error"); - Arc::new( - *io_error - .downcast::() - .expect("should downcast as io error"), - ) - } else { - Arc::new(e) - } - } else { - Arc::new(e) - }; + let err: Arc = Arc::new(e); TestError::from(RecoverableError::ConnectionErr(SystemTime::now(), err)) }); let outgoing2 = outgoing.clone(); @@ -327,7 +318,8 @@ impl RequestMaker { stats_tx, tags, }; - rh.handle(response, auto_returns) + // Convert from a Response to a Response to pass to handle() + rh.handle(hyper::Response::new(response.into_body().boxed().map_err(std::io::Error::other).boxed()), auto_returns) .map_err(TestError::from) }) .or_else(move |r| { @@ -401,7 +393,7 @@ mod tests { fn sends_request() { let rt = Runtime::new().unwrap(); rt.block_on(async move { - let (port, ..) = test_common::start_test_server(None); + let (port, ..) = test_common::start_test_server(None).await; let url = Template::simple(&format!("https://127.0.0.1:{}", port)); let method = Method::GET; let headers = Vec::new(); diff --git a/src/request/response_handler.rs b/src/request/response_handler.rs index a70f1112..0062fe30 100644 --- a/src/request/response_handler.rs +++ b/src/request/response_handler.rs @@ -2,6 +2,7 @@ use super::*; use config::{RESPONSE_BODY, RESPONSE_HEADERS, RESPONSE_HEADERS_ALL, RESPONSE_STARTLINE, STATS}; use futures::TryStreamExt; +use http_body_util::{combinators::BoxBody, BodyExt}; pub(super) struct ResponseHandler { pub(super) provider_delays: ProviderDelays, @@ -19,7 +20,7 @@ impl ResponseHandler { // https://github.com/rust-lang/rust/issues/71723 pub(super) fn handle( self, - response: hyper::Response, + response: hyper::Response>, auto_returns: Option, ) -> impl Future> where @@ -86,7 +87,7 @@ impl ResponseHandler { ) { (true, Some(ce)) => { let body = response - .into_body() + .into_data_stream() .map_err(|e| RecoverableError::BodyErr(Arc::new(e))); let br = body_reader::BodyReader::new(ce); let body_buffer = bytes::BytesMut::new(); @@ -109,7 +110,7 @@ impl ResponseHandler { _ => { // when we don't need the body, skip parsing it, but make sure we get it all response - .into_body() + .into_data_stream() .map_err(|e| RecoverableError::BodyErr(Arc::new(e))) .try_fold((), |_, _| future::ok(())) .map_ok(|_| None) @@ -143,7 +144,7 @@ fn handle_response_requirements( bitwise: u16, response_fields_added: &mut u16, rp: &mut json::map::Map, - response: &Response, + response: &Response>, ) { // check if we need the response startline and it hasn't already been set if ((bitwise & RESPONSE_STARTLINE) ^ (*response_fields_added & RESPONSE_STARTLINE)) != 0 { diff --git a/src/util.rs b/src/util.rs index d8d5cc5a..3efdc369 100644 --- a/src/util.rs +++ b/src/util.rs @@ -14,6 +14,7 @@ pub fn json_value_to_string(v: Cow<'_, json::Value>) -> Cow<'_, String> { } } +#[allow(clippy::needless_borrows_for_generic_args)] pub fn tweak_path(rest: &mut String, base: &Path) { *rest = base.with_file_name(&rest).to_string_lossy().into(); } diff --git a/tests/integration.rs b/tests/integration.rs index 6f07b6ae..3c37ae25 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -7,7 +7,7 @@ use tokio::runtime::Runtime; fn run_test(path: &str) -> (bool, String, String) { let rt = Runtime::new().unwrap(); rt.block_on(async move { - let (port, kill_server, _) = start_test_server(None); + let (port, kill_server, _) = start_test_server(None).await; env::set_var("PORT", port.to_string()); let (_, ctrlc_channel) = futures::channel::mpsc::unbounded();