rusty_oss/actions/
get_bucket_info.rs

1use std::iter;
2use std::time::Duration;
3
4use time::OffsetDateTime;
5use url::Url;
6
7use super::OSSAction;
8use crate::actions::Method;
9use crate::signing::sign;
10use crate::sorting_iter::SortingIterator;
11use crate::{Bucket, Credentials, Map};
12
13/// No HeadBucket action in OSS, use GetBucketInfo instead
14///
15/// Find out more about `GetBucketInfo` from the [OSS API Reference][api]
16///
17/// [api]: https://help.aliyun.com/zh/oss/developer-reference/getbucketinfo
18#[derive(Debug, Clone)]
19pub struct GetBucketInfo<'a> {
20    bucket: &'a Bucket,
21    credentials: Option<&'a Credentials>,
22
23    query: Map<'a>,
24    headers: Map<'a>,
25}
26
27impl<'a> GetBucketInfo<'a> {
28    #[inline]
29    pub fn new(bucket: &'a Bucket, credentials: Option<&'a Credentials>) -> Self {
30        Self {
31            bucket,
32            credentials,
33
34            query: Map::new(),
35            headers: Map::new(),
36        }
37    }
38}
39
40impl<'a> OSSAction<'a> for GetBucketInfo<'a> {
41    const METHOD: Method = Method::Get;
42
43    fn query_mut(&mut self) -> &mut Map<'a> {
44        &mut self.query
45    }
46
47    fn headers_mut(&mut self) -> &mut Map<'a> {
48        &mut self.headers
49    }
50
51    fn sign_with_time(&self, expires_in: Duration, time: &OffsetDateTime) -> Url {
52        let url = self.bucket.base_url().clone();
53        let query = SortingIterator::new(iter::once(("bucketInfo", "1")), self.query.iter());
54
55        match self.credentials {
56            Some(credentials) => sign(
57                time,
58                Method::Get,
59                url,
60                credentials.key(),
61                credentials.secret(),
62                credentials.token(),
63                self.bucket.region(),
64                expires_in.as_secs(),
65                query,
66                self.headers.iter(),
67            ),
68            None => crate::signing::util::add_query_params(url, query),
69        }
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use time::OffsetDateTime;
76
77    use pretty_assertions::assert_eq;
78
79    use super::*;
80    use crate::{Bucket, Credentials, UrlStyle};
81
82    #[test]
83    fn oss_example() {
84        // Fri, 24 May 2013 00:00:00 GMT
85        let date = OffsetDateTime::from_unix_timestamp(1369353600).unwrap();
86        let expires_in = Duration::from_secs(86400);
87
88        let endpoint = "https://oss-cn-hangzhou.aliyuncs.com".parse().unwrap();
89        let bucket = Bucket::new(
90            endpoint,
91            UrlStyle::VirtualHost,
92            "examplebucket",
93            "cn-hangzhou",
94        )
95        .unwrap();
96        let credentials = Credentials::new("access_key_id", "access_key_secret");
97
98        let action = GetBucketInfo::new(&bucket, Some(&credentials));
99
100        let url = action.sign_with_time(expires_in, &date);
101
102        let expected = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/?bucketInfo=1&x-oss-additional-headers=host&x-oss-credential=access_key_id%2F20130524%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20130524T000000Z&x-oss-expires=86400&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-signature=aa6780edbc65215ad1b2f8cd4699264e008bcdbbaef41765bc9af44d0847fd39";
103        assert_eq!(expected, url.as_str());
104    }
105
106    #[test]
107    fn oss_example_custom_query() {
108        // Fri, 24 May 2013 00:00:00 GMT
109        let date = OffsetDateTime::from_unix_timestamp(1369353600).unwrap();
110        let expires_in = Duration::from_secs(86400);
111
112        let endpoint = "https://oss-cn-hangzhou.aliyuncs.com".parse().unwrap();
113        let bucket = Bucket::new(
114            endpoint,
115            UrlStyle::VirtualHost,
116            "examplebucket",
117            "cn-hangzhou",
118        )
119        .unwrap();
120        let credentials = Credentials::new("access_key_id", "access_key_secret");
121
122        let mut action = GetBucketInfo::new(&bucket, Some(&credentials));
123        action
124            .query_mut()
125            .insert("response-content-type", "text/plain");
126
127        let url = action.sign_with_time(expires_in, &date);
128        let expected = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/?bucketInfo=1&response-content-type=text%2Fplain&x-oss-additional-headers=host&x-oss-credential=access_key_id%2F20130524%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20130524T000000Z&x-oss-expires=86400&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-signature=e4c129ee1e740622065c5c696d438120687a26adb5be1d1c1f9208f159556cbe";
129        assert_eq!(expected, url.as_str());
130    }
131
132    #[test]
133    fn anonymous_custom_query() {
134        let expires_in = Duration::from_secs(86400);
135
136        let endpoint = "https://oss-cn-hangzhou.aliyuncs.com".parse().unwrap();
137        let bucket = Bucket::new(
138            endpoint,
139            UrlStyle::VirtualHost,
140            "examplebucket",
141            "cn-hangzhou",
142        )
143        .unwrap();
144
145        let mut action = GetBucketInfo::new(&bucket, None);
146        action
147            .query_mut()
148            .insert("response-content-type", "text/plain");
149
150        let url = action.sign(expires_in);
151        let expected = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/?bucketInfo=1&response-content-type=text%2Fplain";
152
153        assert_eq!(expected, url.as_str());
154    }
155}