aliyun_oss_rs/object/
get_object_meta.rs

1use crate::{
2    Error,
3    request::{Oss, OssRequest},
4};
5use base64::{Engine, engine::general_purpose};
6use bytes::Bytes;
7use http::Method;
8use serde_derive::Deserialize;
9
10// Returned content
11/// Object meta information
12#[derive(Debug, Deserialize)]
13#[serde(rename_all = "PascalCase")]
14pub struct ObjectMeta {
15    /// File size in bytes
16    pub content_length: String,
17    /// Identifies the file content
18    pub e_tag: String,
19    /// Last access time
20    pub last_access_time: Option<String>,
21    /// Last modified time
22    pub last_modified: String,
23}
24
25/// Retrieve the object's meta information
26///
27/// See the [Alibaba Cloud documentation](https://help.aliyun.com/document_detail/31985.html) for details
28pub struct GetObjectMeta {
29    req: OssRequest,
30}
31impl GetObjectMeta {
32    pub(super) fn new(oss: Oss) -> Self {
33        let mut req = OssRequest::new(oss, Method::HEAD);
34        req.insert_query("objectMeta", "");
35        GetObjectMeta { req }
36    }
37    /// Send the request
38    ///
39    pub async fn send(self) -> Result<ObjectMeta, Error> {
40        // Build the HTTP request
41        let response = self.req.send_to_oss()?.await?;
42        // Parse the response
43        let status_code = response.status();
44        match status_code {
45            code if code.is_success() => {
46                let headers = response.headers();
47                let content_length = headers
48                    .get("Content-Length")
49                    .and_then(|header| header.to_str().ok().map(|s| s.to_owned()))
50                    .unwrap_or_else(|| String::new());
51                let e_tag = headers
52                    .get("ETag")
53                    .and_then(|header| header.to_str().ok().map(|s| s.trim_matches('"').to_owned()))
54                    .unwrap_or_else(|| String::new());
55                let last_access_time = headers
56                    .get("x-oss-last-access-time")
57                    .and_then(|header| header.to_str().ok().map(|s| s.to_owned()));
58                let last_modified = headers
59                    .get("Last-Modified")
60                    .and_then(|header| header.to_str().ok().map(|s| s.to_owned()))
61                    .unwrap_or_else(|| String::new());
62                Ok(ObjectMeta {
63                    content_length,
64                    e_tag,
65                    last_access_time,
66                    last_modified,
67                })
68            }
69            _ => {
70                let x_oss_error = response.headers().get("x-oss-err").and_then(|header| {
71                    general_purpose::STANDARD
72                        .decode(header)
73                        .ok()
74                        .map(|v| Bytes::from(v))
75                });
76                match x_oss_error {
77                    None => Err(Error::OssInvalidError(status_code, Bytes::new())),
78                    Some(response_bytes) => {
79                        let oss_error = serde_xml_rs::from_reader(&*response_bytes);
80                        match oss_error {
81                            Ok(oss_error) => Err(Error::OssError(status_code, oss_error)),
82                            Err(_) => Err(Error::OssInvalidError(status_code, response_bytes)),
83                        }
84                    }
85                }
86            }
87        }
88    }
89}