ufile_rus3/api/
head_file.rs1use std::collections::HashMap;
4
5use anyhow::Error;
6use chrono::Local;
7use reqwest::{Method, header::HeaderMap};
8
9use crate::{
10 AuthorizationService,
11 api::{
12 ApiOperation,
13 object::{BaseResponse, HeadFileResponse, ObjectOptAuthParamBuilder},
14 },
15 define_api_request, define_operation_struct,
16};
17define_operation_struct!(HeadFileOperation);
18
19define_api_request!(HeadFileRequest,
20HeadFileOperationBuilder,
21HeadFileResponse,
22{
23 #[builder(setter(into))]
25 pub bucket_name: String,
26
27 #[builder(setter(into))]
29 pub key_name: String,
30
31 #[builder(setter(into, strip_option), default)]
33 pub security_token: Option<String>,
34});
35
36#[async_trait::async_trait]
37impl ApiOperation for HeadFileOperation {
38 type Request = HeadFileRequest;
39 type Response = HeadFileResponse;
40 type Error = Error;
41
42 async fn execute(&self, req: Self::Request) -> Result<Self::Response, Self::Error> {
43 let HeadFileRequest {
44 bucket_name,
45 key_name,
46 security_token,
47 ..
48 } = req;
49 let date = Local::now().format("&Y%m%d%H%M%S").to_string();
50 let auth_object = ObjectOptAuthParamBuilder::default()
51 .method(Method::HEAD)
52 .bucket(bucket_name.clone())
53 .key_name(key_name.clone())
54 .content_type("application/json")
55 .date(date.as_str())
56 .build()?;
57 let authorization =
58 AuthorizationService.authorization(auth_object, self.object_config.clone())?;
59 let mut headers = HeaderMap::new();
60 headers.insert("Content-Type", "application/json".parse().unwrap());
61 headers.insert("Accept", "*/*".parse().unwrap());
62 headers.insert("Date", date.parse().unwrap());
63 headers.insert("Authorization", authorization.parse().unwrap());
64 if let Some(ref security_token) = security_token
65 && !security_token.is_empty()
66 {
67 headers.insert("SecurityToken", security_token.parse().unwrap());
68 }
69 let url = self
70 .object_config
71 .generate_final_host(bucket_name.as_str(), key_name.as_str());
72 let resp = self
74 .client
75 .get_client()
76 .head(url)
77 .headers(headers)
78 .send()
79 .await?;
80 ::tracing::debug!("get file head response: {:?}", resp);
81 if resp.status().is_success() {
82 let headers = resp
84 .headers()
85 .into_iter()
86 .map(|(k, v)| {
87 (
88 k.as_str().to_lowercase(),
89 v.to_str().unwrap().to_lowercase(),
90 )
91 })
92 .collect::<HashMap<String, String>>();
93 return Ok(HeadFileResponse {
94 content_type: headers.get("content-type").unwrap().into(),
95 content_length: headers
96 .get("content-length")
97 .unwrap()
98 .parse::<u64>()
99 .unwrap(),
100 etag: headers.get("etag").map(|v| v.to_string()),
101 last_modified: headers.get("last-modified").map(Into::into),
102 headers: Some(headers),
103 });
104 }
105 let resp = resp.json::<BaseResponse>().await?;
106 tracing::debug!(
107 "Failed to get file head for: {} with error: {:?}",
108 key_name,
109 resp
110 );
111 Err(Error::msg("Failed to get file head"))
112 }
113}