snix_store/pathinfoservice/nix_http/
castore_infused.rs1use nix_compat::{
2 narinfo::NarInfo,
3 nixhash::{Sha256, copy_sha256},
4};
5use snix_castore::{
6 Node, blobservice::BlobService, directoryservice::DirectoryService,
7 proto::parse_infused_nar_path,
8};
9
10pub async fn try_infused_nar_path<BS, DS>(
16 narinfo: &NarInfo<'_>,
17 blob_service: BS,
18 directory_service: DS,
19) -> Result<Option<Node>, Error>
20where
21 BS: BlobService,
22 DS: DirectoryService,
23{
24 let (node, nar_size) = match parse_infused_nar_path(narinfo.url) {
25 Some(e) => e,
26 None => return Ok(None),
27 };
28
29 if nar_size != narinfo.nar_size {
30 return Err(Error::InconsistentNarSizeInURL);
31 }
32
33 let mut r = crate::nar::Reader::new(&node, &blob_service, directory_service).await?;
35
36 let (actual_nar_size, actual_nar_hash) = copy_sha256(&mut r, &mut tokio::io::sink()).await?;
38
39 if narinfo.nar_size != actual_nar_size {
40 return Err(Error::WrongNARSize {
41 expected: narinfo.nar_size,
42 actual: actual_nar_size,
43 });
44 }
45 if narinfo.nar_hash != actual_nar_hash {
46 return Err(Error::WrongNARHash {
47 expected: narinfo.nar_hash.into(),
48 actual: actual_nar_hash,
49 });
50 }
51
52 Ok(Some(node))
53}
54
55#[derive(thiserror::Error, Debug)]
56pub enum Error {
57 #[error("found infused NAR path, but with differing nar_size!")]
58 InconsistentNarSizeInURL,
59
60 #[error("failed to render NAR: {0}")]
61 RenderingNAR(#[from] crate::nar::RenderError),
62
63 #[error("failed to read NAR: {0}")]
64 IO(#[from] std::io::Error),
65
66 #[error("got unexpected NAR size while rendering NAR: {actual}, expected {expected}")]
67 WrongNARSize { expected: u64, actual: u64 },
68
69 #[error("got unexpected NAR hash while rendering NAR: {actual:x}, expected {expected:x}")]
70 WrongNARHash { expected: Sha256, actual: Sha256 },
71}