Skip to main content

objectstore_client/
head.rs

1use objectstore_types::metadata::Metadata;
2use reqwest::StatusCode;
3
4use crate::response::ResponseExt as _;
5use crate::{ObjectKey, Session};
6
7/// The result from a successful [`head()`](Session::head) call.
8///
9/// Returns `Some(metadata)` if the object exists, `None` otherwise.
10pub type HeadResponse = Option<Metadata>;
11
12impl Session {
13    /// Checks whether an object exists and retrieves its metadata.
14    ///
15    /// If the object exists and has a TTI expiration policy, this is considered an access, and
16    /// therefore bumps its expiration.
17    pub fn head(&self, key: &str) -> HeadBuilder {
18        HeadBuilder {
19            session: self.clone(),
20            key: key.to_owned(),
21        }
22    }
23}
24
25/// A [`head`](Session::head) request builder.
26#[derive(Debug)]
27pub struct HeadBuilder {
28    pub(crate) session: Session,
29    pub(crate) key: ObjectKey,
30}
31
32impl HeadBuilder {
33    /// Sends the head request.
34    pub async fn send(self) -> crate::Result<HeadResponse> {
35        let response = self
36            .session
37            .request(reqwest::Method::HEAD, &self.key)?
38            .send()
39            .await?;
40        if response.status() == StatusCode::NOT_FOUND {
41            response.drain_body().await;
42            return Ok(None);
43        }
44        let response = response.error_for_status_and_drain().await?;
45        let metadata = Metadata::from_headers(response.headers(), "");
46        response.drain_body().await;
47        Ok(Some(metadata?))
48    }
49}