diff --git a/Cargo.lock b/Cargo.lock index e08e07da9d0..b86550b81ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -232,14 +232,18 @@ dependencies = [ [[package]] name = "async-tungstenite" -version = "0.23.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e9efbe14612da0a19fb983059a0b621e9cf6225d7018ecab4f9988215540dc" +checksum = "2cca750b12e02c389c1694d35c16539f88b8bbaa5945934fdc1b41a776688589" dependencies = [ "futures-io", "futures-util", "log 0.4.21", "pin-project-lite", + "rustls-native-certs", + "rustls-pki-types", + "tokio 1.37.0", + "tokio-rustls", "tungstenite", ] @@ -1112,9 +1116,9 @@ dependencies = [ [[package]] name = "cynic" -version = "3.4.3" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7335114540697c7b1c1a0131cbe0e983fdb1e646f881234afe9e2a66133ac99a" +checksum = "ae6b0725e67c937e2005f05c6da426f3a490a1f36e76f87cdfba8ea3c895133f" dependencies = [ "cynic-proc-macros", "ref-cast", @@ -1127,9 +1131,9 @@ dependencies = [ [[package]] name = "cynic-codegen" -version = "3.7.1" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5911792b771d9fd7985f489536adeb6f022070dc41517654df18c3bac675ac" +checksum = "0f3f1953f4590381034d75c49a568665567f19ee393d4292835d35bac9724dca" dependencies = [ "counter", "cynic-parser", @@ -1145,9 +1149,9 @@ dependencies = [ [[package]] name = "cynic-parser" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d196e12521c50222a8657924f5430859626379153e920cbff7083ed026cfe6be" +checksum = "7b9f36eeb1107059bea01cc5db8492737c98e9fdf570f909846b8c9fc274aa94" dependencies = [ "indexmap 2.2.6", "lalrpop-util", @@ -1156,9 +1160,9 @@ dependencies = [ [[package]] name = "cynic-proc-macros" -version = "3.7.1" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cdb3ccebd080e369bd52a747118609807fa213c287d9d38c26209a441b78acc" +checksum = "d8c91cdcec0d56aedd760f3cec277a7d2f43c52c9a6d61cb7852be38a2fc8426" dependencies = [ "cynic-codegen", "darling 0.20.9", @@ -1499,7 +1503,7 @@ dependencies = [ "time 0.3.36", "url", "uuid", - "wcgi-host", + "wcgi-host 0.1.2", ] [[package]] @@ -1523,7 +1527,7 @@ dependencies = [ "time 0.3.36", "url", "uuid", - "wcgi-host", + "wcgi-host 0.1.2", ] [[package]] @@ -1533,7 +1537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60d06780ae676369e0a9ac2c75f7d1a6d22e157ef5b10cfeda0ee6a465cf7337" dependencies = [ "edge-schema 0.0.3", - "http", + "http 0.2.12", "serde", "wasmparser 0.121.2", ] @@ -1562,15 +1566,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "enum-iterator" version = "0.7.0" @@ -2000,11 +1995,11 @@ dependencies = [ [[package]] name = "graphql-ws-client" -version = "0.6.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0063064d93204da0f0baf4dc0e03bf8a9307f6924a37e604b912a63b08aa7ea" +checksum = "db7802310624d21a55797a3bc442dbe405424e9b2c967f86fb415634976f9a97" dependencies = [ - "async-tungstenite", + "async-trait", "futures 0.3.30", "graphql_client", "log 0.4.21", @@ -2012,7 +2007,7 @@ dependencies = [ "serde", "serde_json", "thiserror", - "uuid", + "tungstenite", ] [[package]] @@ -2074,25 +2069,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes 1.6.1", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.2.6", - "slab", - "tokio 1.37.0", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "1.8.3" @@ -2235,22 +2211,39 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes 1.6.1", + "fnv", + "itoa", +] + [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes 1.6.1", - "http", - "pin-project-lite", + "http 1.1.0", ] [[package]] -name = "http-range-header" -version = "0.3.1" +name = "http-body-util" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes 1.6.1", + "futures-core", + "http 1.1.0", + "http-body", + "pin-project-lite", +] [[package]] name = "http-serde" @@ -2258,7 +2251,17 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f560b665ad9f1572cfcaf034f7fb84338a7ce945216d64a90fd81f046a3caee" dependencies = [ - "http", + "http 0.2.12", + "serde", +] + +[[package]] +name = "http-serde" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f056c8559e3757392c8d091e796416e4649d8e49e88b8d76df6c002f05027fd" +dependencies = [ + "http 1.1.0", "serde", ] @@ -2282,68 +2285,92 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes 1.6.1", "futures-channel", - "futures-core", "futures-util", - "h2", - "http", + "http 1.1.0", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "smallvec 1.13.2", "tokio 1.37.0", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http", + "http 1.1.0", "hyper", - "rustls 0.21.12", + "hyper-util", + "rustls", + "rustls-pki-types", "tokio 1.37.0", "tokio-rustls", + "tower-service", ] [[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 1.6.1", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio 1.37.0", "tokio-native-tls", + "tower-service", ] [[package]] name = "hyper-tungstenite" -version = "0.11.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc7dcb1ab67cd336f468a12491765672e61a3b6b148634dbfe2fe8acd3fe7d9" +checksum = "7a343d17fe7885302ed7252767dc7bb83609a874b6ff581142241ec4b73957ad" dependencies = [ + "http-body-util", "hyper", + "hyper-util", "pin-project-lite", "tokio 1.37.0", "tokio-tungstenite", "tungstenite", ] +[[package]] +name = "hyper-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +dependencies = [ + "bytes 1.6.1", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body", + "hyper", + "pin-project-lite", + "socket2 0.5.7", + "tokio 1.37.0", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -2808,32 +2835,33 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "logos" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +checksum = "8e31badd9de5131fdf4921f6473d457e3dd85b11b7f091ceb50e4df7c3eeb12a" dependencies = [ "beef", "fnv", + "lazy_static", "proc-macro2", "quote", - "regex-syntax 0.6.29", + "regex-syntax 0.8.3", "syn 2.0.64", ] [[package]] name = "logos-derive" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a" dependencies = [ "logos-codegen", ] @@ -3963,22 +3991,23 @@ checksum = "e3a8614ee435691de62bcffcf4a66d91b3594bf1428a5722e79103249a095690" [[package]] name = "reqwest" -version = "0.11.27" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ "async-compression", - "base64 0.21.7", + "base64 0.22.1", "bytes 1.6.1", - "encoding_rs", + "futures-channel", "futures-core", "futures-util", - "h2", - "http", + "http 1.1.0", "http-body", + "http-body-util", "hyper", "hyper-rustls", "hyper-tls", + "hyper-util", "ipnet", "js-sys", "log 0.4.21", @@ -3988,13 +4017,13 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.12", + "rustls", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio 1.37.0", "tokio-native-tls", "tokio-rustls", @@ -4006,7 +4035,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.25.4", + "webpki-roots", "winreg", ] @@ -4176,18 +4205,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log 0.4.21", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - [[package]] name = "rustls" version = "0.22.4" @@ -4197,30 +4214,32 @@ dependencies = [ "log 0.4.21", "ring", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", "rustls-pemfile", + "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", + "rustls-pki-types", ] [[package]] @@ -4229,16 +4248,6 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.102.4" @@ -4398,16 +4407,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "seahash" version = "4.1.0" @@ -4487,9 +4486,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -4526,9 +4525,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -4868,27 +4867,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tap" version = "1.0.1" @@ -5290,11 +5268,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.21.12", + "rustls", + "rustls-pki-types", "tokio 1.37.0", ] @@ -5395,18 +5374,19 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log 0.4.21", - "rustls 0.21.12", + "rustls", "rustls-native-certs", + "rustls-pki-types", "tokio 1.37.0", "tokio-rustls", "tungstenite", - "webpki-roots 0.25.4", + "webpki-roots", ] [[package]] @@ -5542,17 +5522,16 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "bitflags 2.5.0", "bytes 1.6.1", - "futures-core", "futures-util", - "http", + "http 1.1.0", "http-body", - "http-range-header", + "http-body-util", "pin-project-lite", "tower", "tower-layer", @@ -5716,18 +5695,19 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes 1.6.1", "data-encoding", - "http", + "http 1.1.0", "httparse", "log 0.4.21", "rand", - "rustls 0.21.12", + "rustls", + "rustls-pki-types", "sha1", "thiserror", "url", @@ -5865,11 +5845,11 @@ dependencies = [ "flate2", "log 0.4.21", "once_cell", - "rustls 0.22.4", + "rustls", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki", "url", - "webpki-roots 0.26.1", + "webpki-roots", ] [[package]] @@ -5990,6 +5970,7 @@ dependencies = [ "futures-util", "hyper", "hyper-tungstenite", + "hyper-util", "libc", "mio 0.8.11", "pin-project-lite", @@ -6550,9 +6531,11 @@ dependencies = [ "futures 0.3.30", "futures-util", "hex", - "http", + "http 1.1.0", + "http-body-util", "humantime", "hyper", + "hyper-util", "indexmap 1.9.3", "indicatif", "interfaces", @@ -6911,6 +6894,7 @@ name = "wasmer-registry" version = "5.16.0" dependencies = [ "anyhow", + "async-tungstenite", "clap", "console", "dialoguer", @@ -7039,8 +7023,10 @@ dependencies = [ "getrandom", "heapless", "hex", - "http", + "http 1.1.0", + "http-body-util", "hyper", + "hyper-util", "js-sys", "lazy_static", "libc", @@ -7092,8 +7078,8 @@ dependencies = [ "wasmer-journal", "wasmer-types", "wasmer-wasix-types", - "wcgi", - "wcgi-host", + "wcgi 0.2.0", + "wcgi-host 0.2.0", "web-sys", "webc", "weezl", @@ -7268,8 +7254,21 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ca8f334eec3a8197bd25a612c74f415b8691d219ee11f1acd20f15a3e2bf77" dependencies = [ - "http", - "http-serde", + "http 0.2.12", + "http-serde 1.1.3", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "wcgi" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b51540185fb0764ba68176a955c9530f8f7501b418b034e30607f892fec261b2" +dependencies = [ + "http 1.1.0", + "http-serde 2.1.1", "serde", "serde_json", "url", @@ -7281,12 +7280,25 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a762cf2b0ed389a2a2fb591d63a398c1a4c0f8bef938cfd040285a3c63b695cc" dependencies = [ - "http", + "http 0.2.12", "schemars", "serde", "tokio 1.37.0", "wasmparser 0.95.0", - "wcgi", + "wcgi 0.1.2", +] + +[[package]] +name = "wcgi-host" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfc134be64da186b33675e0154827ba8eb4eb30579c1142cebec88607cd2cf6" +dependencies = [ + "http 1.1.0", + "serde", + "tokio 1.37.0", + "wasmparser 0.95.0", + "wcgi 0.2.0", ] [[package]] @@ -7333,12 +7345,6 @@ dependencies = [ "wasmer-config 0.2.0", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.1" @@ -7619,9 +7625,9 @@ dependencies = [ [[package]] name = "winreg" -version = "0.50.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ "cfg-if 1.0.0", "windows-sys 0.48.0", diff --git a/Cargo.toml b/Cargo.toml index 532a7e18dfe..f8b66453666 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,6 +97,9 @@ edge-schema = { version = "=0.1.0" } shared-buffer = "0.1.4" # Third-party crates +http = "1.0.0" +hyper = "1" +reqwest = { version = "0.12.0", default-features = false } enumset = "1.1.0" memoffset = "0.9.0" wasmparser = { version = "0.121.0", default-features = false } diff --git a/lib/api/src/sys/tunables.rs b/lib/api/src/sys/tunables.rs index df63e3b1d80..45f9225adfe 100644 --- a/lib/api/src/sys/tunables.rs +++ b/lib/api/src/sys/tunables.rs @@ -69,8 +69,7 @@ mod tests { impl VMTinyMemory { pub fn new() -> Result { let sz = 18 * WASM_PAGE_SIZE; - let mut memory = Vec::new(); - memory.resize(sz, 0); + let memory = vec![0; sz]; let mut ret = Self { mem: memory, memory_definition: None, @@ -304,6 +303,7 @@ mod tests { all(target_os = "macos", target_arch = "aarch64") )) ))] + #[allow(clippy::print_stdout)] fn check_small_stack() -> Result<(), Box> { use crate::{imports, wat2wasm, Engine, Instance, Module, Store}; use wasmer_compiler_singlepass::Singlepass; diff --git a/lib/backend-api/Cargo.toml b/lib/backend-api/Cargo.toml index bc43db9bd0f..6a6212cab41 100644 --- a/lib/backend-api/Cargo.toml +++ b/lib/backend-api/Cargo.toml @@ -28,11 +28,11 @@ serde_json = "1" url = "2" futures = "0.3" tracing = "0.1" -cynic = { version = "=3.4.3", features = ["http-reqwest"] } +cynic = { version = "3.7.2", features = ["http-reqwest"] } pin-project-lite = "0.2.10" serde_path_to_error = "0.1.14" harsh = "0.2.2" -reqwest = { version = "0.11.13", default-features = false, features = ["json"] } +reqwest = { workspace = true, default-features = false, features = ["json"] } merge-streams = "0.1.2" [target.'cfg(target_family = "wasm")'.dependencies.getrandom] diff --git a/lib/c-api/examples/wasmer-capi-examples-runner/src/lib.rs b/lib/c-api/examples/wasmer-capi-examples-runner/src/lib.rs index e8f2faba8df..ace57150b11 100644 --- a/lib/c-api/examples/wasmer-capi-examples-runner/src/lib.rs +++ b/lib/c-api/examples/wasmer-capi-examples-runner/src/lib.rs @@ -375,30 +375,30 @@ fn test_run() { } } -#[cfg(test)] -fn print_wasmer_root_to_stdout(config: &Config) { - println!("print_wasmer_root_to_stdout"); - - use walkdir::WalkDir; - - for entry in WalkDir::new(&config.wasmer_dir) - .into_iter() - .filter_map(Result::ok) - { - let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); - println!("{f_name}"); - } - - for entry in WalkDir::new(&config.root_dir) - .into_iter() - .filter_map(Result::ok) - { - let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); - println!("{f_name}"); - } - - println!("printed"); -} +// #[cfg(test)] +// fn print_wasmer_root_to_stdout(config: &Config) { +// println!("print_wasmer_root_to_stdout"); + +// use walkdir::WalkDir; + +// for entry in WalkDir::new(&config.wasmer_dir) +// .into_iter() +// .filter_map(Result::ok) +// { +// let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); +// println!("{f_name}"); +// } + +// for entry in WalkDir::new(&config.root_dir) +// .into_iter() +// .filter_map(Result::ok) +// { +// let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); +// println!("{f_name}"); +// } + +// println!("printed"); +// } #[cfg(test)] fn fixup_symlinks( diff --git a/lib/c-api/tests/wasmer-c-api-test-runner/src/lib.rs b/lib/c-api/tests/wasmer-c-api-test-runner/src/lib.rs index ffa648206ef..5abe14c39ef 100644 --- a/lib/c-api/tests/wasmer-c-api-test-runner/src/lib.rs +++ b/lib/c-api/tests/wasmer-c-api-test-runner/src/lib.rs @@ -316,46 +316,46 @@ fn test_ok() { } } -#[cfg(test)] -fn print_wasmer_root_to_stdout(config: &Config) { - println!("print_wasmer_root_to_stdout"); - - use walkdir::WalkDir; - - println!( - "wasmer dir: {}", - std::path::Path::new(&config.wasmer_dir) - .canonicalize() - .unwrap() - .display() - ); - - for entry in WalkDir::new(&config.wasmer_dir) - .into_iter() - .filter_map(Result::ok) - { - let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); - println!("{f_name}"); - } - - println!( - "root dir: {}", - std::path::Path::new(&config.root_dir) - .canonicalize() - .unwrap() - .display() - ); - - for entry in WalkDir::new(&config.root_dir) - .into_iter() - .filter_map(Result::ok) - { - let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); - println!("{f_name}"); - } - - println!("printed"); -} +// #[cfg(test)] +// fn print_wasmer_root_to_stdout(config: &Config) { +// println!("print_wasmer_root_to_stdout"); + +// use walkdir::WalkDir; + +// println!( +// "wasmer dir: {}", +// std::path::Path::new(&config.wasmer_dir) +// .canonicalize() +// .unwrap() +// .display() +// ); + +// for entry in WalkDir::new(&config.wasmer_dir) +// .into_iter() +// .filter_map(Result::ok) +// { +// let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); +// println!("{f_name}"); +// } + +// println!( +// "root dir: {}", +// std::path::Path::new(&config.root_dir) +// .canonicalize() +// .unwrap() +// .display() +// ); + +// for entry in WalkDir::new(&config.root_dir) +// .into_iter() +// .filter_map(Result::ok) +// { +// let f_name = String::from(entry.path().canonicalize().unwrap().to_string_lossy()); +// println!("{f_name}"); +// } + +// println!("printed"); +// } #[cfg(test)] fn fixup_symlinks( diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index 291fcd783ee..e7db84b559e 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -160,6 +160,7 @@ time01 = { package = "time", version = "0.1.45", optional = true } # Third-party dependencies. +http.workspace = true is-terminal = "0.4.7" colored = "2.0" anyhow = "1.0" @@ -206,8 +207,9 @@ once_cell = "1.17.1" indicatif = "0.17.5" opener = "0.6.1" normpath = "=1.1.1" -hyper = { version = "0.14.27", features = ["server"] } -http = "0.2.9" +hyper = { workspace = true, features = ["server"] } +hyper-util = { version = "0.1.5", features = ["tokio"] } +http-body-util = "0.1.1" futures = "0.3.29" humantime = "2.1.0" interfaces = { version = "0.0.9", optional = true } @@ -221,8 +223,9 @@ comfy-table = "7.0.1" # Used by tuntap and connect futures-util = "0.3" mio = { version = "0.8", optional = true } -tokio-tungstenite = { version = "0.20.1", features = [ +tokio-tungstenite = { version = "0.21.0", features = [ "rustls-tls-webpki-roots", + "stream", ], optional = true } mac_address = { version = "1.1.5", optional = true } tun-tap = { version = "0.1.3", features = ["tokio"], optional = true } @@ -248,7 +251,7 @@ clap = { version = "4.3.4", default-features = false, features = [ ] } [target.'cfg(not(target_arch = "riscv64"))'.dependencies] -reqwest = { version = "^0.11", default-features = false, features = [ +reqwest = { workspace = true, default-features = false, features = [ "rustls-tls", "json", "multipart", @@ -256,7 +259,7 @@ reqwest = { version = "^0.11", default-features = false, features = [ ] } [target.'cfg(target_arch = "riscv64")'.dependencies] -reqwest = { version = "^0.11", default-features = false, features = [ +reqwest = { workspace = true, default-features = false, features = [ "native-tls", "json", "multipart", diff --git a/lib/cli/src/commands/app/deploy.rs b/lib/cli/src/commands/app/deploy.rs index 449446369c7..865dcd86018 100644 --- a/lib/cli/src/commands/app/deploy.rs +++ b/lib/cli/src/commands/app/deploy.rs @@ -19,6 +19,11 @@ use wasmer_config::{ package::{PackageIdent, PackageSource}, }; +// TODO: apparently edge-util uses a different version of the http crate, which makes the +// HEADER_APP_VERSION_ID field incompatible with our use here, so it needs to be redeclared. +static EDGE_HEADER_APP_VERSION_ID: http::HeaderName = + http::HeaderName::from_static("x-edge-app-version-id"); + /// Deploy an app to Wasmer Edge. #[derive(clap::Parser, Debug)] pub struct CmdAppDeploy { @@ -669,7 +674,7 @@ pub async fn wait_app( Ok(res) => { let header = res .headers() - .get(edge_util::headers::HEADER_APP_VERSION_ID) + .get(&EDGE_HEADER_APP_VERSION_ID) .and_then(|x| x.to_str().ok()) .unwrap_or_default(); diff --git a/lib/cli/src/commands/login.rs b/lib/cli/src/commands/login.rs index a917de52304..e1040621ddb 100644 --- a/lib/cli/src/commands/login.rs +++ b/lib/cli/src/commands/login.rs @@ -1,16 +1,16 @@ -use std::{net::TcpListener, path::PathBuf, str::FromStr, time::Duration}; +use std::{path::PathBuf, str::FromStr, time::Duration}; use anyhow::Ok; use clap::Parser; use colored::Colorize; #[cfg(not(test))] use dialoguer::{console::style, Input}; -use hyper::{ - service::{make_service_fn, service_fn}, - Body, Request, Response, Server, StatusCode, -}; -use reqwest::Method; +use futures::{stream::FuturesUnordered, StreamExt}; +use http_body_util::BodyExt; +use hyper::{body::Incoming, service::service_fn, Request, Response, StatusCode}; +use reqwest::{Body, Method}; use serde::Deserialize; +use tokio::net::TcpListener; use wasmer_registry::{ types::NewNonceOutput, wasmer_env::{Registry, WasmerEnv, WASMER_DIR}, @@ -177,26 +177,40 @@ impl Login { ); }); - // Create a new server - let make_svc = make_service_fn(move |_| { - let context = app_context.clone(); + // Jump through hyper 1.0's hoops... + let graceful = hyper_util::server::graceful::GracefulShutdown::new(); - // Create a `Service` for responding to the request. - let service = service_fn(move |req| service_router(context.clone(), req)); + let http = hyper::server::conn::http1::Builder::new(); - // Return the service to hyper. - async move { Ok(service) } - }); + let mut futs = FuturesUnordered::new(); + + let service = service_fn(move |req| service_router(app_context.clone(), req)); print!("Waiting for session... "); // start the server - Server::from_tcp(listener)? - .serve(make_svc) - .with_graceful_shutdown(async { - server_shutdown_rx.recv().await; - }) - .await?; + loop { + tokio::select! { + Result::Ok((stream, _addr)) = listener.accept() => { + let io = hyper_util::rt::tokio::TokioIo::new(stream); + let conn = http.serve_connection(io, service.clone()); + // watch this connection + let fut = graceful.watch(conn); + futs.push(async move { + if let Err(e) = fut.await { + eprintln!("Error serving connection: {:?}", e); + } + }); + }, + + _ = futs.next() => {} + + _ = server_shutdown_rx.recv() => { + // stop the accept loop + break; + } + } + } // receive the token from the server let token = token_rx @@ -217,7 +231,7 @@ impl Login { } async fn setup_listener() -> Result<(TcpListener, String), anyhow::Error> { - let listener = TcpListener::bind("127.0.0.1:0")?; + let listener = TcpListener::bind("127.0.0.1:0").await?; let addr = listener.local_addr()?; let port = addr.port(); @@ -331,8 +345,7 @@ impl Login { } } -async fn preflight(req: Request) -> Result, anyhow::Error> { - let _whole_body = hyper::body::aggregate(req).await?; +async fn preflight(_: Request) -> Result, anyhow::Error> { let response = Response::builder() .status(StatusCode::OK) .header("Access-Control-Allow-Origin", "*") // FIXME: this is not secure, Don't allow all origins. @syrusakbary @@ -344,14 +357,14 @@ async fn preflight(req: Request) -> Result, anyhow::Error> async fn handle_post_save_token( context: AppContext, - req: Request, + req: Request, ) -> Result, anyhow::Error> { let AppContext { server_shutdown_tx, token_tx, } = context; let (.., body) = req.into_parts(); - let body = hyper::body::to_bytes(body).await?; + let body = body.collect().await?.to_bytes(); let ValidatedNonceOutput { token, @@ -425,7 +438,7 @@ async fn handle_unknown_method(context: AppContext) -> Result, an /// Then proceed to handle the actual request - POST request async fn service_router( context: AppContext, - req: Request, + req: Request, ) -> Result, anyhow::Error> { match *req.method() { Method::OPTIONS => preflight(req).await, diff --git a/lib/cli/src/commands/package/common/mod.rs b/lib/cli/src/commands/package/common/mod.rs index cbc5fd61284..9e9ca102627 100644 --- a/lib/cli/src/commands/package/common/mod.rs +++ b/lib/cli/src/commands/package/common/mod.rs @@ -5,8 +5,8 @@ use crate::{ }; use colored::Colorize; use dialoguer::Confirm; -use hyper::Body; use indicatif::{ProgressBar, ProgressStyle}; +use reqwest::Body; use std::{ collections::BTreeMap, path::{Path, PathBuf}, diff --git a/lib/compiler-singlepass/src/compiler.rs b/lib/compiler-singlepass/src/compiler.rs index 3669805bbae..06f9cecf70c 100644 --- a/lib/compiler-singlepass/src/compiler.rs +++ b/lib/compiler-singlepass/src/compiler.rs @@ -315,8 +315,8 @@ mod tests { // Compile for 32bit Linux let linux32 = Target::new(triple!("i686-unknown-linux-gnu"), CpuFeature::for_host()); - let (mut info, translation, inputs) = dummy_compilation_ingredients(); - let result = compiler.compile_module(&linux32, &mut info, &translation, inputs); + let (info, translation, inputs) = dummy_compilation_ingredients(); + let result = compiler.compile_module(&linux32, &info, &translation, inputs); match result.unwrap_err() { CompileError::UnsupportedTarget(name) => assert_eq!(name, "i686"), error => panic!("Unexpected error: {:?}", error), @@ -324,8 +324,8 @@ mod tests { // Compile for win32 let win32 = Target::new(triple!("i686-pc-windows-gnu"), CpuFeature::for_host()); - let (mut info, translation, inputs) = dummy_compilation_ingredients(); - let result = compiler.compile_module(&win32, &mut info, &translation, inputs); + let (info, translation, inputs) = dummy_compilation_ingredients(); + let result = compiler.compile_module(&win32, &info, &translation, inputs); match result.unwrap_err() { CompileError::UnsupportedTarget(name) => assert_eq!(name, "i686"), // Windows should be checked before architecture error => panic!("Unexpected error: {:?}", error), diff --git a/lib/config/src/hash.rs b/lib/config/src/hash.rs index 79cf00de31b..a7475ae3fd1 100644 --- a/lib/config/src/hash.rs +++ b/lib/config/src/hash.rs @@ -93,13 +93,13 @@ mod tests { fn hash_sha256_parse_fails() { let res1 = "c355cd53795b9b481f7eb2b5f4f6c8cf73631bdc343723a579d671e32db70b3".parse::(); - assert!(matches!(res1, Err(_))); + assert!(res1.is_err()); let res2 = "".parse::(); - assert!(matches!(res2, Err(_))); + assert!(res2.is_err()); let res3 = "öööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö" .parse::(); - assert!(matches!(res3, Err(_))); + assert!(res3.is_err()); } } diff --git a/lib/derive/tests/compiletest.rs b/lib/derive/tests/compiletest.rs index ae91da95c96..7cda93820a8 100644 --- a/lib/derive/tests/compiletest.rs +++ b/lib/derive/tests/compiletest.rs @@ -17,14 +17,16 @@ extern crate compiletest_rs as ct; use std::env; fn run_mode(src: &'static str, mode: &'static str) { - let mut config = ct::Config::default(); + let mut config = ct::Config { + mode: mode.parse().expect("invalid mode"), + target_rustcflags: Some("-L ../../target/debug/deps".to_owned()), + src_base: format!("tests/{}", src).into(), + ..Default::default() + }; - config.mode = mode.parse().expect("invalid mode"); - config.target_rustcflags = Some("-L ../../target/debug/deps".to_owned()); if let Ok(name) = env::var("TESTNAME") { config.filters.push(name); } - config.src_base = format!("tests/{}", src).into(); // hack to make this work on OSX: we probably don't need it though /*if std::env::var("DYLD_LIBRARY_PATH").is_err() { diff --git a/lib/registry/Cargo.toml b/lib/registry/Cargo.toml index 01a1dd19a7d..aa3b7ba48ee 100644 --- a/lib/registry/Cargo.toml +++ b/lib/registry/Cargo.toml @@ -22,7 +22,7 @@ filetime = "0.2.19" flate2 = "1.0.24" futures = "0.3" futures-util = "0.3.25" -graphql-ws-client = {version = "0.6.0", features = ["client-graphql-client"]} +graphql-ws-client = {version = "0.8.0", features = ["async-tungstenite", "client-graphql-client"]} graphql_client = "0.13.0" hex = "0.4.3" indexmap = { version = "1.9.3", optional = true } @@ -33,7 +33,7 @@ lzma-rs = "0.2.0" minisign = { version = "0.7.2", optional = true } rand = "0.8.5" regex = "1.7.0" -reqwest = { version = "0.11.12", default-features = false, features = ["blocking", "multipart", "json", "stream"] } +reqwest = { workspace = true, default-features = false, features = ["blocking", "multipart", "json", "stream"] } rpassword = { version = "7.2.0", optional = true } rusqlite = { version = "0.28.0", optional = true, features = ["bundled"] } semver = "1.0.14" @@ -45,15 +45,16 @@ thiserror = "1.0.37" time = { version = "0.3.17", default-features = false, features = ["parsing", "std", "formatting"], optional = true } tldextract = "0.6.0" tokio = {version = "1", features = ["rt-multi-thread"]} -tokio-tungstenite = {version = "0.20", features = ["rustls-tls-native-roots"]} +tokio-tungstenite = {version = "0.21", features = ["rustls-tls-native-roots"]} toml.workspace = true tracing = "0.1.40" -url = "2.3.1" +url = "2.5.0" wasmer-config = { version = "0.4.0", path = "../config" } wasmer-wasm-interface = { version = "4.3.4", path = "../wasm-interface", optional = true } wasmparser = { workspace = true, optional = true } whoami = "1.2.3" webc.workspace = true +async-tungstenite = { version = "0.25.1", features = ["tokio-runtime", "tokio-rustls-native-certs"] } [dev-dependencies] pretty_assertions = "1.3.0" diff --git a/lib/registry/src/lib.rs b/lib/registry/src/lib.rs index 4ccba8d4ebc..6804d864e1d 100644 --- a/lib/registry/src/lib.rs +++ b/lib/registry/src/lib.rs @@ -18,7 +18,6 @@ pub mod login; pub mod package; pub mod publish; pub mod subscriptions; -pub(crate) mod tokio_spawner; pub mod types; pub mod utils; pub mod wasmer_env; diff --git a/lib/registry/src/subscriptions.rs b/lib/registry/src/subscriptions.rs index 911f2b80395..daca2295e5a 100644 --- a/lib/registry/src/subscriptions.rs +++ b/lib/registry/src/subscriptions.rs @@ -1,22 +1,13 @@ -use std::env; +use std::{env, future::IntoFuture}; -use crate::{ - graphql::subscriptions::{package_version_ready, PackageVersionReady}, - tokio_spawner::TokioSpawner, -}; +use anyhow::Context; -use futures_util::StreamExt; +use crate::graphql::subscriptions::{package_version_ready, PackageVersionReady}; use graphql_client::GraphQLQuery; -use graphql_ws_client::{ - graphql::{GraphQLClient, StreamingOperation}, - GraphQLClientClient, SubscriptionStream, -}; +use graphql_ws_client::{graphql::StreamingOperation, Client, Subscription}; -use tokio_tungstenite::{ - connect_async, - tungstenite::{client::IntoClientRequest, http::HeaderValue, Message}, -}; +use tokio_tungstenite::tungstenite::{client::IntoClientRequest, http::HeaderValue}; pub use crate::graphql::subscriptions::package_version_ready::PackageVersionState; @@ -24,10 +15,7 @@ async fn subscribe_graphql( registry_url: &str, login_token: &str, variables: Q::Variables, -) -> anyhow::Result<( - SubscriptionStream>, - GraphQLClientClient, -)> +) -> anyhow::Result<(Subscription>, Client)> where ::Variables: Send + Sync + Unpin, { @@ -56,14 +44,15 @@ where reqwest::header::USER_AGENT, HeaderValue::from_str(&user_agent)?, ); - let (ws_con, _resp) = connect_async(req).await?; - let (sink, stream) = ws_con.split(); + let (connection, _resp) = async_tungstenite::tokio::connect_async(req) + .await + .context("could not connect")?; + + let (client, actor) = graphql_ws_client::Client::build(connection).await?; + tokio::spawn(actor.into_future()); - let mut client = graphql_ws_client::GraphQLClientClientBuilder::new() - .build(stream, sink, TokioSpawner::current()) - .await?; let stream = client - .streaming_operation(StreamingOperation::::new(variables)) + .subscribe(StreamingOperation::::new(variables)) .await?; Ok((stream, client)) @@ -74,8 +63,8 @@ pub async fn subscribe_package_version_ready( login_token: &str, package_version_id: &str, ) -> anyhow::Result<( - SubscriptionStream>, - GraphQLClientClient, + Subscription>, + Client, )> { subscribe_graphql( registry_url, diff --git a/lib/registry/src/tokio_spawner.rs b/lib/registry/src/tokio_spawner.rs deleted file mode 100644 index d4937e1d9ab..00000000000 --- a/lib/registry/src/tokio_spawner.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[derive(Debug)] -pub struct TokioSpawner(tokio::runtime::Handle); - -impl TokioSpawner { - pub fn new(handle: tokio::runtime::Handle) -> Self { - TokioSpawner(handle) - } - - pub fn current() -> Self { - TokioSpawner::new(tokio::runtime::Handle::current()) - } -} - -impl futures::task::Spawn for TokioSpawner { - fn spawn_obj( - &self, - obj: futures::task::FutureObj<'static, ()>, - ) -> Result<(), futures::task::SpawnError> { - self.0.spawn(obj); - Ok(()) - } -} diff --git a/lib/sys-utils/src/memory/fd_memory/fd_mmap.rs b/lib/sys-utils/src/memory/fd_memory/fd_mmap.rs index 3aa795a7f0b..aeb2f6acada 100644 --- a/lib/sys-utils/src/memory/fd_memory/fd_mmap.rs +++ b/lib/sys-utils/src/memory/fd_memory/fd_mmap.rs @@ -376,7 +376,7 @@ mod tests { .read(true) .write(true) .create_new(true) - .open(&pa) + .open(pa) .unwrap(); a.write_all(&data).unwrap(); @@ -385,7 +385,7 @@ mod tests { .read(true) .write(true) .create_new(true) - .open(&pb) + .open(pb) .unwrap(); b.write_all(&datb).unwrap(); diff --git a/lib/virtual-fs/src/host_fs.rs b/lib/virtual-fs/src/host_fs.rs index 0d0a53cc7b3..cde3eba76cd 100644 --- a/lib/virtual-fs/src/host_fs.rs +++ b/lib/virtual-fs/src/host_fs.rs @@ -1214,39 +1214,35 @@ mod tests { ); assert_eq!( - fs.rename(&foo, &foo.join("bar").join("baz"),).await, + fs.rename(foo, &foo.join("bar").join("baz"),).await, Err(FsError::EntryNotFound), "renaming to a directory that has parent that doesn't exist", ); // On Windows, rename "to" must not be an existing directory #[cfg(not(target_os = "windows"))] - assert_eq!(fs.create_dir(&bar), Ok(())); + assert_eq!(fs.create_dir(bar), Ok(())); assert_eq!( - fs.rename(&foo, &bar).await, + fs.rename(foo, bar).await, Ok(()), "renaming to a directory that has parent that exists", ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(bar.join("hello1.txt")), - Ok(_), - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(bar.join("hello1.txt")) + .is_ok(), "creating a new file (`hello1.txt`)", ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(bar.join("hello2.txt")), - Ok(_), - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(bar.join("hello2.txt")) + .is_ok(), "creating a new file (`hello2.txt`)", ); @@ -1262,7 +1258,7 @@ mod tests { "the bar directory still exists" ); - let bar_dir = read_dir_names(&fs, &bar); + let bar_dir = read_dir_names(&fs, bar); if !bar_dir.contains(&"qux".to_string()) { println!("qux does not exist: {:?}", bar_dir) @@ -1282,7 +1278,7 @@ mod tests { "the /bar/hello2.txt file exists" ); - assert_eq!(fs.create_dir(&foo), Ok(()), "create ./foo again",); + assert_eq!(fs.create_dir(foo), Ok(()), "create ./foo again",); assert_eq!( fs.rename(&bar.join("hello2.txt"), &foo.join("world2.txt")) @@ -1292,7 +1288,7 @@ mod tests { ); assert_eq!( - fs.rename(&foo, &bar.join("baz")).await, + fs.rename(foo, &bar.join("baz")).await, Ok(()), "renaming a directory", ); @@ -1350,9 +1346,9 @@ mod tests { let foo = Path::new("foo"); - assert_eq!(fs.create_dir(&foo), Ok(())); + assert_eq!(fs.create_dir(foo), Ok(())); - let foo_metadata = fs.metadata(&foo); + let foo_metadata = fs.metadata(foo); assert!(foo_metadata.is_ok()); let foo_metadata = foo_metadata.unwrap(); @@ -1367,15 +1363,15 @@ mod tests { let bar = Path::new("bar"); - assert_eq!(fs.rename(&foo, &bar).await, Ok(())); + assert_eq!(fs.rename(foo, bar).await, Ok(())); - let bar_metadata = fs.metadata(&bar).unwrap(); + let bar_metadata = fs.metadata(bar).unwrap(); assert!(bar_metadata.ft.dir); assert!(bar_metadata.accessed >= foo_metadata.accessed); assert_eq!(bar_metadata.created, foo_metadata.created); assert!(bar_metadata.modified > foo_metadata.modified); - let root_metadata = fs.metadata(&bar).unwrap(); + let root_metadata = fs.metadata(bar).unwrap(); assert!( root_metadata.modified > foo_metadata.modified, "the parent modified time was updated" @@ -1388,13 +1384,11 @@ mod tests { let fs = FileSystem::new(Handle::current(), temp.path()).expect("get filesystem"); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(Path::new("foo.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("foo.txt")) + .is_ok(), "creating a new file", ); @@ -1403,7 +1397,7 @@ mod tests { assert!(temp.path().join("foo.txt").is_file()); assert_eq!( - fs.remove_file(&Path::new("foo.txt")), + fs.remove_file(Path::new("foo.txt")), Ok(()), "removing a file that exists", ); @@ -1411,7 +1405,7 @@ mod tests { assert!(!temp.path().join("foo.txt").exists()); assert_eq!( - fs.remove_file(&Path::new("foo.txt")), + fs.remove_file(Path::new("foo.txt")), Err(FsError::EntryNotFound), "removing a file that doesn't exists", ); @@ -1422,32 +1416,28 @@ mod tests { let temp = TempDir::new().unwrap(); let fs = FileSystem::new(Handle::current(), temp.path()).expect("get filesystem"); - assert_eq!(fs.create_dir(&Path::new("foo")), Ok(()), "creating `foo`"); + assert_eq!(fs.create_dir(Path::new("foo")), Ok(()), "creating `foo`"); assert_eq!( - fs.create_dir(&Path::new("foo/sub")), + fs.create_dir(Path::new("foo/sub")), Ok(()), "creating `sub`" ); - assert_eq!(fs.create_dir(&Path::new("bar")), Ok(()), "creating `bar`"); - assert_eq!(fs.create_dir(&Path::new("baz")), Ok(()), "creating `bar`"); + assert_eq!(fs.create_dir(Path::new("bar")), Ok(()), "creating `bar`"); + assert_eq!(fs.create_dir(Path::new("baz")), Ok(()), "creating `bar`"); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(Path::new("a.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("a.txt")) + .is_ok(), "creating `a.txt`", ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(&Path::new("b.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("b.txt")) + .is_ok(), "creating `b.txt`", ); diff --git a/lib/virtual-fs/src/mem_fs/file.rs b/lib/virtual-fs/src/mem_fs/file.rs index 77a9dedf8c9..3c0f3837b47 100644 --- a/lib/virtual-fs/src/mem_fs/file.rs +++ b/lib/virtual-fs/src/mem_fs/file.rs @@ -1379,7 +1379,7 @@ mod test_read_write_seek { let mut buffer = [0; 16]; assert!( - matches!(file.read_exact(&mut buffer).await, Err(_)), + file.read_exact(&mut buffer).await.is_err(), "failing to read an exact buffer", ); @@ -1390,7 +1390,7 @@ mod test_read_write_seek { let mut buffer = [0; 3]; assert!( - matches!(file.read_exact(&mut buffer).await, Ok(_)), + file.read_exact(&mut buffer).await.is_ok(), "failing to read an exact buffer", ); } diff --git a/lib/virtual-fs/src/mem_fs/file_opener.rs b/lib/virtual-fs/src/mem_fs/file_opener.rs index f2a7da582e7..46be5e53b1d 100644 --- a/lib/virtual-fs/src/mem_fs/file_opener.rs +++ b/lib/virtual-fs/src/mem_fs/file_opener.rs @@ -568,13 +568,11 @@ mod test_file_opener { let fs = FileSystem::default(); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(path!("/foo.txt")), - Ok(_), - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .is_ok(), "creating a new file", ); @@ -631,13 +629,11 @@ mod test_file_opener { assert_eq!(fs.remove_file(path!("/foo.txt")), Ok(()), "removing a file"); assert!( - matches!( - fs.new_open_options() - .write(false) - .create_new(true) - .open(path!("/foo.txt")), - Ok(_), - ), + fs.new_open_options() + .write(false) + .create_new(true) + .open(path!("/foo.txt")) + .is_ok(), "creating a file without the `write` option", ); } @@ -768,13 +764,11 @@ mod test_file_opener { let fs = FileSystem::default(); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(path!("/foo.txt")), - Ok(_), - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .is_ok(), "creating a _new_ file", ); @@ -789,10 +783,10 @@ mod test_file_opener { ); assert!( - matches!( - fs.new_open_options().read(true).open(path!("/foo.txt")), - Ok(_), - ), + fs.new_open_options() + .read(true) + .open(path!("/foo.txt")) + .is_ok(), "opening a file that already exists", ); } diff --git a/lib/virtual-fs/src/mem_fs/filesystem.rs b/lib/virtual-fs/src/mem_fs/filesystem.rs index 97d5c6679a0..0358125e8d5 100644 --- a/lib/virtual-fs/src/mem_fs/filesystem.rs +++ b/lib/virtual-fs/src/mem_fs/filesystem.rs @@ -1633,13 +1633,11 @@ mod test_filesystem { let fs = FileSystem::default(); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(path!("/foo.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .is_ok(), "creating a new file", ); @@ -1712,23 +1710,19 @@ mod test_filesystem { assert_eq!(fs.create_dir(path!("/bar")), Ok(()), "creating `bar`"); assert_eq!(fs.create_dir(path!("/baz")), Ok(()), "creating `bar`"); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(path!("/a.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/a.txt")) + .is_ok(), "creating `a.txt`", ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(path!("/b.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/b.txt")) + .is_ok(), "creating `b.txt`", ); @@ -1793,7 +1787,7 @@ mod test_filesystem { ), "checking entry #5", ); - assert!(matches!(readdir.next(), None), "no more entries"); + assert!(readdir.next().is_none(), "no more entries"); } #[tokio::test] @@ -1813,13 +1807,11 @@ mod test_filesystem { "creating `qux`", ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(path!("/foo/bar/baz/qux/hello.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo/bar/baz/qux/hello.txt")) + .is_ok(), "creating `hello.txt`", ); @@ -1921,21 +1913,21 @@ mod test_filesystem { let other = FileSystem::default(); crate::ops::create_dir_all(&other, "/a/x").unwrap(); other - .insert_ro_file(&Path::new("/a/x/a.txt"), Cow::Borrowed(b"a")) + .insert_ro_file(Path::new("/a/x/a.txt"), Cow::Borrowed(b"a")) .unwrap(); other - .insert_ro_file(&Path::new("/a/x/b.txt"), Cow::Borrowed(b"b")) + .insert_ro_file(Path::new("/a/x/b.txt"), Cow::Borrowed(b"b")) .unwrap(); other - .insert_ro_file(&Path::new("/a/x/c.txt"), Cow::Borrowed(b"c")) + .insert_ro_file(Path::new("/a/x/c.txt"), Cow::Borrowed(b"c")) .unwrap(); - let out = other.read_dir(&Path::new("/")).unwrap(); + let out = other.read_dir(Path::new("/")).unwrap(); dbg!(&out); let other: Arc = Arc::new(other); - main.mount_directory_entries(&Path::new("/"), &other, &Path::new("/a")) + main.mount_directory_entries(Path::new("/"), &other, Path::new("/a")) .unwrap(); let mut buf = Vec::new(); @@ -1943,7 +1935,7 @@ mod test_filesystem { let mut f = main .new_open_options() .read(true) - .open(&Path::new("/x/a.txt")) + .open(Path::new("/x/a.txt")) .unwrap(); f.read_to_end(&mut buf).await.unwrap(); diff --git a/lib/virtual-fs/src/mem_fs/offloaded_file.rs b/lib/virtual-fs/src/mem_fs/offloaded_file.rs index 356a7e739b5..d22cccc774c 100644 --- a/lib/virtual-fs/src/mem_fs/offloaded_file.rs +++ b/lib/virtual-fs/src/mem_fs/offloaded_file.rs @@ -452,7 +452,7 @@ mod tests { .collect::>() ); - file.resize(33, 01u8); + file.resize(33, 1u8); cursor = 0; let mut result = std::iter::repeat(0u8).take(33).collect::>(); diff --git a/lib/virtual-fs/src/union_fs.rs b/lib/virtual-fs/src/union_fs.rs index f9b3b95ca00..4e6eff9f044 100644 --- a/lib/virtual-fs/src/union_fs.rs +++ b/lib/virtual-fs/src/union_fs.rs @@ -708,23 +708,19 @@ mod tests { ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(Path::new("/test_rename/bar/hello1.txt")), - Ok(_), - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("/test_rename/bar/hello1.txt")) + .is_ok(), "creating a new file (`hello1.txt`)", ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(Path::new("/test_rename/bar/hello2.txt")), - Ok(_), - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("/test_rename/bar/hello2.txt")) + .is_ok(), "creating a new file (`hello2.txt`)", ); @@ -897,13 +893,11 @@ mod tests { assert!(fs.create_dir(Path::new("/test_remove_file")).is_ok()); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(Path::new("/test_remove_file/foo.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("/test_remove_file/foo.txt")) + .is_ok(), "creating a new file", ); @@ -951,23 +945,19 @@ mod tests { "creating `bar`" ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(Path::new("/test_readdir/a.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("/test_readdir/a.txt")) + .is_ok(), "creating `a.txt`", ); assert!( - matches!( - fs.new_open_options() - .write(true) - .create_new(true) - .open(Path::new("/test_readdir/b.txt")), - Ok(_) - ), + fs.new_open_options() + .write(true) + .create_new(true) + .open(Path::new("/test_readdir/b.txt")) + .is_ok(), "creating `b.txt`", ); diff --git a/lib/virtual-net/Cargo.toml b/lib/virtual-net/Cargo.toml index b22758ada5d..350c66d1e7c 100644 --- a/lib/virtual-net/Cargo.toml +++ b/lib/virtual-net/Cargo.toml @@ -28,11 +28,12 @@ futures-util = { version = "0.3" } anyhow = "1.0" tokio-serde = { version = "0.8", features = [ "bincode" ], optional = true } tokio-util = { version = "0.7.8", features = ["codec"], optional = true } -hyper-tungstenite = { version = "0.11", optional = true } -hyper = { version = "0.14", optional = true } -tokio-tungstenite = { version = "0.20", optional = true } +hyper-tungstenite = { version = "0.13", optional = true } +hyper = { workspace = true, optional = true } +tokio-tungstenite = { version = "0.21", optional = true } rkyv = { workspace = true, optional = true } bytecheck = { version = "0.6.8", optional = true } +hyper-util = { version = "0.1.5", features = ["tokio"], optional = true } [dependencies.smoltcp] version = "0.8" @@ -51,7 +52,7 @@ remote = [ "libc", "tokio/io-util", "tokio/sync", "tokio-serde", "tokio-util" ] json = [ "tokio-serde/json" ] messagepack = [ "tokio-serde/messagepack" ] cbor = [ "tokio-serde/cbor" ] -hyper = [ "hyper-tungstenite", "dep:hyper" ] +hyper = [ "hyper-tungstenite", "hyper-util", "dep:hyper" ] tokio-tungstenite = [ "dep:tokio-tungstenite" ] rkyv = [ "dep:rkyv", "dep:bytecheck" ] diff --git a/lib/virtual-net/src/client.rs b/lib/virtual-net/src/client.rs index 879b99244ab..5cb31ede648 100644 --- a/lib/virtual-net/src/client.rs +++ b/lib/virtual-net/src/client.rs @@ -23,6 +23,7 @@ use futures_util::stream::FuturesOrdered; use futures_util::Sink; use futures_util::Stream; use futures_util::StreamExt; +use hyper_util::rt::tokio::TokioIo; use tokio::io::AsyncRead; use tokio::io::AsyncWrite; use tokio::sync::mpsc; @@ -200,11 +201,11 @@ impl RemoteNetworkingClient { #[cfg(feature = "hyper")] pub fn new_from_hyper_ws_io( tx: futures_util::stream::SplitSink< - hyper_tungstenite::WebSocketStream, + hyper_tungstenite::WebSocketStream>, hyper_tungstenite::tungstenite::Message, >, rx: futures_util::stream::SplitStream< - hyper_tungstenite::WebSocketStream, + hyper_tungstenite::WebSocketStream>, >, format: FrameSerializationFormat, ) -> (Self, RemoteNetworkingClientDriver) { diff --git a/lib/virtual-net/src/rx_tx.rs b/lib/virtual-net/src/rx_tx.rs index bb052f6de1d..6d8391b37b2 100644 --- a/lib/virtual-net/src/rx_tx.rs +++ b/lib/virtual-net/src/rx_tx.rs @@ -7,6 +7,7 @@ use std::{ use crate::Result; use futures_util::{future::BoxFuture, Future, Sink, SinkExt, Stream}; +use hyper_util::rt::tokio::TokioIo; use serde::Serialize; #[cfg(feature = "tokio-tungstenite")] use tokio::net::TcpStream; @@ -79,7 +80,7 @@ where tx: Arc< tokio::sync::Mutex< futures_util::stream::SplitSink< - hyper_tungstenite::WebSocketStream, + hyper_tungstenite::WebSocketStream>, hyper_tungstenite::tungstenite::Message, >, >, @@ -516,7 +517,7 @@ where #[cfg(feature = "hyper")] HyperWebSocket { rx: futures_util::stream::SplitStream< - hyper_tungstenite::WebSocketStream, + hyper_tungstenite::WebSocketStream>, >, format: crate::meta::FrameSerializationFormat, }, diff --git a/lib/virtual-net/src/server.rs b/lib/virtual-net/src/server.rs index bc33c5a404d..73859d428e4 100644 --- a/lib/virtual-net/src/server.rs +++ b/lib/virtual-net/src/server.rs @@ -16,6 +16,8 @@ use std::mem::MaybeUninit; use std::net::IpAddr; use std::task::Waker; use std::time::Duration; + +use hyper_util::rt::tokio::TokioIo; use std::{ collections::HashMap, future::Future, @@ -167,10 +169,10 @@ impl RemoteNetworkingServer { #[cfg(feature = "hyper")] pub fn new_from_hyper_ws_io( tx: SplitSink< - hyper_tungstenite::WebSocketStream, + hyper_tungstenite::WebSocketStream>, hyper_tungstenite::tungstenite::Message, >, - rx: SplitStream>, + rx: SplitStream>>, format: FrameSerializationFormat, inner: Arc, ) -> (Self, RemoteNetworkingServerDriver) { diff --git a/lib/vm/src/lib.rs b/lib/vm/src/lib.rs index fabdc38a48f..726e304b8b5 100644 --- a/lib/vm/src/lib.rs +++ b/lib/vm/src/lib.rs @@ -88,17 +88,6 @@ impl std::ops::Deref for SectionBodyPtr { #[repr(C)] pub struct VMFunctionBody(u8); -#[cfg(test)] -mod test_vmfunction_body { - use super::VMFunctionBody; - use std::mem::size_of; - - #[test] - fn check_vmfunction_body_offsets() { - assert_eq!(size_of::(), 1); - } -} - /// A safe wrapper around `VMFunctionBody`. #[derive(Clone, Copy, Debug)] #[repr(transparent)] @@ -142,3 +131,14 @@ impl VMFuncRef { NonNull::new(raw.funcref as *mut VMCallerCheckedAnyfunc).map(Self) } } + +#[cfg(test)] +mod test_vmfunction_body { + use super::VMFunctionBody; + use std::mem::size_of; + + #[test] + fn check_vmfunction_body_offsets() { + assert_eq!(size_of::(), 1); + } +} diff --git a/lib/wasix/Cargo.toml b/lib/wasix/Cargo.toml index 5c0e4aad269..c5db3de94bb 100644 --- a/lib/wasix/Cargo.toml +++ b/lib/wasix/Cargo.toml @@ -23,6 +23,7 @@ wasmer-journal = { path = "../journal", version = "0.6.0", default-features = fa wasmer-emscripten = { path = "../emscripten", version = "=4.3.4", optional = true } wasmer-config = { version = "0.4.0", path = "../config" } +http.workspace = true xxhash-rust = { version = "0.8.8", features = ["xxh64"] } rusty_pool = { version = "0.7.0", optional = true } cfg-if = "1.0" @@ -60,7 +61,6 @@ serde_yaml.workspace = true weezl = { version = "^0.1" } hex = { version = "^0.4" } linked_hash_set = { version = "0.1" } -http = "0.2.8" heapless = "0.7.16" once_cell = "1.17.0" pin-project = "1.0.12" @@ -69,10 +69,10 @@ dashmap = "5.4.0" tempfile = "3.6.0" num_enum = "0.5.7" # Used by the WCGI runner -hyper = { version = "0.14", features = ["server", "stream"], optional = true } -wcgi = { version = "0.1.2", optional = true } -wcgi-host = { version = "0.1.2", optional = true } -tower-http = { version = "0.4.0", features = [ +hyper = { workspace = true, features = ["server"], optional = true } +wcgi = { version = "0.2.0", optional = true } +wcgi-host = { version = "0.2.0", optional = true } +tower-http = { version = "0.5.0", features = [ "trace", "util", "catch-panic", @@ -101,15 +101,17 @@ web-sys = { version = "0.3.64", features = [ "Headers", ], optional = true } ahash = "0.8.11" +hyper-util = { version = "0.1.5", features = ["server", "server-graceful", "tokio", "service", "client"], optional = true } +http-body-util = { version="0.1.1", optional = true } [target.'cfg(not(target_arch = "riscv64"))'.dependencies.reqwest] -version = "0.11" +workspace = true default-features = false features = ["rustls-tls", "json", "stream", "socks", "blocking"] optional = true [target.'cfg(target_arch = "riscv64")'.dependencies.reqwest] -version = "0.11" +workspace = true default-features = false features = ["native-tls", "json", "stream", "socks", "blocking"] optional = true @@ -147,9 +149,9 @@ default = ["sys-default"] time = ["tokio/time"] ctrlc = ["tokio/signal"] -webc_runner_rt_wcgi = ["hyper", "wcgi", "wcgi-host", "tower", "tower-http"] +webc_runner_rt_wcgi = ["hyper", "hyper-util", "http-body-util", "wcgi", "wcgi-host", "tower", "tower-http"] webc_runner_rt_dcgi = ["webc_runner_rt_wcgi", "journal"] -webc_runner_rt_dproxy = ["hyper", "tower", "tower-http", "journal"] +webc_runner_rt_dproxy = ["hyper", "hyper-util", "http-body-util", "tower", "tower-http", "journal"] webc_runner_rt_emscripten = ["wasmer-emscripten"] sys = ["webc/mmap", "time", "virtual-mio/sys"] diff --git a/lib/wasix/src/runners/dcgi/handler.rs b/lib/wasix/src/runners/dcgi/handler.rs index 627751fd4ec..b6415eb8118 100644 --- a/lib/wasix/src/runners/dcgi/handler.rs +++ b/lib/wasix/src/runners/dcgi/handler.rs @@ -1,14 +1,15 @@ -use std::{ops::Deref, pin::Pin, sync::Arc, task::Poll}; +use std::{ops::Deref, pin::Pin, sync::Arc}; use anyhow::Error; use futures::{Future, FutureExt}; use http::{Request, Response}; -use hyper::{service::Service, Body}; use crate::runners::wcgi; use super::DcgiInstanceFactory; +use super::super::Body; + /// The shared object that manages the instantiaion of WASI executables and /// communicating with them via the CGI protocol. #[derive(Clone, Debug)] @@ -30,7 +31,10 @@ impl Handler { } #[tracing::instrument(level = "debug", skip_all, err)] - pub(crate) async fn handle(&self, req: Request) -> Result, Error> { + pub(crate) async fn handle( + &self, + req: Request, + ) -> Result, Error> { // we acquire a guard token so that only one request at a time can be processed // which effectively means that DCGI is single-threaded. This is a limitation // of the MVP which should be rectified in future releases. @@ -57,17 +61,19 @@ pub(crate) struct SharedState { master_lock: Arc>, } -impl Service> for Handler { +impl tower::Service> for Handler { type Response = Response; type Error = Error; type Future = Pin, Error>> + Send>>; - fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll> { - // TODO: We probably should implement some sort of backpressure here... - Poll::Ready(Ok(())) + fn poll_ready( + &mut self, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + std::task::Poll::Ready(Ok(())) } - fn call(&mut self, request: Request) -> Self::Future { + fn call(&mut self, request: Request) -> Self::Future { // Note: all fields are reference-counted so cloning is pretty cheap let handler = self.clone(); let fut = async move { handler.handle(request).await }; diff --git a/lib/wasix/src/runners/dproxy/factory.rs b/lib/wasix/src/runners/dproxy/factory.rs index f5f492fbe9c..34465ef3885 100644 --- a/lib/wasix/src/runners/dproxy/factory.rs +++ b/lib/wasix/src/runners/dproxy/factory.rs @@ -6,6 +6,7 @@ use std::{ }; use derivative::Derivative; +use hyper_util::rt::TokioExecutor; use wasmer_journal::{DynJournal, RecombinedJournal}; use crate::{ @@ -121,7 +122,8 @@ impl DProxyInstanceFactory { Ok(DProxyInstance { last_used: Arc::new(Mutex::new(Instant::now())), socket_manager, - client: hyper::Client::builder().build(connector), + client: hyper_util::client::legacy::Client::builder(TokioExecutor::new()) + .build(connector), }) } } diff --git a/lib/wasix/src/runners/dproxy/handler.rs b/lib/wasix/src/runners/dproxy/handler.rs index ea0cf3d6fbb..0d83d053eb8 100644 --- a/lib/wasix/src/runners/dproxy/handler.rs +++ b/lib/wasix/src/runners/dproxy/handler.rs @@ -4,9 +4,10 @@ use std::task::Poll; use futures::{Future, FutureExt}; use http::{Request, Response, Uri}; -use hyper::Body; +use http_body_util::BodyExt; use tower::Service; +use super::super::Body; use crate::runners::dproxy::shard::Shard; use crate::Runtime; @@ -45,7 +46,7 @@ impl Handler { #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn handle( &self, - mut req: Request, + mut req: Request, _token: T, ) -> anyhow::Result> where @@ -91,7 +92,15 @@ impl Handler { let client = instance.client.clone(); // Perform the request - Ok(client.request(req).await?) + let resp = client.request(req).await?; + let (parts, body) = resp.into_parts(); + let body = body + .collect() + .await? + .map_err(|_| anyhow::anyhow!("Infallible")) + .boxed(); + + Ok(Response::from_parts(parts, body)) } } @@ -103,7 +112,7 @@ impl std::ops::Deref for Handler { } } -impl Service> for Handler { +impl Service> for Handler { type Response = Response; type Error = anyhow::Error; type Future = Pin>> + Send>>; @@ -112,7 +121,7 @@ impl Service> for Handler { Poll::Ready(Ok(())) } - fn call(&mut self, request: Request) -> Self::Future { + fn call(&mut self, request: Request) -> Self::Future { // Note: all fields are reference-counted so cloning is pretty cheap let handler = self.clone(); let fut = async move { handler.handle(request, ()).await }; diff --git a/lib/wasix/src/runners/dproxy/hyper_proxy/connector.rs b/lib/wasix/src/runners/dproxy/hyper_proxy/connector.rs index a309c8c18c8..d224c459dee 100644 --- a/lib/wasix/src/runners/dproxy/hyper_proxy/connector.rs +++ b/lib/wasix/src/runners/dproxy/hyper_proxy/connector.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use hyper_util::rt::TokioIo; use tokio_stream::wrappers::BroadcastStream; use super::socket_manager::SocketManager; @@ -18,7 +19,7 @@ impl HyperProxyConnector { } } -impl Service for HyperProxyConnector { +impl tower::Service for HyperProxyConnector { type Response = HyperProxyStream; type Error = BoxError; @@ -37,7 +38,7 @@ impl Service for HyperProxyConnector { let (tx, rx) = socket.split(); Ok(HyperProxyStream { tx, - rx, + rx: TokioIo::new(rx), terminate: BroadcastStream::new(terminate_rx), terminated: false, }) diff --git a/lib/wasix/src/runners/dproxy/hyper_proxy/mod.rs b/lib/wasix/src/runners/dproxy/hyper_proxy/mod.rs index 5dcc7c785b4..cd20a5f615e 100644 --- a/lib/wasix/src/runners/dproxy/hyper_proxy/mod.rs +++ b/lib/wasix/src/runners/dproxy/hyper_proxy/mod.rs @@ -8,11 +8,11 @@ pub use stream::*; use super::*; -pub(super) use hyper::{service::Service, Uri}; +pub(super) use hyper::Uri; pub(super) use std::pin::Pin; pub(super) type BoxError = Box; pub(super) use std::{ future::Future, task::{Context, Poll}, }; -pub(super) use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +pub(super) use tokio::io::AsyncWrite; diff --git a/lib/wasix/src/runners/dproxy/hyper_proxy/stream.rs b/lib/wasix/src/runners/dproxy/hyper_proxy/stream.rs index fd5d0d17493..81e2bb5d3de 100644 --- a/lib/wasix/src/runners/dproxy/hyper_proxy/stream.rs +++ b/lib/wasix/src/runners/dproxy/hyper_proxy/stream.rs @@ -1,7 +1,7 @@ use std::io; use futures::Stream; -use hyper::client::connect::Connected; +use hyper_util::{client::legacy::connect::Connected, rt::TokioIo}; use tokio_stream::wrappers::BroadcastStream; use virtual_net::tcp_pair::{TcpSocketHalfRx, TcpSocketHalfTx}; @@ -10,18 +10,23 @@ use super::*; #[derive(Debug)] pub struct HyperProxyStream { pub(super) tx: TcpSocketHalfTx, - pub(super) rx: TcpSocketHalfRx, + pub(super) rx: TokioIo, pub(super) terminate: BroadcastStream<()>, pub(super) terminated: bool, } -impl AsyncRead for HyperProxyStream { - #[inline] +impl hyper_util::client::legacy::connect::Connection for HyperProxyStream { + fn connected(&self) -> Connected { + Connected::new().proxy(true) + } +} + +impl hyper::rt::Read for HyperProxyStream { fn poll_read( mut self: Pin<&mut Self>, - cx: &mut Context, - buf: &mut ReadBuf<'_>, - ) -> Poll> { + cx: &mut Context<'_>, + buf: hyper::rt::ReadBufCursor<'_>, + ) -> Poll> { if let Poll::Ready(ret) = Pin::new(&mut self.rx).poll_read(cx, buf) { return Poll::Ready(ret); } @@ -35,13 +40,12 @@ impl AsyncRead for HyperProxyStream { } } -impl AsyncWrite for HyperProxyStream { - #[inline] +impl hyper::rt::Write for HyperProxyStream { fn poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], - ) -> Poll> { + ) -> Poll> { if let Poll::Ready(ret) = Pin::new(&mut self.tx).poll_write(cx, buf) { return Poll::Ready(ret); } @@ -54,8 +58,10 @@ impl AsyncWrite for HyperProxyStream { Poll::Pending } - #[inline] - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + fn poll_flush( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { if let Poll::Ready(ret) = Pin::new(&mut self.tx).poll_flush(cx) { return Poll::Ready(ret); } @@ -68,11 +74,10 @@ impl AsyncWrite for HyperProxyStream { Poll::Pending } - #[inline] fn poll_shutdown( mut self: Pin<&mut Self>, cx: &mut Context<'_>, - ) -> Poll> { + ) -> Poll> { if let Poll::Ready(ret) = Pin::new(&mut self.tx).poll_shutdown(cx) { return Poll::Ready(ret); } @@ -85,9 +90,3 @@ impl AsyncWrite for HyperProxyStream { Poll::Pending } } - -impl hyper::client::connect::Connection for HyperProxyStream { - fn connected(&self) -> Connected { - Connected::new().proxy(true) - } -} diff --git a/lib/wasix/src/runners/dproxy/instance.rs b/lib/wasix/src/runners/dproxy/instance.rs index edbb8e656fe..8f46688f78c 100644 --- a/lib/wasix/src/runners/dproxy/instance.rs +++ b/lib/wasix/src/runners/dproxy/instance.rs @@ -3,6 +3,8 @@ use std::{ time::Instant, }; +use hyper_util::client::legacy::Client; + use super::{hyper_proxy::HyperProxyConnector, socket_manager::SocketManager}; #[derive(Debug, Clone)] @@ -11,5 +13,5 @@ pub struct DProxyInstance { pub(super) last_used: Arc>, #[allow(unused)] pub(super) socket_manager: Arc, - pub(super) client: hyper::Client, + pub(super) client: Client, } diff --git a/lib/wasix/src/runners/dproxy/runner.rs b/lib/wasix/src/runners/dproxy/runner.rs index 5fced6201f1..446d63fa7a7 100644 --- a/lib/wasix/src/runners/dproxy/runner.rs +++ b/lib/wasix/src/runners/dproxy/runner.rs @@ -1,11 +1,10 @@ use std::{net::SocketAddr, sync::Arc, time::Duration}; use anyhow::{Context, Error}; -use http::{Request, Response}; -use hyper::Body; -use tower::{make::Shared, ServiceBuilder}; +use futures::{stream::FuturesUnordered, StreamExt}; +use http::Request; +use tower::ServiceBuilder; use tower_http::{catch_panic::CatchPanicLayer, cors::CorsLayer, trace::TraceLayer}; -use tracing::Span; use webc::metadata::Command; use crate::{ @@ -62,7 +61,7 @@ impl crate::runners::Runner for DProxyRunner { let service = ServiceBuilder::new() .layer( TraceLayer::new_for_http() - .make_span_with(|request: &Request| { + .make_span_with(|request: &Request| { tracing::info_span!( "request", method = %request.method(), @@ -70,10 +69,7 @@ impl crate::runners::Runner for DProxyRunner { status_code = tracing::field::Empty, ) }) - .on_response(|response: &Response<_>, _latency: Duration, span: &Span| { - span.record("status_code", &tracing::field::display(response.status())); - tracing::info!("response generated") - }), + .on_response(super::super::response_tracing::OnResponseTracer), ) .layer(CatchPanicLayer::new()) .layer(CorsLayer::permissive()) @@ -85,16 +81,42 @@ impl crate::runners::Runner for DProxyRunner { runtime .task_manager() .spawn_and_block_on(async move { - let (shutdown, _abort_handle) = + let (mut shutdown, _abort_handle) = futures::future::abortable(futures::future::pending::<()>()); - hyper::Server::bind(&address) - .serve(Shared::new(service)) - .with_graceful_shutdown(async { - let _ = shutdown.await; - tracing::info!("Shutting down gracefully"); - }) - .await + let listener = tokio::net::TcpListener::bind(&address).await?; + let graceful = hyper_util::server::graceful::GracefulShutdown::new(); + + let http = hyper::server::conn::http1::Builder::new(); + + let mut futs = FuturesUnordered::new(); + + loop { + tokio::select! { + Ok((stream, _addr)) = listener.accept() => { + let io = hyper_util::rt::tokio::TokioIo::new(stream); + let service = hyper_util::service::TowerToHyperService::new(service.clone()); + let conn = http.serve_connection(io, service); + // watch this connection + let fut = graceful.watch(conn); + futs.push(async move { + if let Err(e) = fut.await { + eprintln!("Error serving connection: {:?}", e); + } + }); + }, + + _ = futs.next() => {} + + _ = &mut shutdown => { + tracing::info!("Shutting down gracefully"); + // stop the accept loop + break; + } + } + } + + Ok::<_, anyhow::Error>(()) }) .context("Unable to start the server")??; diff --git a/lib/wasix/src/runners/mod.rs b/lib/wasix/src/runners/mod.rs index 949ac65b397..25ccfc939f4 100644 --- a/lib/wasix/src/runners/mod.rs +++ b/lib/wasix/src/runners/mod.rs @@ -11,9 +11,56 @@ mod wasi_common; #[cfg(feature = "webc_runner_rt_wcgi")] pub mod wcgi; +#[cfg(any(feature = "webc_runner_rt_wcgi", feature = "webc_runner_rt_dproxy"))] +mod body { + use http_body_util::{combinators::BoxBody, BodyExt, Full}; + + pub type Body = BoxBody; + + pub fn body_from_data(data: impl Into) -> Body { + BoxBody::new(Full::new(data.into()).map_err(|_| -> anyhow::Error { unreachable!() })) + } + + pub fn body_from_stream(s: S) -> Body + where + S: futures::stream::Stream, anyhow::Error>> + + Send + + Sync + + 'static, + { + BoxBody::new(http_body_util::StreamBody::new(s)) + } +} + +#[cfg(any(feature = "webc_runner_rt_wcgi", feature = "webc_runner_rt_dproxy"))] +pub use self::body::*; + pub use self::{ runner::Runner, wasi_common::{ MappedCommand, MappedDirectory, MountedDirectory, MAPPED_CURRENT_DIR_DEFAULT_PATH, }, }; + +// For some reason, providing the same code to on_response() in a lambda +// causes lifetime-related errors, so we use an owned struct instead to +// make *absolutely* sure it's 'static. +#[cfg(any(feature = "webc_runner_rt_wcgi", feature = "webc_runner_rt_dproxy"))] +mod response_tracing { + use tower_http::trace::OnResponse; + + #[derive(Clone, Copy)] + pub struct OnResponseTracer; + + impl OnResponse for OnResponseTracer { + fn on_response( + self, + response: &http::Response, + _latency: std::time::Duration, + span: &tracing::Span, + ) { + span.record("status_code", &tracing::field::display(response.status())); + tracing::info!("response generated") + } + } +} diff --git a/lib/wasix/src/runners/wcgi/handler.rs b/lib/wasix/src/runners/wcgi/handler.rs index 4c2f0938599..5d4c5b5f898 100644 --- a/lib/wasix/src/runners/wcgi/handler.rs +++ b/lib/wasix/src/runners/wcgi/handler.rs @@ -1,9 +1,11 @@ -use std::{collections::HashMap, ops::Deref, pin::Pin, sync::Arc, task::Poll}; +use std::{collections::HashMap, ops::Deref, pin::Pin, sync::Arc}; use anyhow::Error; -use futures::{Future, FutureExt, StreamExt}; +use bytes::Bytes; +use futures::{Future, FutureExt}; use http::{Request, Response, StatusCode}; -use hyper::{service::Service, Body}; +use http_body_util::BodyExt; +use hyper::body::Frame; use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncWrite, AsyncWriteExt}; use tracing::Instrument; use virtual_mio::InlineWaker; @@ -11,12 +13,17 @@ use wasmer::Module; use wasmer_wasix_types::wasi::ExitCode; use wcgi_host::CgiDialect; +use super::super::Body; + use crate::{ bin_factory::run_exec, os::task::OwnedTaskStatus, - runners::wcgi::{ - callbacks::{CreateEnvConfig, RecycleEnvConfig}, - Callbacks, + runners::{ + body_from_data, body_from_stream, + wcgi::{ + callbacks::{CreateEnvConfig, RecycleEnvConfig}, + Callbacks, + }, }, runtime::task_manager::{TaskWasm, TaskWasmRecycleProperties}, Runtime, VirtualTaskManager, WasiEnvBuilder, @@ -36,7 +43,7 @@ impl Handler { #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn handle( &self, - req: Request, + req: Request, token: T, ) -> Result, Error> where @@ -155,7 +162,7 @@ impl Handler { if !stderr.is_empty() { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(stderr))?); + .body(body_from_data(stderr))?); } } } else { @@ -175,7 +182,7 @@ impl Handler { tracing::error!(error = e, "Unable to drive the request to completion"); return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(e.as_bytes().to_vec()))?); + .body(body_from_data(Bytes::from(e)))?); } } @@ -200,14 +207,14 @@ impl Handler { match r.fill_buf().await { Ok(chunk) if chunk.is_empty() => Ok(None), Ok(chunk) => { - let chunk = chunk.to_vec(); + let chunk: bytes::Bytes = chunk.to_vec().into(); r.consume(chunk.len()); - Ok(Some((chunk, r))) + Ok(Some((Frame::data(chunk), r))) } - Err(e) => Err(e), + Err(e) => Err(anyhow::Error::from(e)), } }); - let body = hyper::Body::wrap_stream(chunks); + let body = body_from_stream(chunks); tracing::trace!( dialect=%self.dialect, @@ -231,7 +238,7 @@ impl Deref for Handler { /// instance and waiting for it to exit. async fn drive_request_to_completion( finished: Arc, - mut request_body: hyper::Body, + mut request_body: hyper::body::Incoming, mut instance_stdin: impl AsyncWrite + Send + Sync + Unpin + 'static, ) -> Result { let request_body_send = async move { @@ -239,12 +246,16 @@ async fn drive_request_to_completion( // dies before we finish writing the body, the instance's side of the // pipe will be automatically closed and we'll error out. let mut request_size = 0; - while let Some(res) = request_body.next().await { + while let Some(res) = request_body.frame().await { // FIXME(theduke): figure out how to propagate a body error to the // CGI instance. let chunk = res?; - request_size += chunk.len(); - instance_stdin.write_all(chunk.as_ref()).await?; + if let Some(data) = chunk.data_ref() { + request_size += data.len(); + instance_stdin.write_all(data.as_ref()).await?; + } else { + // Trailers are not supported... + } } instance_stdin.shutdown().await?; @@ -323,17 +334,19 @@ pub(crate) struct SharedState { pub(crate) runtime: Arc, } -impl Service> for Handler { +impl tower::Service> for Handler { type Response = Response; type Error = Error; type Future = Pin, Error>> + Send>>; - fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll> { - // TODO: We probably should implement some sort of backpressure here... - Poll::Ready(Ok(())) + fn poll_ready( + &mut self, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + std::task::Poll::Ready(Ok(())) } - fn call(&mut self, request: Request) -> Self::Future { + fn call(&mut self, request: Request) -> Self::Future { // Note: all fields are reference-counted so cloning is pretty cheap let handler = self.clone(); let fut = async move { handler.handle(request, ()).await }; diff --git a/lib/wasix/src/runners/wcgi/runner.rs b/lib/wasix/src/runners/wcgi/runner.rs index b814694fefe..f1ddc8f6376 100644 --- a/lib/wasix/src/runners/wcgi/runner.rs +++ b/lib/wasix/src/runners/wcgi/runner.rs @@ -1,11 +1,11 @@ -use std::{net::SocketAddr, sync::Arc, time::Duration}; +use std::{net::SocketAddr, sync::Arc}; +use super::super::Body; use anyhow::{Context, Error}; +use futures::{stream::FuturesUnordered, StreamExt}; use http::{Request, Response}; -use hyper::Body; -use tower::{make::Shared, Service, ServiceBuilder}; +use tower::ServiceBuilder; use tower_http::{catch_panic::CatchPanicLayer, cors::CorsLayer, trace::TraceLayer}; -use tracing::Span; use wcgi_host::CgiDialect; use webc::metadata::{ annotations::{Wasi, Wcgi}, @@ -100,8 +100,8 @@ impl WcgiRunner { runtime: Arc, ) -> Result<(), Error> where - S: Service< - Request, + S: tower::Service< + Request, Response = http::Response, Error = anyhow::Error, Future = std::pin::Pin< @@ -113,7 +113,7 @@ impl WcgiRunner { let service = ServiceBuilder::new() .layer( TraceLayer::new_for_http() - .make_span_with(|request: &Request| { + .make_span_with(|request: &Request| { tracing::info_span!( "request", method = %request.method(), @@ -121,10 +121,7 @@ impl WcgiRunner { status_code = tracing::field::Empty, ) }) - .on_response(|response: &Response<_>, _latency: Duration, span: &Span| { - span.record("status_code", &tracing::field::display(response.status())); - tracing::info!("response generated") - }), + .on_response(super::super::response_tracing::OnResponseTracer), ) .layer(CatchPanicLayer::new()) .layer(CorsLayer::permissive()) @@ -134,23 +131,46 @@ impl WcgiRunner { tracing::info!(%address, "Starting the server"); let callbacks = Arc::clone(&self.config.callbacks); - runtime - .task_manager() - .spawn_and_block_on(async move { - let (shutdown, abort_handle) = - futures::future::abortable(futures::future::pending::<()>()); - - callbacks.started(abort_handle); - - hyper::Server::bind(&address) - .serve(Shared::new(service)) - .with_graceful_shutdown(async { - let _ = shutdown.await; - tracing::info!("Shutting down gracefully"); - }) - .await - }) - .context("Unable to start the server")??; + runtime.task_manager().spawn_and_block_on(async move { + let (mut shutdown, abort_handle) = + futures::future::abortable(futures::future::pending::<()>()); + + callbacks.started(abort_handle); + + let listener = tokio::net::TcpListener::bind(&address).await?; + let graceful = hyper_util::server::graceful::GracefulShutdown::new(); + + let http = hyper::server::conn::http1::Builder::new(); + + let mut futs = FuturesUnordered::new(); + + loop { + tokio::select! { + Ok((stream, _addr)) = listener.accept() => { + let io = hyper_util::rt::tokio::TokioIo::new(stream); + let service = hyper_util::service::TowerToHyperService::new(service.clone()); + let conn = http.serve_connection(io, service); + // watch this connection + let fut = graceful.watch(conn); + futs.push(async move { + if let Err(e) = fut.await { + eprintln!("Error serving connection: {:?}", e); + } + }); + }, + + _ = futs.next() => {} + + _ = &mut shutdown => { + eprintln!("graceful shutdown signal received"); + // stop the accept loop + break; + } + } + } + + Ok::<_, anyhow::Error>(()) + })??; Ok(()) } diff --git a/lib/wasix/src/runtime/resolver/backend_source.rs b/lib/wasix/src/runtime/resolver/backend_source.rs index 27aa45dda30..00fd3491b54 100644 --- a/lib/wasix/src/runtime/resolver/backend_source.rs +++ b/lib/wasix/src/runtime/resolver/backend_source.rs @@ -717,7 +717,7 @@ mod tests { use crate::{ http::HttpResponse, - runtime::resolver::inputs::{DistributionInfo, FileSystemMapping, PackageInfo}, + runtime::resolver::inputs::{DistributionInfo, PackageInfo}, }; use super::*; diff --git a/tests/integration/cli/Cargo.toml b/tests/integration/cli/Cargo.toml index d31c100a7e4..ed9e4a8e1df 100644 --- a/tests/integration/cli/Cargo.toml +++ b/tests/integration/cli/Cargo.toml @@ -16,7 +16,7 @@ md5 = "0.7.0" hex = "0.4.3" pretty_assertions = "1.3.0" object = "0.30.0" -reqwest = { version = "0.11.14", default-features = false, features = ["json", "blocking", "rustls-tls"] } +reqwest = { workspace = true, default-features = false, features = ["json", "blocking", "rustls-tls"] } tokio = { version = "1", features = [ "rt", "rt-multi-thread", "macros" ] } assert_cmd = "2.0.8" predicates = "2.1.5" diff --git a/tests/wasmer-argus/Cargo.toml b/tests/wasmer-argus/Cargo.toml index cadc8d6cfcb..be3c984542f 100644 --- a/tests/wasmer-argus/Cargo.toml +++ b/tests/wasmer-argus/Cargo.toml @@ -33,7 +33,7 @@ shared-buffer.workspace = true [target.'cfg(not(target_arch = "riscv64"))'.dependencies] -reqwest = { version = "^0.11", default-features = false, features = [ +reqwest = { workspace = true, default-features = false, features = [ "rustls-tls", "json", "multipart", @@ -41,7 +41,7 @@ reqwest = { version = "^0.11", default-features = false, features = [ ] } [target.'cfg(target_arch = "riscv64")'.dependencies] -reqwest = { version = "^0.11", default-features = false, features = [ +reqwest = { workspace = true, default-features = false, features = [ "native-tls", "json", "multipart",