1use sha2::{Digest, Sha256};
10
11use crate::http::{get_bytes, HttpError};
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct Pinned {
16 pub size: u64,
17 pub sha256: String,
19}
20
21#[derive(Debug, thiserror::Error)]
22pub enum PinError {
23 #[error(transparent)]
24 Transport(#[from] HttpError),
25 #[error("{url} returned HTTP {status}")]
26 Status { url: String, status: u16 },
27}
28
29pub fn sha256_hex(bytes: &[u8]) -> String {
31 hex::encode(Sha256::digest(bytes))
32}
33
34pub fn pin_url(url: &str, headers: &[(&str, &str)]) -> Result<Pinned, PinError> {
36 let response = get_bytes(url, headers)?;
37 if !response.ok() {
38 return Err(PinError::Status {
39 url: url.to_owned(),
40 status: response.status,
41 });
42 }
43 Ok(Pinned {
44 size: response.body.len() as u64,
45 sha256: sha256_hex(&response.body),
46 })
47}