s3/bucket/
presign.rs

1use crate::bucket::{validate_expiry, Bucket, Request};
2use crate::command::Command;
3use crate::error::S3Error;
4use crate::request::RequestImpl;
5use http::header::HeaderMap;
6use std::collections::HashMap;
7
8impl Bucket {
9    /// Get a presigned url for getting object on a given path
10    ///
11    /// # Example:
12    ///
13    /// ```no_run
14    /// use std::collections::HashMap;
15    /// use s3::bucket::Bucket;
16    /// use s3::creds::Credentials;
17    ///
18    /// let bucket_name = "rust-s3-test";
19    /// let region = "us-east-1".parse().unwrap();
20    /// let credentials = Credentials::default().unwrap();
21    /// let bucket = Bucket::new(bucket_name, region, credentials).unwrap();
22    ///
23    /// // Add optional custom queries
24    /// let mut custom_queries = HashMap::new();
25    /// custom_queries.insert(
26    ///    "response-content-disposition".into(),
27    ///    "attachment; filename=\"test.png\"".into(),
28    /// );
29    ///
30    /// let url = bucket.presign_get("/test.file", 86400, Some(custom_queries)).unwrap();
31    /// println!("Presigned url: {}", url);
32    /// ```
33    pub fn presign_get<S: AsRef<str>>(
34        &self,
35        path: S,
36        expiry_secs: u32,
37        custom_queries: Option<HashMap<String, String>>,
38    ) -> Result<String, S3Error> {
39        validate_expiry(expiry_secs)?;
40        let request = RequestImpl::new(
41            self,
42            path.as_ref(),
43            Command::PresignGet {
44                expiry_secs,
45                custom_queries,
46            },
47        )?;
48        request.presigned()
49    }
50
51    /// Get a presigned url for posting an object to a given path
52    ///
53    /// # Example:
54    ///
55    /// ```no_run
56    /// use s3::bucket::Bucket;
57    /// use s3::creds::Credentials;
58    /// use http::HeaderMap;
59    /// use http::header::HeaderName;
60    ///
61    /// let bucket_name = "rust-s3-test";
62    /// let region = "us-east-1".parse().unwrap();
63    /// let credentials = Credentials::default().unwrap();
64    /// let bucket = Bucket::new(bucket_name, region, credentials).unwrap();
65    ///
66    /// let post_policy = "eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJzaWd2NGV4YW1wbGVidWNrZXQifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwNCiAgICB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL3NpZ3Y0ZXhhbXBsZWJ1Y2tldC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRDb250ZW50LVR5cGUiLCAiaW1hZ2UvIl0sDQogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwNCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkeC1hbXotbWV0YS10YWciLCAiIl0sDQoNCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlPU0ZPRE5ON0VYQU1QTEUvMjAxNTEyMjkvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LA0KICAgIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwNCiAgICB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfQ0KICBdDQp9";
67    ///
68    /// let url = bucket.presign_post("/test.file", 86400, post_policy.to_string()).unwrap();
69    /// println!("Presigned url: {}", url);
70    /// ```
71    pub fn presign_post<S: AsRef<str>>(
72        &self,
73        path: S,
74        expiry_secs: u32,
75        // base64 encoded post policy document -> https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
76        post_policy: String,
77    ) -> Result<String, S3Error> {
78        validate_expiry(expiry_secs)?;
79        let request = RequestImpl::new(
80            self,
81            path.as_ref(),
82            Command::PresignPost {
83                expiry_secs,
84                post_policy,
85            },
86        )?;
87        request.presigned()
88    }
89
90    /// Get a presigned url for putting object to a given path
91    ///
92    /// # Example:
93    ///
94    /// ```no_run
95    /// use s3::bucket::Bucket;
96    /// use s3::creds::Credentials;
97    /// use http::HeaderMap;
98    /// use http::header::HeaderName;
99    ///
100    /// let bucket_name = "rust-s3-test";
101    /// let region = "us-east-1".parse().unwrap();
102    /// let credentials = Credentials::default().unwrap();
103    /// let bucket = Bucket::new(bucket_name, region, credentials).unwrap();
104    ///
105    /// // Add optional custom headers
106    /// let mut custom_headers = HeaderMap::new();
107    /// custom_headers.insert(
108    ///    HeaderName::from_static("custom_header"),
109    ///    "custom_value".parse().unwrap(),
110    /// );
111    ///
112    /// let url = bucket.presign_put("/test.file", 86400, Some(custom_headers)).unwrap();
113    /// println!("Presigned url: {}", url);
114    /// ```
115    pub fn presign_put<S: AsRef<str>>(
116        &self,
117        path: S,
118        expiry_secs: u32,
119        custom_headers: Option<HeaderMap>,
120    ) -> Result<String, S3Error> {
121        validate_expiry(expiry_secs)?;
122        let request = RequestImpl::new(
123            self,
124            path.as_ref(),
125            Command::PresignPut {
126                expiry_secs,
127                custom_headers,
128            },
129        )?;
130        request.presigned()
131    }
132
133    /// Get a presigned url for deleting object on a given path
134    ///
135    /// # Example:
136    ///
137    /// ```no_run
138    /// use s3::bucket::Bucket;
139    /// use s3::creds::Credentials;
140    ///
141    /// let bucket_name = "rust-s3-test";
142    /// let region = "us-east-1".parse().unwrap();
143    /// let credentials = Credentials::default().unwrap();
144    /// let bucket = Bucket::new(bucket_name, region, credentials).unwrap();
145    ///
146    /// let url = bucket.presign_delete("/test.file", 86400).unwrap();
147    /// println!("Presigned url: {}", url);
148    /// ```
149    pub fn presign_delete<S: AsRef<str>>(
150        &self,
151        path: S,
152        expiry_secs: u32,
153    ) -> Result<String, S3Error> {
154        validate_expiry(expiry_secs)?;
155        let request =
156            RequestImpl::new(self, path.as_ref(), Command::PresignDelete { expiry_secs })?;
157        request.presigned()
158    }
159}