Skip to content

Commit

Permalink
Merge pull request #24 from flatcar/dongsu/status-download-failed
Browse files Browse the repository at this point in the history
download_sysext: check for download failure
  • Loading branch information
dongsupark authored Nov 16, 2023
2 parents 58c7969 + d608308 commit f122a63
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/bin/download_sysext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use update_format_crau::delta_update;
enum PackageStatus {
ToDownload,
DownloadIncomplete(omaha::FileSize),
DownloadFailed,
BadChecksum,
Unverified,
BadSignature,
Expand Down Expand Up @@ -138,7 +139,14 @@ impl<'a> Package<'a> {
let path = into_dir.join(&*self.name);
let mut file = File::create(path)?;

let res = ue_rs::download_and_hash(&client, self.url.clone(), &mut file).await?;
let res = match ue_rs::download_and_hash(&client, self.url.clone(), &mut file).await {
Ok(ok) => ok,
Err(err) => {
error!("Downloading failed with error {}", err);
self.status = PackageStatus::DownloadFailed;
return Err("unable to download data".into());
}
};

self.verify_checksum(res.hash);
Ok(())
Expand Down Expand Up @@ -336,7 +344,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
for pkg in pkgs_to_dl.iter_mut() {
pkg.check_download(&unverified_dir)?;

pkg.download(&unverified_dir, &client).await?;
match pkg.download(&unverified_dir, &client).await {
Ok(_) => (),
_ => return Err(format!("unable to download \"{}\"", pkg.name).into()),
};

// Unverified payload is stored in e.g. "output_dir/.unverified/oem.gz".
// Verified payload is stored in e.g. "output_dir/oem.raw".
Expand Down
20 changes: 20 additions & 0 deletions src/download.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::error::Error;
use std::io::Write;
use std::io;
use log::warn;

use reqwest::StatusCode;

use sha2::{Sha256, Digest};

Expand All @@ -19,6 +22,23 @@ where
.send()
.await?;

// Return immediately on download failure on the client side.
let status = res.status();

// TODO: handle redirect with retrying with a new URL or Attempt follow.
if status.is_redirection() {
warn!("redirect with status code {:?}", status);
}

if !status.is_success() {
match status {
StatusCode::FORBIDDEN | StatusCode::NOT_FOUND => {
return Err(format!("cannnot fetch remotely with status code {:?}", status).into());
}
_ => return Err(format!("general failure with status code {:?}", status).into()),
}
}

let mut hasher = Sha256::new();

let mut bytes_read = 0usize;
Expand Down

0 comments on commit f122a63

Please sign in to comment.