aliyun_oss_rs/object/
head_object.rs1use crate::common::format_gmt;
2use crate::{
3 Error,
4 request::{Oss, OssRequest},
5};
6use base64::{Engine, engine::general_purpose};
7use bytes::Bytes;
8use http::Method;
9use std::collections::HashMap;
10use time::OffsetDateTime;
11
12pub struct HeadObject {
16 req: OssRequest,
17}
18impl HeadObject {
19 pub(super) fn new(oss: Oss) -> Self {
20 HeadObject {
21 req: OssRequest::new(oss, Method::HEAD),
22 }
23 }
24 pub fn set_if_modified_since(mut self, if_modified_since: OffsetDateTime) -> Self {
27 self.req
28 .insert_header("If-Modified-Since", format_gmt(if_modified_since));
29 self
30 }
31 pub fn set_if_unmodified_since(mut self, if_unmodified_since: OffsetDateTime) -> Self {
34 self.req
35 .insert_header("If-Unmodified-Since", format_gmt(if_unmodified_since));
36 self
37 }
38 pub fn set_if_match(mut self, if_match: impl ToString) -> Self {
42 self.req.insert_header("If-Match", if_match);
43 self
44 }
45 pub fn set_if_none_match(mut self, if_none_match: impl ToString) -> Self {
48 self.req.insert_header("If-None-Match", if_none_match);
49 self
50 }
51 pub async fn send(self) -> Result<HashMap<String, String>, Error> {
54 let mut response = self.req.send_to_oss()?.await?;
56 let status_code = response.status();
58 match status_code {
59 code if code.is_success() => {
60 let headers = response.headers_mut();
61 headers.remove("server");
62 headers.remove("date");
63 headers.remove("content-type");
64 headers.remove("content-length");
65 headers.remove("connection");
66 headers.remove("x-oss-request-id");
67 headers.remove("accept-ranges");
68 let result = headers
69 .into_iter()
70 .map(|(key, value)| {
71 let key = key.to_string();
72 let mut value = String::from_utf8(value.as_bytes().to_vec())
73 .unwrap_or_else(|_| String::new());
74 if &key == "etag" {
75 value = value.trim_matches('"').to_owned();
76 }
77 (key, value)
78 })
79 .collect::<HashMap<String, String>>();
80 Ok(result)
81 }
82 _ => {
83 let x_oss_error = response.headers().get("x-oss-err").and_then(|header| {
84 general_purpose::STANDARD
85 .decode(header)
86 .ok()
87 .map(|v| Bytes::from(v))
88 });
89 match x_oss_error {
90 None => Err(Error::OssInvalidError(status_code, Bytes::new())),
91 Some(response_bytes) => {
92 let oss_error = serde_xml_rs::from_reader(&*response_bytes);
93 match oss_error {
94 Ok(oss_error) => Err(Error::OssError(status_code, oss_error)),
95 Err(_) => Err(Error::OssInvalidError(status_code, response_bytes)),
96 }
97 }
98 }
99 }
100 }
101 }
102}