in src/api/sync.rs [576:617]
fn download_tempfile<P: Progress>(
&self,
url: &str,
size: usize,
mut progress: P,
tmp_path: PathBuf,
filename: &str,
) -> Result<PathBuf, ApiError> {
progress.init(size, filename);
let filepath = tmp_path;
// Create the file and set everything properly
let mut file = match std::fs::OpenOptions::new().append(true).open(&filepath) {
Ok(f) => f,
Err(_) => std::fs::File::create(&filepath)?,
};
// In case of resume.
let start = file.metadata()?.len();
if start > size as u64 {
return Err(ApiError::InvalidResume);
}
let mut res = self.download_from(url, start, size, &mut file, filename, &mut progress);
if self.max_retries > 0 {
let mut i = 0;
while let Err(dlerr) = res {
let wait_time = exponential_backoff(300, i, 10_000);
std::thread::sleep(std::time::Duration::from_millis(wait_time as u64));
let current = file.stream_position()?;
res = self.download_from(url, current, size, &mut file, filename, &mut progress);
i += 1;
if i > self.max_retries {
return Err(ApiError::TooManyRetries(dlerr.into()));
}
}
}
res?;
Ok(filepath)
}