use base64::Engine;
use super::CHECKSUM;
use super::keyspace::Keyspace;
use crate::error::Error;
const KEY: &str = ".probe/checksum";
const BODY: &[u8] = b"lfsx checksum probe";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Checksums {
Enforced,
Ignored,
Unknown,
}
fn wrong_digest() -> String {
base64::engine::general_purpose::STANDARD.encode([0u8; 32])
}
pub(crate) async fn checksums(keys: &Keyspace) -> Checksums {
let signed = keys.signed_upload(KEY, vec![(CHECKSUM.to_owned(), wrong_digest())]);
let mut request = keys.client().put(&signed.href).body(BODY.to_vec());
for (name, value) in &signed.headers {
request = request.header(name, value);
}
if let Err(error) = request.send().await {
tracing::warn!(%error, "the object store could not be reached to check it verifies uploads");
return Checksums::Unknown;
}
match keys.head(KEY).await {
Err(Error::NotFound) => Checksums::Enforced,
Err(error) => {
tracing::warn!(%error, "the object store could not say whether it kept the probe");
Checksums::Unknown
}
Ok(_) => {
if let Err(error) = keys.delete(KEY).await {
tracing::warn!(%error, key = KEY, "the probe object could not be cleaned up");
}
Checksums::Ignored
}
}
}
#[cfg(test)]
mod tests;