use std::time::Duration;
use ureq::tls::TlsConfig;
pub fn fetch(url: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let agent = ureq::Agent::new_with_config(
ureq::Agent::config_builder()
.tls_config(TlsConfig::builder().build())
.build(),
);
let attempts = 2;
for attempt in 1..=attempts {
match try_fetch(&agent, url) {
Ok(body) => return Ok(body),
Err(e) if attempt < attempts => {
eprintln!(
"npm-utils: download attempt {attempt}/{attempts} failed for {url}: {e}; \
retrying in 500ms"
);
std::thread::sleep(Duration::from_millis(500));
}
Err(e) => return Err(e),
}
}
unreachable!()
}
fn try_fetch(agent: &ureq::Agent, url: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let mut response = agent.get(url).call()?;
let body = response.body_mut();
Ok(body.with_config().limit(100 * 1024 * 1024).read_to_vec()?)
}
pub fn github_archive_url(owner: &str, repo: &str, git_ref: &str) -> String {
format!("https://github.com/{owner}/{repo}/archive/{git_ref}.zip")
}