diff --git a/src/bin/download_sysext.rs b/src/bin/download_sysext.rs index 1556710..7f1b531 100644 --- a/src/bin/download_sysext.rs +++ b/src/bin/download_sysext.rs @@ -4,7 +4,6 @@ use std::path::{Path, PathBuf}; use std::fs::File; use std::fs; use std::io; -use std::io::{Read, Seek, SeekFrom}; use std::io::BufReader; #[macro_use] @@ -18,6 +17,7 @@ use reqwest::redirect::Policy; use url::Url; use update_format_crau::delta_update; +use ue_rs::hash_on_disk_sha256; #[derive(Debug)] enum PackageStatus { @@ -45,51 +45,7 @@ impl<'a> Package<'a> { // If maxlen is None, a simple read to the end of the file. // If maxlen is Some, read only until the given length. fn hash_on_disk(&mut self, path: &Path, maxlen: Option) -> Result> { - use sha2::{Sha256, Digest}; - - let file = File::open(path).context({ - format!("failed to open path({:?})", path.display()) - })?; - let mut hasher = Sha256::new(); - - let filelen = file.metadata().unwrap().len() as usize; - - let mut maxlen_to_read: usize = match maxlen { - Some(len) => { - if filelen < len { - filelen - } else { - len - } - } - None => filelen, - }; - - const CHUNKLEN: usize = 10485760; // 10M - - let mut freader = BufReader::new(file); - let mut chunklen: usize; - - freader.seek(SeekFrom::Start(0)).context("failed to seek(0)".to_string())?; - while maxlen_to_read > 0 { - if maxlen_to_read < CHUNKLEN { - chunklen = maxlen_to_read; - } else { - chunklen = CHUNKLEN; - } - - let mut databuf = vec![0u8; chunklen]; - - freader.read_exact(&mut databuf).context(format!("failed to read_exact(chunklen {:?})", chunklen))?; - - maxlen_to_read -= chunklen; - - hasher.update(&databuf); - } - - Ok(omaha::Hash::from_bytes( - hasher.finalize().into() - )) + hash_on_disk_sha256(path, maxlen) } #[rustfmt::skip] diff --git a/src/download.rs b/src/download.rs index 8ba914b..b42edee 100644 --- a/src/download.rs +++ b/src/download.rs @@ -1,6 +1,8 @@ use anyhow::{Context, Result, bail}; -use std::io::Write; +use std::io::{BufReader, Read, Seek, SeekFrom, Write}; use std::io; +use std::fs::File; +use std::path::Path; use log::info; use url::Url; @@ -13,6 +15,48 @@ pub struct DownloadResult { pub data: W, } +pub fn hash_on_disk_sha256(path: &Path, maxlen: Option) -> Result> { + let file = File::open(path).context(format!("failed to open path({:?})", path.display()))?; + let mut hasher = Sha256::new(); + + let filelen = file.metadata().context(format!("failed to get metadata of {:?}", path.display()))?.len() as usize; + + let mut maxlen_to_read: usize = match maxlen { + Some(len) => { + if filelen < len { + filelen + } else { + len + } + } + None => filelen, + }; + + const CHUNKLEN: usize = 10485760; // 10M + + let mut freader = BufReader::new(file); + let mut chunklen: usize; + + freader.seek(SeekFrom::Start(0)).context("failed to seek(0)".to_string())?; + while maxlen_to_read > 0 { + if maxlen_to_read < CHUNKLEN { + chunklen = maxlen_to_read; + } else { + chunklen = CHUNKLEN; + } + + let mut databuf = vec![0u8; chunklen]; + + freader.read_exact(&mut databuf).context(format!("failed to read_exact(chunklen {:?})", chunklen))?; + + maxlen_to_read -= chunklen; + + hasher.update(&databuf); + } + + Ok(omaha::Hash::from_bytes(hasher.finalize().into())) +} + pub async fn download_and_hash(client: &reqwest::Client, url: U, mut data: W) -> Result> where U: reqwest::IntoUrl + Clone, diff --git a/src/lib.rs b/src/lib.rs index 72dbc06..7a73d1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ mod download; +pub use download::DownloadResult; pub use download::download_and_hash; +pub use download::hash_on_disk_sha256; pub mod request;