diff --git a/src/content/read.rs b/src/content/read.rs index 8284c4d..0b46284 100644 --- a/src/content/read.rs +++ b/src/content/read.rs @@ -118,8 +118,7 @@ pub fn read(cache: &Path, sri: &Integrity) -> Result> { } #[cfg(any(feature = "async-std", feature = "tokio"))] -pub async fn read_async<'c, 's>(cache: &'c Path, sri: Integrity) -> Result> { - // let cache = cache.to_path_buf(); +pub async fn read_async<'c, 's>(cache: &'c Path, sri: Integrity, verify_integrity: bool) -> Result> { let cpath = path::content_path(&cache, &sri); let ret = crate::async_lib::read(&cpath).await.with_context(|| { format!( @@ -127,14 +126,20 @@ pub async fn read_async<'c, 's>(cache: &'c Path, sri: Integrity) -> Result(ret) + let ret = if verify_integrity { + let integrity_check = move || { + sri.check(&ret)?; + Ok::<_, ssri::Error>(ret) + }; + #[cfg(feature = "tokio")] + let ret = tokio::task::spawn_blocking(integrity_check).await??; + #[cfg(feature = "async-std")] + let ret = async_std::task::spawn_blocking(integrity_check).await?; + + ret + } else { + ret }; - #[cfg(feature = "tokio")] - let ret = tokio::task::spawn_blocking(integrity_check).await??; - #[cfg(feature = "async-std")] - let ret = async_std::task::spawn_blocking(integrity_check).await?; Ok(ret) } diff --git a/src/get.rs b/src/get.rs index b481e8f..e6370d6 100644 --- a/src/get.rs +++ b/src/get.rs @@ -167,6 +167,39 @@ where inner(cache.as_ref(), key.as_ref()).await } +/// Reads the entire contents of a cache file into a bytes vector, looking the +/// data up by key. Skips integrity checking. Use this for loading large files. +/// +/// ## Example +/// ```no_run +/// use async_std::prelude::*; +/// use async_attributes; +/// +/// #[async_attributes::main] +/// async fn main() -> cacache::Result<()> { +/// let data: Vec = cacache::read_no_integrity("./my-cache", "my-key").await?; +/// Ok(()) +/// } +/// ``` +/// +/// If you have no integrity this function is for you. +#[doc(hidden)] +#[cfg(any(feature = "async-std", feature = "tokio"))] +pub async fn read_no_integrity(cache: P, key: K) -> Result> +where + P: AsRef, + K: AsRef, +{ + async fn inner(cache: &Path, key: &str) -> Result> { + if let Some(entry) = index::find_async(cache, key).await? { + read_hash_no_integrity(cache, entry.integrity).await + } else { + Err(Error::EntryNotFound(cache.to_path_buf(), key.into())) + } + } + inner(cache.as_ref(), key.as_ref()).await +} + /// Reads the entire contents of a cache file into a bytes vector, looking the /// data up by its content address. /// @@ -178,7 +211,7 @@ where /// #[async_attributes::main] /// async fn main() -> cacache::Result<()> { /// let sri = cacache::write("./my-cache", "my-key", b"hello").await?; -/// let data: Vec = cacache::read_hash("./my-cache", &sri).await?; +/// let data: Vec = cacache::read_hash("./my-cache", sri).await?; /// Ok(()) /// } /// ``` @@ -187,7 +220,33 @@ pub async fn read_hash

(cache: P, sri: Integrity) -> Result> where P: AsRef, { - read::read_async(cache.as_ref(), sri).await + read::read_async(cache.as_ref(), sri, true).await +} + +/// Reads the entire contents of a cache file into a bytes vector, looking the +/// data up by its content address. Skips integrity checking. Use this for large files. +/// +/// ## Example +/// ```no_run +/// use async_std::prelude::*; +/// use async_attributes; +/// +/// #[async_attributes::main] +/// async fn main() -> cacache::Result<()> { +/// let sri = cacache::write("./my-cache", "my-key", b"hello").await?; +/// let data: Vec = cacache::read_hash_no_integrity("./my-cache", sri).await?; +/// Ok(()) +/// } +/// ``` +/// +/// If you have no integrity this function is for you. +#[doc(hidden)] +#[cfg(any(feature = "async-std", feature = "tokio"))] +pub async fn read_hash_no_integrity

(cache: P, sri: Integrity) -> Result> +where + P: AsRef, +{ + read::read_async(cache.as_ref(), sri, false).await } /// Copies cache data to a specified location. Returns the number of bytes @@ -995,7 +1054,7 @@ mod tests { let dir = tmp.path().to_owned(); let sri = crate::write(&dir, "my-key", b"hello world").await.unwrap(); - let data = crate::read_hash(&dir, &sri).await.unwrap(); + let data = crate::read_hash(&dir, sri).await.unwrap(); assert_eq!(data, b"hello world"); } diff --git a/src/lib.rs b/src/lib.rs index 07f0826..15fe683 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,7 +66,7 @@ //! let sri = cacache::write("./my-cache", "key", b"hello").await?; //! //! // ...data gets looked up by `sri` ("Subresource Integrity"). -//! let data = cacache::read_hash("./my-cache", &sri).await?; +//! let data = cacache::read_hash("./my-cache", sri).await?; //! assert_eq!(data, b"hello"); //! //! Ok(()) diff --git a/src/put.rs b/src/put.rs index 5dc7e60..ca41187 100644 --- a/src/put.rs +++ b/src/put.rs @@ -652,7 +652,7 @@ mod tests { let integrity = crate::write_hash(&dir, &original) .await .expect("should be able to write a hash asynchronously"); - let bytes = crate::read_hash(&dir, &integrity) + let bytes = crate::read_hash(&dir, integrity) .await .expect("should be able to read back what we wrote"); let result = diff --git a/src/rm.rs b/src/rm.rs index bc15000..c2d7345 100644 --- a/src/rm.rs +++ b/src/rm.rs @@ -26,7 +26,7 @@ use crate::index; /// cacache::read("./my-cache", "my-key").await?; /// /// // But this succeeds: -/// cacache::read_hash("./my-cache", &sri).await?; +/// cacache::read_hash("./my-cache", sri).await?; /// /// Ok(()) /// } @@ -56,7 +56,7 @@ where /// /// // These fail: /// cacache::read("./my-cache", "my-key").await?; -/// cacache::read_hash("./my-cache", &sri).await?; +/// cacache::read_hash("./my-cache", sri).await?; /// /// // But this succeeds: /// cacache::metadata("./my-cache", "my-key").await?; @@ -86,7 +86,7 @@ pub async fn remove_hash>(cache: P, sri: &Integrity) -> Result<() /// // These all fail: /// cacache::read("./my-cache", "my-key").await?; /// cacache::metadata("./my-cache", "my-key").await?; -/// cacache::read_hash("./my-cache", &sri).await?; +/// cacache::read_hash("./my-cache", sri).await?; /// /// Ok(()) /// }