From 4a4db1b62e4f3588a1c79f382c1eef86c7bc8406 Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 15 Aug 2024 16:22:01 -0400 Subject: [PATCH] bootstrap: improve error recovery flags to curl alternative to #128459 fixes #110178 --- src/bootstrap/bootstrap.py | 8 +++++++- src/bootstrap/src/core/download.rs | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 4e8e0fd2532f1..4cf4318bde9b9 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -79,6 +79,8 @@ def get(base, url, path, checksums, verbose=False): eprint("removing", temp_path) os.unlink(temp_path) +def curl_version(): + return re.match("^curl ([0-9]+\\.[0-9]+)", run(["curl", "-V"]))[1] def download(path, url, probably_big, verbose): for _ in range(4): @@ -107,11 +109,15 @@ def _download(path, url, probably_big, verbose, exception): # If curl is not present on Win32, we should not sys.exit # but raise `CalledProcessError` or `OSError` instead require(["curl", "--version"], exception=platform_is_win32()) - run(["curl", option, + extra_flags = [] + if curl_version() > 7.70: + extra_flags = [ "--retry-all-errors" ] + run(["curl", option] + extra_flags + [ "-L", # Follow redirect. "-y", "30", "-Y", "10", # timeout if speed is < 10 bytes/sec for > 30 seconds "--connect-timeout", "30", # timeout if cannot connect within 30 seconds "-o", path, + "--continue-at", "-", "--retry", "3", "-SRf", url], verbose=verbose, exception=True, # Will raise RuntimeError on failure diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 4d1aea3cd956a..f4c9e7c48997b 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -21,6 +21,15 @@ fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> { config.try_run(cmd) } +fn curl_version() -> f32 { + let mut curl = Command::new("curl"); + curl.arg("-V"); + let Ok(out) = curl.output() else { return 0.0 }; + let out = out.stdout; + let Some(i) = out[5..].iter().position(|&x| x == b' ') else { return 0.0 }; + std::str::from_utf8(&out[5..i + 5]).unwrap().parse().unwrap_or(0.0) +} + /// Generic helpers that are useful anywhere in bootstrap. impl Config { pub fn is_verbose(&self) -> bool { @@ -219,6 +228,8 @@ impl Config { "30", // timeout if cannot connect within 30 seconds "-o", tempfile.to_str().unwrap(), + "--continue-at", + "-", "--retry", "3", "-SRf", @@ -229,6 +240,10 @@ impl Config { } else { curl.arg("--progress-bar"); } + // --retry-all-errors was added in 7.71.0, don't use it if curl is old. + if curl_version() > 7.70 { + curl.arg("--retry-all-errors"); + } curl.arg(url); if !self.check_run(&mut curl) { if self.build.contains("windows-msvc") {