ali_oss_rs/blocking/
presign.rs1use crate::{
2 presign::SignedOssRequest,
3 presign_common::{build_presign_get_request, PresignGetOptions},
4 request::OssRequest,
5 util::{self, get_iso8601_date_time_string},
6};
7
8use super::Client;
9
10impl Client {
11 pub fn presign_url<S1, S2>(&self, bucket_name: S1, object_key: S2, options: PresignGetOptions) -> String
13 where
14 S1: AsRef<str>,
15 S2: AsRef<str>,
16 {
17 let mut request = build_presign_get_request(bucket_name.as_ref(), object_key.as_ref(), &options);
18
19 let date_time_string = request.query.get("x-oss-date").unwrap().clone();
20 let date_string = &date_time_string[..8];
21
22 let credential = format!("{}/{}/{}/oss/aliyun_v4_request", self.access_key_id, date_string, self.region);
23
24 request = request.add_query("x-oss-credential", &credential);
25
26 if let Some(s) = &self.sts_token {
27 request = request.add_query("x-oss-security-token", s);
28 }
29
30 let canonical_request = request.build_canonical_request();
31
32 let canonical_request_hash = util::sha256(canonical_request.as_bytes());
33
34 let string_to_sign = format!(
35 "OSS4-HMAC-SHA256\n{}\n{}/{}/oss/aliyun_v4_request\n{}",
36 date_time_string,
37 date_string,
38 self.region,
39 hex::encode(&canonical_request_hash)
40 );
41
42 let sig = self.calculate_signature(&string_to_sign, date_string);
43
44 request = request.add_query("x-oss-signature", &sig);
45
46 let uri = request.build_request_uri();
47 let query_string = request.build_canonical_query_string();
48
49 let domain_name = if request.bucket_name.is_empty() {
50 format!("{}://{}{}", self.scheme, self.endpoint, uri)
51 } else {
52 format!("{}://{}.{}{}", self.scheme, request.bucket_name, self.endpoint, uri)
53 };
54
55 if query_string.is_empty() {
56 domain_name
57 } else {
58 format!("{}?{}", domain_name, query_string)
59 }
60 }
61
62 pub fn presign_raw_request(&self, mut oss_request: OssRequest) -> SignedOssRequest {
63 let date_header = "x-oss-date".to_string();
64 {
65 oss_request.headers_mut().entry(date_header.clone()).or_insert(get_iso8601_date_time_string());
66 }
67
68 let date_time_string = oss_request.headers.get(&date_header).unwrap().to_string();
69 let date_string = &date_time_string[..8];
70
71 if let Some(s) = &self.sts_token {
72 if !oss_request.headers.contains_key("x-oss-security-token") {
73 oss_request = oss_request.add_header("x-oss-security-token", s);
74 }
75 }
76 let additional_headers = oss_request.build_additional_headers();
77 let string_to_sign = oss_request.build_string_to_sign(&self.region);
78
79 log::debug!("string to sign: \n--------\n{}\n--------", string_to_sign);
80
81 let sig = self.calculate_signature(&string_to_sign, date_string);
82
83 log::debug!("signature: {}", sig);
84
85 let auth_string = format!(
86 "OSS4-HMAC-SHA256 Credential={}/{}/{}/oss/aliyun_v4_request,{}Signature={}",
87 self.access_key_id,
88 date_string,
89 self.region,
90 if additional_headers.is_empty() {
91 "".to_string()
92 } else {
93 format!("{},", additional_headers)
94 },
95 sig
96 );
97
98 oss_request = oss_request.add_header("authorization", &auth_string);
99
100 let uri = oss_request.build_request_uri();
101 let query_string = oss_request.build_canonical_query_string();
102
103 let url = if oss_request.bucket_name.is_empty() {
104 format!("{}://{}{}", self.scheme, self.endpoint, uri)
105 } else {
106 format!("{}://{}.{}{}", self.scheme, oss_request.bucket_name, self.endpoint, uri)
107 };
108
109 let url = if query_string.is_empty() { url } else { format!("{}?{}", url, query_string) };
110
111 SignedOssRequest {
112 url,
113 headers: oss_request.headers,
114 }
115 }
116}