ufile_rus3/api/
multipart_init.rs1use anyhow::Error;
2use chrono::Local;
3use reqwest::{
4 Method,
5 header::{HeaderMap, HeaderName},
6};
7
8use crate::{
9 AuthorizationService,
10 api::{ApiOperation, ObjectOptAuthParamBuilder, object::InitMultipartState},
11 define_api_request, define_operation_struct,
12};
13
14define_operation_struct!(MultipartInitOperation);
15
16define_api_request!(
17 MultipartInitRequest,
18 MultipartInitOperationBuilder,
19 InitMultipartState,
20 {
21 #[builder(setter(into))]
23 pub key_name: String,
24
25 #[builder(setter(into))]
27 pub mime_type: String,
28
29 #[builder(setter(into))]
31 pub bucket_name: String,
32
33 #[builder(setter(into, strip_option), default)]
35 pub metadata: ::std::option::Option<::std::collections::HashMap<String, String>>,
36
37 #[builder(setter(into, strip_option), default)]
39 pub storage_type: ::std::option::Option<String>,
40
41 #[builder(setter(into, strip_option), default)]
43 pub security_token: ::std::option::Option<String>,
44 }
45);
46
47#[async_trait::async_trait]
48impl ApiOperation for MultipartInitOperation {
49 type Request = MultipartInitRequest;
50 type Response = InitMultipartState;
51 type Error = Error;
52
53 async fn execute(&self, request: Self::Request) -> Result<Self::Response, Self::Error> {
54 let MultipartInitRequest {
55 key_name,
56 mime_type,
57 bucket_name,
58 metadata,
59 storage_type,
60 security_token,
61 ..
62 } = request;
63 let date = Local::now().format("&Y%m%d%H%M%S").to_string();
64 let auth_object = ObjectOptAuthParamBuilder::default()
65 .method(Method::POST)
66 .bucket(bucket_name.as_str())
67 .key_name(key_name.as_str())
68 .content_type(mime_type.as_str())
69 .date(date.as_str())
70 .build()?;
71 let authorization =
72 AuthorizationService.authorization(auth_object, self.object_config.clone())?;
73 let mut headers = HeaderMap::new();
74 headers.insert("Content-Type", mime_type.parse().unwrap());
75 headers.insert("Accept", "*/*".parse().unwrap());
76 headers.insert("Date", date.parse().unwrap());
77 headers.insert("Authorization", authorization.parse().unwrap());
78 if let Some(ref storage_type) = storage_type
79 && !storage_type.is_empty()
80 {
81 headers.insert("X-Ufile-Storage-Class", storage_type.parse().unwrap());
82 }
83 if let Some(ref security_token) = security_token
84 && !security_token.is_empty()
85 {
86 headers.insert("SecurityToken", security_token.parse().unwrap());
87 }
88 if let Some(ref metadata) = metadata
90 && !metadata.is_empty()
91 {
92 for (k, v) in metadata {
93 headers.insert(
94 format!("X-Ufile-Meta-{k}").parse::<HeaderName>().unwrap(),
95 v.parse().unwrap(),
96 );
97 }
98 }
99 let url = self
100 .object_config
101 .generate_final_host(bucket_name.as_str(), key_name.as_str());
102 let url = format!("{url}?uploads");
103 let resp = self
105 .client
106 .get_client()
107 .post(url)
108 .headers(headers)
109 .json("")
110 .send()
111 .await?;
112 ::tracing::debug!("Init multipart file response: {:?}", resp);
113 if resp.status().is_success() {
114 let mut resp: InitMultipartState = resp.json().await?;
115 resp.mime_type.replace(mime_type.clone());
116 return Ok(resp);
117 }
118 Err(Error::msg("Failed to init multipart file"))
119 }
120}