From c5f1655a6b5a2c872bc19e18780c6d971fa9241d Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Thu, 17 Oct 2024 11:14:17 +0200 Subject: [PATCH] Update to ureq 3.0.0-rc1 (#143) * Update to ureq 3.0.0-rc1 * Update CHANGELOG * oops * Just allow MPL-2.0 * Fix rebase * Add basic HTTP retry due to EOF I/O errors * Update CHANGELOG --- CHANGELOG.md | 3 + Cargo.lock | 747 ++++++++++---------------------------- Cargo.toml | 6 +- deny.toml | 3 +- src/ctx.rs | 144 ++++++-- src/lib.rs | 2 +- src/main.rs | 18 +- tests/compiles.rs | 6 +- tests/deterministic.rs | 3 +- tests/snapshots/xwin.snap | 7 + 10 files changed, 346 insertions(+), 593 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b3959a..528371f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate ### Fixed +- [PR#143](https://github.com/Jake-Shadle/xwin/pull/142) is a second attempt to resolve [#141](https://github.com/Jake-Shadle/xwin/issues/141) by switching to a new `3.0.0-rc1` version of ureq that might not have the same issue, as well as adding support for retries of EOF I/O errors seen by users which can be configured via `--http-retry` or `XWIN_HTTP_RETRY`. + +### Fixed (failed) - [PR#142](https://github.com/Jake-Shadle/xwin/pull/142) is an attempt to resolve [#141](https://github.com/Jake-Shadle/xwin/issues/141) by switching from `ureq` to `reqwest`. ## [0.6.5] - 2024-08-21 diff --git a/Cargo.lock b/Cargo.lock index 5755477..8207dee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.0" @@ -90,46 +81,24 @@ dependencies = [ "derive_arbitrary", ] -[[package]] -name = "async-compression" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e26a9844c659a2a293d239c7910b752f8487fe122c6c8bd1659bf85a6507c302" -dependencies = [ - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", -] - [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "2.6.0" @@ -190,6 +159,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfb" version = "0.10.0" @@ -264,6 +239,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "console" version = "0.15.8" @@ -355,6 +340,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.11" @@ -479,56 +474,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -550,12 +495,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "hashbrown" version = "0.15.0" @@ -569,10 +508,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "hermit-abi" -version = "0.3.9" +name = "hoot" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "6a018c1f2075066355e95ac5ab7909d35a84c9d14d1fae84c4bacdf6dec188d8" +dependencies = [ + "http", + "httparse", + "log", + "url", +] [[package]] name = "http" @@ -585,107 +530,12 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -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", -] - [[package]] name = "httparse" version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" -[[package]] -name = "hyper" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -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.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - [[package]] name = "idna" version = "0.5.0" @@ -740,12 +590,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "ipnet" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" - [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -768,14 +612,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "js-sys" -version = "0.3.72" +name = "jni" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" dependencies = [ - "wasm-bindgen", + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", ] +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "lazy_static" version = "1.5.0" @@ -784,9 +639,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "f0b21006cd1874ae9e650973c565615676dc4a274c965bb0a73796dac838ce4f" [[package]] name = "libmimalloc-sys" @@ -862,12 +717,6 @@ dependencies = [ "libmimalloc-sys", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -883,18 +732,6 @@ dependencies = [ "adler2", ] -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", -] - [[package]] name = "msi" version = "0.8.0" @@ -934,6 +771,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -941,20 +788,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] -name = "number_prefix" -version = "0.4.0" +name = "num-integer" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] [[package]] -name = "object" -version = "0.36.5" +name = "num-traits" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "memchr", + "autocfg", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "once_cell" version = "1.20.2" @@ -963,9 +819,9 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" -version = "0.10.67" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8cefcf97f41316955f9294cd61f639bdcfa9f2f230faac6cb896aa8ab64704" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags", "cfg-if", @@ -1038,6 +894,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1050,12 +915,6 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "pkg-config" version = "0.3.31" @@ -1085,61 +944,13 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] -[[package]] -name = "quinn" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" -dependencies = [ - "bytes", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "quinn-proto" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" -dependencies = [ - "bytes", - "rand", - "ring", - "rustc-hash", - "rustls", - "slab", - "thiserror", - "tinyvec", - "tracing", -] - -[[package]] -name = "quinn-udp" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" -dependencies = [ - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.59.0", -] - [[package]] name = "quote" version = "1.0.37" @@ -1252,54 +1063,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.12.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" -dependencies = [ - "async-compression", - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pemfile", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tokio-rustls", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots", - "windows-registry", -] - [[package]] name = "ring" version = "0.17.8" @@ -1315,18 +1078,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" - [[package]] name = "rustix" version = "0.38.37" @@ -1342,10 +1093,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ + "log", "once_cell", "ring", "rustls-pki-types", @@ -1354,6 +1106,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -1369,6 +1134,33 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +[[package]] +name = "rustls-platform-verifier" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-roots", + "winapi", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.102.8" @@ -1420,6 +1212,7 @@ dependencies = [ "core-foundation", "core-foundation-sys", "libc", + "num-bigint", "security-framework-sys", ] @@ -1474,18 +1267,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha2" version = "0.10.8" @@ -1524,15 +1305,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - [[package]] name = "smallvec" version = "1.13.2" @@ -1540,13 +1312,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "socket2" -version = "0.5.7" +name = "socks" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" dependencies = [ + "byteorder", "libc", - "windows-sys 0.52.0", + "winapi", ] [[package]] @@ -1584,15 +1357,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -dependencies = [ - "futures-core", -] - [[package]] name = "tempfile" version = "3.13.0" @@ -1689,55 +1453,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" -dependencies = [ - "rustls", - "rustls-pki-types", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - [[package]] name = "toml" version = "0.8.19" @@ -1772,12 +1487,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - [[package]] name = "tracing" version = "0.1.40" @@ -1838,12 +1547,6 @@ dependencies = [ "tracing-serde", ] -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "twox-hash" version = "1.6.3" @@ -1894,6 +1597,33 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "3.0.0-rc1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443349052924188e919be78d5870f6e827435579085947d1ae9ba32bb997e16f" +dependencies = [ + "base64", + "cc", + "der", + "flate2", + "hoot", + "http", + "log", + "native-tls", + "once_cell", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "rustls-platform-verifier", + "smallvec", + "socks", + "thiserror", + "utf-8", + "webpki-root-certs", + "webpki-roots", +] + [[package]] name = "url" version = "2.5.2" @@ -1905,6 +1635,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1955,15 +1691,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1971,80 +1698,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasm-bindgen" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" -dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" - -[[package]] -name = "web-sys" -version = "0.3.72" +name = "webpki-root-certs" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "e8c6dfa3ac045bc517de14c7b1384298de1dbd229d38e08e169d9ae8c170937c" dependencies = [ - "js-sys", - "wasm-bindgen", + "rustls-pki-types", ] [[package]] @@ -2057,43 +1716,35 @@ dependencies = [ ] [[package]] -name = "winapi-util" -version = "0.1.9" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "windows-sys 0.59.0", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "windows-registry" -version = "0.2.0" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets", -] +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] -name = "windows-result" -version = "0.2.0" +name = "winapi-util" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-targets", + "windows-sys 0.59.0", ] [[package]] -name = "windows-strings" -version = "0.1.0" +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets", -] +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" @@ -2206,7 +1857,6 @@ dependencies = [ "parking_lot", "rayon", "regex", - "reqwest", "serde", "serde_json", "sha2", @@ -2215,6 +1865,7 @@ dependencies = [ "tracing", "tracing-subscriber", "twox-hash", + "ureq", "versions", "walkdir", "zip", diff --git a/Cargo.toml b/Cargo.toml index 79120aa..b295cd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,10 +22,10 @@ exclude = [ [features] # By default we use rustls for TLS default = ["rustls-tls"] -rustls-tls = ["reqwest/rustls-tls"] +rustls-tls = ["ureq/rustls"] # If this feature is enabled we instead use the native TLS implementation for the # target platform -native-tls = ["reqwest/native-tls", "native-tls-crate/vendored"] +native-tls = ["ureq/native-tls", "native-tls-crate/vendored"] [dependencies] # Easy errors @@ -49,7 +49,7 @@ rayon = "1.5" # Include scanning regex = "1.11" # HTTP requests -reqwest = { version = "0.12", default-features = false, features = ["gzip", "blocking"] } +ureq = { version = "3.0.0-rc1", default-features = false, features = ["gzip", "socks-proxy"] } memchr = "2.6" native-tls-crate = { package = "native-tls", version = "0.2", optional = true } # SHA-256 verification diff --git a/deny.toml b/deny.toml index a53f4c8..20f9cef 100644 --- a/deny.toml +++ b/deny.toml @@ -11,9 +11,8 @@ all-features = true ignore = [] [licenses] -allow = ["MIT", "Apache-2.0", "BSD-3-Clause", "ISC"] +allow = ["MIT", "Apache-2.0", "BSD-3-Clause", "ISC", "MPL-2.0"] exceptions = [ - { allow = ["MPL-2.0"], name = "webpki-roots" }, # ring uses code from multiple libraries but all with permissive licenses # https://tldrlegal.com/license/openssl-license-(openssl) { allow = ["ISC", "MIT", "OpenSSL"], name = "ring" }, diff --git a/src/ctx.rs b/src/ctx.rs index 3b567e7..1948bc5 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -4,7 +4,6 @@ use crate::{ Path, PathBuf, WorkItem, }; use anyhow::{Context as _, Error}; -use reqwest::blocking::Client; #[allow(dead_code)] pub enum Unpack { @@ -20,12 +19,17 @@ pub enum Unpack { pub struct Ctx { pub work_dir: PathBuf, pub tempdir: Option, - pub client: Client, + pub client: ureq::Agent, pub draw_target: ProgressTarget, + pub http_retry: u8, } impl Ctx { - pub fn with_temp(dt: ProgressTarget, client: Client) -> Result { + pub fn with_temp( + dt: ProgressTarget, + client: ureq::Agent, + http_retry: u8, + ) -> Result { let td = tempfile::TempDir::new()?; Ok(Self { @@ -35,13 +39,15 @@ impl Ctx { tempdir: Some(td), client, draw_target: dt, + http_retry, }) } pub fn with_dir( mut work_dir: PathBuf, dt: ProgressTarget, - client: Client, + client: ureq::Agent, + http_retry: u8, ) -> Result { work_dir.push("dl"); std::fs::create_dir_all(&work_dir)?; @@ -55,6 +61,7 @@ impl Ctx { tempdir: None, client, draw_target: dt, + http_retry, }) } @@ -63,7 +70,7 @@ impl Ctx { url: impl AsRef, path: &P, checksum: Option, - progress: indicatif::ProgressBar, + mut progress: indicatif::ProgressBar, ) -> Result where P: AsRef + std::fmt::Debug, @@ -108,21 +115,25 @@ impl Ctx { } } - let mut res = self.client.get(url.as_ref()).send()?; - - let content_length = res.content_length().unwrap_or_default(); - progress.inc_length(content_length); - - let body = bytes::BytesMut::with_capacity(content_length as usize); + use bytes::BufMut; struct ProgressCopy { progress: indicatif::ProgressBar, inner: bytes::buf::Writer, + failed: usize, + written: usize, } impl std::io::Write for ProgressCopy { fn write(&mut self, buf: &[u8]) -> std::io::Result { - self.progress.inc(buf.len() as u64); + self.written += buf.len(); + if self.failed == 0 { + self.progress.inc(buf.len() as u64); + } else if self.written > self.failed { + self.progress.inc((self.written - self.failed) as u64); + self.failed = 0; + } + self.inner.write(buf) } @@ -131,32 +142,107 @@ impl Ctx { } } - use bytes::BufMut; + enum DownloadError { + Ureq(ureq::Error), + Io(std::io::Error), + Retry((bytes::BytesMut, indicatif::ProgressBar)), + } + + let try_download = |mut body: bytes::BytesMut, + progress: indicatif::ProgressBar| + -> Result { + let res = self + .client + .get(url.as_ref()) + .call() + .map_err(DownloadError::Ureq)?; + + let content_length = res + .headers() + .get("content-length") + .and_then(|header| header.to_str().ok()?.parse().ok()) + .unwrap_or_default(); + + if body.capacity() > 0 { + if body.capacity() as u64 != content_length { + tracing::warn!(url = url.as_ref(), "a previous HTTP GET had a content-length of {}, but we now received a content-length of {content_length}", body.capacity()); + + if body.capacity() as u64 > content_length { + progress.inc_length(body.capacity() as u64 - content_length); + } else { + body.reserve(content_length as usize - body.capacity()); + } + } + } else { + body.reserve(content_length as usize); + progress.inc_length(content_length); + } + + let failed = body.len(); + body.clear(); - let mut pc = ProgressCopy { - progress, - inner: body.writer(), + let mut pc = ProgressCopy { + progress, + inner: body.writer(), + failed, + written: 0, + }; + + let res = std::io::copy(&mut res.into_body().as_reader(), &mut pc); + let body = pc.inner.into_inner(); + + match res { + Ok(_) => Ok(body), + Err(ref err) if err.kind() == std::io::ErrorKind::UnexpectedEof => { + Err(DownloadError::Retry((body, pc.progress))) + } + Err(err) => Err(DownloadError::Io(err)), + } }; - res.copy_to(&mut pc)?; + let mut tries = self.http_retry + 1; + let total = tries; + let mut body = bytes::BytesMut::new(); - let body = pc.inner.into_inner().freeze(); + while tries > 0 { + match try_download(body, progress) { + Ok(body) => { + let body = body.freeze(); - if let Some(expected) = checksum { - let chksum = Sha256::digest(&body); + if let Some(expected) = checksum { + let chksum = Sha256::digest(&body); - anyhow::ensure!( - chksum == expected, - "checksum mismatch, expected {expected} != actual {chksum}" - ); - } + anyhow::ensure!( + chksum == expected, + "checksum mismatch, expected {expected} != actual {chksum}" + ); + } - if let Some(parent) = cache_path.parent() { - std::fs::create_dir_all(parent)?; + if let Some(parent) = cache_path.parent() { + std::fs::create_dir_all(parent)?; + } + + std::fs::write(cache_path, &body)?; + return Ok(body); + } + Err(DownloadError::Retry((b, prog))) => { + tries -= 1; + body = b; + progress = prog; + continue; + } + Err(DownloadError::Ureq(err)) => { + return Err(err) + .with_context(|| format!("HTTP GET request for {} failed", url.as_ref())); + } + Err(DownloadError::Io(err)) => { + return Err(err) + .with_context(|| format!("failed to retrieve body for {}", url.as_ref())); + } + } } - std::fs::write(cache_path, &body)?; - Ok(body) + anyhow::bail!("failed to retrieve {} after {total} tries due to I/O failures reading the response body, try using --http-retries to increase the retry count", url.as_ref()); } #[allow(clippy::too_many_arguments)] diff --git a/src/lib.rs b/src/lib.rs index b212d80..5aad5d6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,8 +17,8 @@ pub mod util; pub use ctx::Ctx; pub use minimize::MinimizeConfig; -pub use reqwest; pub use splat::SplatConfig; +pub use ureq; #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum Arch { diff --git a/src/main.rs b/src/main.rs index a94f251..9f364a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -230,6 +230,10 @@ pub struct Args { /// An HTTPS proxy to use #[arg(long, env = "HTTPS_PROXY")] https_proxy: Option, + /// The number of times an HTTP get will be retried if it fails due to I/O + /// failures + #[arg(long, env = "XWIN_HTTP_RETRY", default_value = "0")] + http_retry: u8, /// The architectures to include #[arg( long, @@ -275,25 +279,25 @@ fn main() -> Result<(), Error> { let draw_target = xwin::util::ProgressTarget::Stdout; let client = { - let mut builder = reqwest::blocking::Client::builder().timeout(args.timeout); + let mut builder = ureq::Config::new(); + builder.timeouts.recv_body = Some(args.timeout); if let Some(proxy) = args.https_proxy { - let proxy = - reqwest::Proxy::all(proxy).context("failed to parse https proxy address")?; - builder = builder.proxy(proxy); + let proxy = ureq::Proxy::new(&proxy).context("failed to parse https proxy address")?; + builder.proxy = Some(proxy); } - builder.build()? + ureq::Agent::new_with_config(builder) }; let ctx = if args.temp { - xwin::Ctx::with_temp(draw_target, client)? + xwin::Ctx::with_temp(draw_target, client, args.http_retry)? } else { let cache_dir = match &args.cache_dir { Some(cd) => cd.clone(), None => cwd.join(".xwin-cache"), }; - xwin::Ctx::with_dir(cache_dir, draw_target, client)? + xwin::Ctx::with_dir(cache_dir, draw_target, client, args.http_retry)? }; let ctx = std::sync::Arc::new(ctx); diff --git a/tests/compiles.rs b/tests/compiles.rs index b62125d..f9a1236 100644 --- a/tests/compiles.rs +++ b/tests/compiles.rs @@ -3,7 +3,8 @@ fn verify_compiles() { let ctx = xwin::Ctx::with_dir( xwin::PathBuf::from(".xwin-cache/compile-test"), xwin::util::ProgressTarget::Hidden, - reqwest::blocking::Client::new(), + ureq::agent(), + 0, ) .unwrap(); @@ -166,7 +167,8 @@ fn verify_compiles_minimized() { let ctx = xwin::Ctx::with_dir( xwin::PathBuf::from(".xwin-cache/compile-test-minimized"), xwin::util::ProgressTarget::Hidden, - reqwest::blocking::Client::new(), + ureq::agent(), + 0, ) .unwrap(); diff --git a/tests/deterministic.rs b/tests/deterministic.rs index 3f75259..223d6f5 100644 --- a/tests/deterministic.rs +++ b/tests/deterministic.rs @@ -6,7 +6,8 @@ fn verify_deterministic() { let ctx = xwin::Ctx::with_dir( PathBuf::from(".xwin-cache/deterministic"), xwin::util::ProgressTarget::Hidden, - reqwest::blocking::Client::new(), + ureq::agent(), + 0, ) .unwrap(); diff --git a/tests/snapshots/xwin.snap b/tests/snapshots/xwin.snap index 68145c7..61ab56f 100644 --- a/tests/snapshots/xwin.snap +++ b/tests/snapshots/xwin.snap @@ -84,6 +84,13 @@ Options: [env: HTTPS_PROXY] + --http-retry + The number of times an HTTP get will be retried if it fails due to I/O + failures + + [env: XWIN_HTTP_RETRY] + [default: 0] + --arch The architectures to include