download.rs (947B)
1 use crate::error::{Error, Result}; 2 3 /// Downloads a URL, retrying up to `tries` times. 4 /// 5 /// # Errors 6 /// Returns an error if all attempts fail or `tries` is 0. 7 pub fn download(url: &str, tries: u32) -> Result<ureq::http::Response<ureq::Body>> { 8 static CLIENT: std::sync::LazyLock<ureq::Agent> = 9 std::sync::LazyLock::new(ureq::Agent::new_with_defaults); 10 for attempt in 0..tries { 11 if attempt > 0 { 12 std::thread::sleep(std::time::Duration::from_millis(500 * 2u64.pow(attempt))); 13 } 14 match CLIENT.get(url).call() { 15 Ok(response) => return Ok(response), 16 Err(ureq::Error::StatusCode(code)) if code >= 400 && code < 500 => { 17 return Err(Error::HttpClientError(code)); 18 } 19 Err(ureq::Error::StatusCode(_)) => continue, 20 Err(e) => return Err(e.into()), 21 } 22 } 23 Err(Error::DownloadFailed { url: url.to_string(), tries }) 24 }