any_object_storage/async_impl/
object.rs1use hmac::Hmac;
2use sha1::digest::Mac;
3use crate::entity::{PolicyBuilder, PolicyResp};
4use crate::error::OssError;
5use crate::oss::{OSSInfo, API, OSS};
6use crate::request::{RequestBuilder, RequestType};
7use crate::{debug, util};
8use crate::metadata::ObjectMetadata;
9use crate::util::read_file;
10
11impl OSS {
12 pub async fn get_object<S: AsRef<str>>(
25 &self,
26 key: S,
27 build: RequestBuilder,
28 ) -> Result<Vec<u8>, OssError> {
29 let key = self.format_key(key);
30 let (url, headers) = self
31 .build_request(key.as_str(), build)
32 .map_err(|e| OssError::Err(format!("build request error: {}", e)))?;
33 debug!("oss logget object url: {} headers: {:?}", url,headers);
34 let client = reqwest::Client::new();
35 let response = client.get(url).headers(headers).send().await?;
36 return if response.status().is_success() {
37 let result = response.bytes().await?;
38 Ok(result.to_vec())
39 } else {
40 let status = response.status();
41 let result = response.text().await?;
42 debug!("oss log: get object status: {} error: {}", status,result);
43 Err(OssError::Err(format!(
44 "get object status: {} error: {}",
45 status, result
46 )))
47 };
48 }
49
50 pub fn get_upload_object_policy(&self, build: PolicyBuilder) -> Result<PolicyResp, OssError> {
69 let date = chrono::Local::now().naive_local() + chrono::Duration::seconds(build.expire);
70 let date_str = date.format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string();
71 let mut json_data = r#"
72 {
73 "expiration": "{time}",
74 "conditions": [
75 {"bucket": "{bucket}" },
76 ["content-length-range", 1, {size}],
77 ["eq", "$success_action_status", "{success_action_status}"],
78 ["starts-with", "$key", "{prefix}"],
79 ["in", "$content-type", ["{content_type}"]]
80 ]
81 }
82 "#
83 .to_string();
84 let success_action_status = 200;
85 json_data = json_data.replacen("{time}", &date_str, 1);
86 json_data = json_data.replacen("{bucket}", &self.bucket(), 1);
87 json_data = json_data.replacen("{size}", &build.max_upload_size.to_string(), 1); json_data = json_data.replacen(
91 "{success_action_status}",
92 success_action_status.to_string().as_str(),
93 1,
94 );
95 json_data = json_data.replacen("{prefix}", &build.upload_dir, 1); json_data = json_data.replacen("{content_type}", &build.content_type, 1);
98 debug!("oss log: policy json: {}", json_data);
100 let base64_policy = util::base64_encode(json_data.as_bytes());
101 let mut hasher: Hmac<sha1::Sha1> = Hmac::new_from_slice(self.key_secret().as_bytes())
102 .map_err(|_| OssError::Err("Hmac new from slice error".to_string()))?;
103 hasher.update(base64_policy.as_bytes());
104 let signature = util::base64_encode(&hasher.finalize().into_bytes());
105 Ok(PolicyResp {
106 access_id: self.key_id().to_string(),
107 host: format!("https://{}.{}", self.bucket(), self.endpoint()),
108 policy: base64_policy,
109 signature,
110 success_action_status,
111 })
112 }
113
114 pub async fn put_object_from_file<S: AsRef<str>>(
126 &self,
127 key: S,
128 file_path: S,
129 build: RequestBuilder,
130 ) -> Result<(), OssError> {
131 let buffer = read_file(file_path)?;
132 let mut build = build.clone();
133 build.method = RequestType::Put;
134 let key = self.format_key(key);
135 let (url, headers) = self
136 .build_request(key.as_str(), build)
137 .map_err(|e| OssError::Err(format!("build request error: {}", e)))?;
138 debug!("oss log: put object from file: {} headers: {:?}", url,headers);
139 let client = reqwest::Client::new();
140 let response = client.put(url).headers(headers).body(buffer).send().await?;
141 return if response.status().is_success() {
142 Ok(())
143 } else {
144 let status = response.status();
145 let result = response.text().await?;
146 debug!("oss log: get object status: {} error: {}", status,result);
147 Err(OssError::Err(format!(
148 "get object status: {} error: {}",
149 status, result
150 )))
151 };
152 }
153
154 pub async fn pub_object_from_buffer<S: AsRef<str>>(
167 &self,
168 key: S,
169 buffer: &[u8],
170 build: RequestBuilder,
171 ) -> Result<(), OssError> {
172 let mut build = build.clone();
173 build.method = RequestType::Put;
174 let key = self.format_key(key);
175 let (url, headers) = self
176 .build_request(key.as_str(), build)
177 .map_err(|e| OssError::Err(format!("build request error: {}", e)))?;
178 debug!("oss log: put object from file: {} headers: {:?}", url,headers);
179 let client = reqwest::Client::new();
180 let response = client
181 .put(url)
182 .headers(headers)
183 .body(buffer.to_owned())
184 .send()
185 .await?;
186 return if response.status().is_success() {
187 Ok(())
188 } else {
189 let status = response.status();
190 let result = response.text().await?;
191 debug!("oss log: get object status: {} error: {}", status,result);
192 Err(OssError::Err(format!(
193 "get object status: {} error: {}",
194 status, result
195 )))
196 };
197 }
198
199 pub async fn delete_object<S: AsRef<str>>(
210 &self,
211 key: S,
212 build: RequestBuilder,
213 ) -> Result<(), OssError> {
214 let mut build = build.clone();
215 build.method = RequestType::Delete;
216 let key = self.format_key(key);
217 let (url, headers) = self
218 .build_request(key.as_str(), build)
219 .map_err(|e| OssError::Err(format!("build request error: {}", e)))?;
220 debug!("oss log: put object from file: {} headers: {:?}", url,headers);
221 let client = reqwest::Client::new();
222 let response = client.delete(url).headers(headers).send().await?;
223 return if response.status().is_success() {
224 Ok(())
225 } else {
226 let status = response.status();
227 let result = response.text().await?;
228 debug!("oss log: get object status: {} error: {}", status,result);
229 Err(OssError::Err(format!(
230 "get object status: {} error: {}",
231 status, result
232 )))
233 };
234 }
235
236 pub async fn get_object_metadata<S: AsRef<str>>(&self, key: S, build: RequestBuilder) -> Result<ObjectMetadata, OssError>{
248 let mut build = build.clone();
249 build.method = RequestType::Head;
250 let key = self.format_key(key);
251 let (url, headers) = self.build_request(key.as_str(), build)
252 .map_err(|e| OssError::Err(format!("build request error: {}", e)))?;
253 debug!("put object from file: {} headers: {:?}", url,headers);
254 let client = reqwest::Client::new();
255 let response = client.head(url)
256 .headers(headers)
257 .send()
258 .await?;
259 return if response.status().is_success() {
260 let metadata = ObjectMetadata::new(response.headers());
261 Ok(metadata)
262 } else {
263 let status = response.status();
264 let result = response.text().await?;
265 debug!("get object status: {} error: {}", status,result);
266 Err(OssError::Err(format!("get object status: {} error: {}", status, result)))
267 };
268 }
269}