mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 15:26:51 +08:00
Add documentation and few enhancements (#45)
Signed-off-by: Bala.FA <bala@minio.io>
This commit is contained in:
parent
aee702f337
commit
28e7fee8fa
1
.github/workflows/rust.yml
vendored
1
.github/workflows/rust.yml
vendored
@ -24,6 +24,7 @@ jobs:
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
truncate --size=6M asiaphotos-2015.zip
|
||||
./tests/start-server.sh
|
||||
export SERVER_ENDPOINT=localhost:9000
|
||||
export ACCESS_KEY=minioadmin
|
||||
|
||||
697
src/s3/args.rs
697
src/s3/args.rs
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! S3 client to perform bucket and object operations
|
||||
|
||||
use crate::s3::args::*;
|
||||
use crate::s3::creds::Provider;
|
||||
use crate::s3::error::{Error, ErrorResponse};
|
||||
@ -201,6 +203,10 @@ fn parse_list_objects_common_prefixes(
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Simple Storage Service (aka S3) client to perform bucket and object operations.
|
||||
///
|
||||
/// If credential provider is passed, all S3 operation requests are signed using AWS Signature
|
||||
/// Version 4; else they are performed anonymously.
|
||||
pub struct Client<'a> {
|
||||
client: reqwest::Client,
|
||||
base_url: BaseUrl,
|
||||
@ -209,6 +215,22 @@ pub struct Client<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Client<'a> {
|
||||
/// Returns a S3 client with given base URL.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use minio::s3::client::Client;
|
||||
/// use minio::s3::creds::StaticProvider;
|
||||
/// use minio::s3::http::BaseUrl;
|
||||
/// let mut base_url = BaseUrl::from_string("play.min.io".to_string()).unwrap();
|
||||
/// let static_provider = StaticProvider::new(
|
||||
/// "Q3AM3UQ867SPQQA43P2F",
|
||||
/// "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
|
||||
/// None,
|
||||
/// );
|
||||
/// let client = Client::new(base_url.clone(), Some(&static_provider), None, None).unwrap();
|
||||
/// ```
|
||||
pub fn new(
|
||||
base_url: BaseUrl,
|
||||
provider: Option<&(dyn Provider + Send + Sync)>,
|
||||
@ -626,6 +648,7 @@ impl<'a> Client<'a> {
|
||||
Ok(location)
|
||||
}
|
||||
|
||||
/// Executes [AbortMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) S3 API
|
||||
pub async fn abort_multipart_upload(
|
||||
&self,
|
||||
args: &AbortMultipartUploadArgs<'_>,
|
||||
@ -712,6 +735,7 @@ impl<'a> Client<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes [CompleteMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) S3 API
|
||||
pub async fn complete_multipart_upload(
|
||||
&self,
|
||||
args: &CompleteMultipartUploadArgs<'_>,
|
||||
@ -1131,6 +1155,7 @@ impl<'a> Client<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes [CreateMultipartUpload](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html) S3 API
|
||||
pub async fn create_multipart_upload(
|
||||
&self,
|
||||
args: &CreateMultipartUploadArgs<'_>,
|
||||
@ -2434,6 +2459,7 @@ impl<'a> Client<'a> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Executes [ListObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) S3 API
|
||||
pub async fn list_objects_v1(
|
||||
&self,
|
||||
args: &ListObjectsV1Args<'_>,
|
||||
@ -2500,6 +2526,7 @@ impl<'a> Client<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes [ListObjectsV2](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) S3 API
|
||||
pub async fn list_objects_v2(
|
||||
&self,
|
||||
args: &ListObjectsV2Args<'_>,
|
||||
@ -2584,6 +2611,7 @@ impl<'a> Client<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes [ListObjectVersions](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html) S3 API
|
||||
pub async fn list_object_versions(
|
||||
&self,
|
||||
args: &ListObjectVersionsArgs<'_>,
|
||||
@ -2980,6 +3008,7 @@ impl<'a> Client<'a> {
|
||||
res
|
||||
}
|
||||
|
||||
/// Executes [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) S3 API
|
||||
pub async fn put_object_api(
|
||||
&self,
|
||||
args: &PutObjectApiArgs<'_>,
|
||||
@ -3099,6 +3128,7 @@ impl<'a> Client<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes [DeleteObjects](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) S3 API
|
||||
pub async fn remove_objects_api(
|
||||
&self,
|
||||
args: &RemoveObjectsApiArgs<'_>,
|
||||
@ -3779,6 +3809,7 @@ impl<'a> Client<'a> {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Executes [UploadPart](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) S3 API
|
||||
pub async fn upload_part(
|
||||
&self,
|
||||
args: &UploadPartArgs<'_>,
|
||||
@ -3803,6 +3834,7 @@ impl<'a> Client<'a> {
|
||||
self.put_object_api(&poa_args).await
|
||||
}
|
||||
|
||||
/// Executes [UploadPartCopy](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html) S3 API
|
||||
pub async fn upload_part_copy(
|
||||
&self,
|
||||
args: &UploadPartCopyArgs<'_>,
|
||||
|
||||
@ -13,23 +13,36 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Credential providers
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Credentials contain access key, secret key and session token optionally
|
||||
pub struct Credentials {
|
||||
pub access_key: String,
|
||||
pub secret_key: String,
|
||||
pub session_token: Option<String>,
|
||||
}
|
||||
|
||||
/// Provider trait to fetch credentials
|
||||
pub trait Provider: std::fmt::Debug {
|
||||
fn fetch(&self) -> Credentials;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Static credential provider
|
||||
pub struct StaticProvider {
|
||||
creds: Credentials,
|
||||
}
|
||||
|
||||
impl StaticProvider {
|
||||
/// Returns a static provider with given access key, secret key and optional session token
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use minio::s3::creds::StaticProvider;
|
||||
/// let provider = StaticProvider::new("minioadmin", "minio123", None);
|
||||
/// ```
|
||||
pub fn new(access_key: &str, secret_key: &str, session_token: Option<&str>) -> StaticProvider {
|
||||
StaticProvider {
|
||||
creds: Credentials {
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Error definitions for S3 operations
|
||||
|
||||
extern crate alloc;
|
||||
use crate::s3::utils::get_default_text;
|
||||
use bytes::{Buf, Bytes};
|
||||
@ -20,6 +22,7 @@ use std::fmt;
|
||||
use xmltree::Element;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Error response for S3 operations
|
||||
pub struct ErrorResponse {
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
@ -50,6 +53,7 @@ impl ErrorResponse {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Error definitions
|
||||
pub enum Error {
|
||||
TimeParseError(chrono::ParseError),
|
||||
InvalidUrl(http::uri::InvalidUri),
|
||||
@ -74,6 +78,7 @@ pub enum Error {
|
||||
InvalidPartNumber(String),
|
||||
EmptyParts(String),
|
||||
InvalidRetentionMode(String),
|
||||
InvalidRetentionConfig(String),
|
||||
InvalidMinPartSize(usize),
|
||||
InvalidMaxPartSize(usize),
|
||||
InvalidObjectSize(usize),
|
||||
@ -128,6 +133,7 @@ impl fmt::Display for Error {
|
||||
Error::InvalidPartNumber(m) => write!(f, "{}", m),
|
||||
Error::EmptyParts(m) => write!(f, "{}", m),
|
||||
Error::InvalidRetentionMode(m) => write!(f, "invalid retention mode {}", m),
|
||||
Error::InvalidRetentionConfig(m) => write!(f, "invalid retention configuration; {}", m),
|
||||
Error::InvalidMinPartSize(s) => write!(f, "part size {} is not supported; minimum allowed 5MiB", s),
|
||||
Error::InvalidMaxPartSize(s) => write!(f, "part size {} is not supported; maximum allowed 5GiB", s),
|
||||
Error::InvalidObjectSize(s) => write!(f, "object size {} is not supported; maximum allowed 5TiB", s),
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! HTTP URL definitions
|
||||
|
||||
use crate::s3::error::Error;
|
||||
use crate::s3::utils::{to_query_string, Multimap};
|
||||
use derivative::Derivative;
|
||||
@ -22,6 +24,7 @@ use std::fmt;
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Clone, Debug, Default)]
|
||||
/// Represents HTTP URL
|
||||
pub struct Url {
|
||||
#[derivative(Default(value = "true"))]
|
||||
pub https: bool,
|
||||
@ -90,6 +93,7 @@ fn extract_region(host: &str) -> String {
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Clone, Debug, Default)]
|
||||
/// Represents Base URL of S3 endpoint
|
||||
pub struct BaseUrl {
|
||||
#[derivative(Default(value = "true"))]
|
||||
pub https: bool,
|
||||
@ -103,6 +107,7 @@ pub struct BaseUrl {
|
||||
}
|
||||
|
||||
impl BaseUrl {
|
||||
/// Builds URL from base URL for given parameters for S3 operation
|
||||
pub fn build_url(
|
||||
&self,
|
||||
method: &Method,
|
||||
@ -188,6 +193,21 @@ impl BaseUrl {
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
/// Returns a base URL from given host string
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use minio::s3::http::BaseUrl;
|
||||
/// // Get base URL from host name
|
||||
/// let base_url = BaseUrl::from_string("play.min.io".to_string()).unwrap();
|
||||
/// // Get base URL from host:port
|
||||
/// let base_url = BaseUrl::from_string("play.minio.io:9000".to_string()).unwrap();
|
||||
/// // Get base URL from IPv4 address
|
||||
/// let base_url = BaseUrl::from_string("http://192.168.124.63:9000".to_string()).unwrap();
|
||||
/// // Get base URL from IPv6 address
|
||||
/// let base_url = BaseUrl::from_string("[0:0:0:0:0:ffff:c0a8:7c3f]:9000".to_string()).unwrap();
|
||||
/// ```
|
||||
pub fn from_string(s: String) -> Result<BaseUrl, Error> {
|
||||
let url = s.parse::<Uri>()?;
|
||||
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Implementation of Simple Storage Service (aka S3) client
|
||||
|
||||
pub mod args;
|
||||
pub mod client;
|
||||
pub mod creds;
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Responses for [minio::s3::client::Client](crate::s3::client::Client) APIs
|
||||
|
||||
use crate::s3::error::Error;
|
||||
use crate::s3::types::{
|
||||
parse_legal_hold, Bucket, Item, LifecycleConfig, NotificationConfig, ObjectLockConfig,
|
||||
@ -28,23 +30,28 @@ use std::io::BufReader;
|
||||
use xmltree::Element;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Response of [list_buckets()](crate::s3::client::Client::list_buckets) API
|
||||
pub struct ListBucketsResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub buckets: Vec<Bucket>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Base response for bucket operation
|
||||
pub struct BucketResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
pub bucket_name: String,
|
||||
}
|
||||
|
||||
/// Response of [make_bucket()](crate::s3::client::Client::make_bucket) API
|
||||
pub type MakeBucketResponse = BucketResponse;
|
||||
|
||||
/// Response of [remove_bucket()](crate::s3::client::Client::remove_bucket) API
|
||||
pub type RemoveBucketResponse = BucketResponse;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Base response for object operation
|
||||
pub struct ObjectResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -53,9 +60,11 @@ pub struct ObjectResponse {
|
||||
pub version_id: Option<String>,
|
||||
}
|
||||
|
||||
/// Response of [remove_object()](crate::s3::client::Client::remove_object) API
|
||||
pub type RemoveObjectResponse = ObjectResponse;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Base Upload ID response
|
||||
pub struct UploadIdResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -64,11 +73,14 @@ pub struct UploadIdResponse {
|
||||
pub upload_id: String,
|
||||
}
|
||||
|
||||
/// Response of [abort_multipart_upload()](crate::s3::client::Client::abort_multipart_upload) API
|
||||
pub type AbortMultipartUploadResponse = UploadIdResponse;
|
||||
|
||||
/// Response of [create_multipart_upload()](crate::s3::client::Client::create_multipart_upload) API
|
||||
pub type CreateMultipartUploadResponse = UploadIdResponse;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Base response for put object
|
||||
pub struct PutObjectBaseResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub bucket_name: String,
|
||||
@ -78,23 +90,32 @@ pub struct PutObjectBaseResponse {
|
||||
pub version_id: Option<String>,
|
||||
}
|
||||
|
||||
/// Response of [complete_multipart_upload()](crate::s3::client::Client::complete_multipart_upload) API
|
||||
pub type CompleteMultipartUploadResponse = PutObjectBaseResponse;
|
||||
|
||||
/// Response of [put_object_api()](crate::s3::client::Client::put_object_api) S3 API
|
||||
pub type PutObjectApiResponse = PutObjectBaseResponse;
|
||||
|
||||
/// Response of [upload_part()](crate::s3::client::Client::upload_part) S3 API
|
||||
pub type UploadPartResponse = PutObjectApiResponse;
|
||||
|
||||
/// Response of [put_object()](crate::s3::client::Client::put_object) API
|
||||
pub type PutObjectResponse = PutObjectApiResponse;
|
||||
|
||||
/// Response of [upload_part_copy()](crate::s3::client::Client::upload_part_copy) S3 API
|
||||
pub type UploadPartCopyResponse = PutObjectApiResponse;
|
||||
|
||||
/// Response of [copy_object()](crate::s3::client::Client::copy_object) API
|
||||
pub type CopyObjectResponse = PutObjectApiResponse;
|
||||
|
||||
/// Response of [compose_object()](crate::s3::client::Client::compose_object) API
|
||||
pub type ComposeObjectResponse = PutObjectApiResponse;
|
||||
|
||||
/// Response of [upload_object()](crate::s3::client::Client::upload_object) API
|
||||
pub type UploadObjectResponse = PutObjectApiResponse;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Response of [stat_object()](crate::s3::client::Client::stat_object) API
|
||||
pub struct StatObjectResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -184,6 +205,7 @@ impl StatObjectResponse {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Error defintion of [remove_objects_api()](crate::s3::client::Client::remove_objects_api) S3 API
|
||||
pub struct DeleteError {
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
@ -192,6 +214,7 @@ pub struct DeleteError {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Deleted object defintion of [remove_objects_api()](crate::s3::client::Client::remove_objects_api) S3 API
|
||||
pub struct DeletedObject {
|
||||
pub name: String,
|
||||
pub version_id: Option<String>,
|
||||
@ -200,6 +223,7 @@ pub struct DeletedObject {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [remove_objects_api()](crate::s3::client::Client::remove_objects_api) S3 API
|
||||
pub struct RemoveObjectsApiResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -208,9 +232,11 @@ pub struct RemoveObjectsApiResponse {
|
||||
pub errors: Vec<DeleteError>,
|
||||
}
|
||||
|
||||
/// Response of [remove_objects()](crate::s3::client::Client::remove_objects) API
|
||||
pub type RemoveObjectsResponse = RemoveObjectsApiResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [list_objects_v1()](crate::s3::client::Client::list_objects_v1) S3 API
|
||||
pub struct ListObjectsV1Response {
|
||||
pub headers: HeaderMap,
|
||||
pub name: String,
|
||||
@ -225,6 +251,7 @@ pub struct ListObjectsV1Response {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [list_objects_v2()](crate::s3::client::Client::list_objects_v2) S3 API
|
||||
pub struct ListObjectsV2Response {
|
||||
pub headers: HeaderMap,
|
||||
pub name: String,
|
||||
@ -241,6 +268,7 @@ pub struct ListObjectsV2Response {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [list_object_versions()](crate::s3::client::Client::list_object_versions) S3 API
|
||||
pub struct ListObjectVersionsResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub name: String,
|
||||
@ -257,6 +285,7 @@ pub struct ListObjectVersionsResponse {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [list_objects()](crate::s3::client::Client::list_objects) API
|
||||
pub struct ListObjectsResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub name: String,
|
||||
@ -284,6 +313,7 @@ pub struct ListObjectsResponse {
|
||||
pub next_version_id_marker: String,
|
||||
}
|
||||
|
||||
/// Response of [select_object_content()](crate::s3::client::Client::select_object_content) API
|
||||
pub struct SelectObjectContentResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -607,6 +637,7 @@ impl SelectObjectContentResponse {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [listen_bucket_notification()](crate::s3::client::Client::listen_bucket_notification) API
|
||||
pub struct ListenBucketNotificationResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -627,9 +658,11 @@ impl ListenBucketNotificationResponse {
|
||||
}
|
||||
}
|
||||
|
||||
/// Response of [delete_bucket_encryption()](crate::s3::client::Client::delete_bucket_encryption) API
|
||||
pub type DeleteBucketEncryptionResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_encryption()](crate::s3::client::Client::get_bucket_encryption) API
|
||||
pub struct GetBucketEncryptionResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -637,13 +670,17 @@ pub struct GetBucketEncryptionResponse {
|
||||
pub config: SseConfig,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_encryption()](crate::s3::client::Client::set_bucket_encryption) API
|
||||
pub type SetBucketEncryptionResponse = BucketResponse;
|
||||
|
||||
/// Response of [enable_object_legal_hold()](crate::s3::client::Client::enable_object_legal_hold) API
|
||||
pub type EnableObjectLegalHoldResponse = ObjectResponse;
|
||||
|
||||
/// Response of [disable_object_legal_hold()](crate::s3::client::Client::disable_object_legal_hold) API
|
||||
pub type DisableObjectLegalHoldResponse = ObjectResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [is_object_legal_hold_enabled()](crate::s3::client::Client::is_object_legal_hold_enabled) API
|
||||
pub struct IsObjectLegalHoldEnabledResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -653,9 +690,11 @@ pub struct IsObjectLegalHoldEnabledResponse {
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
/// Response of [delete_bucket_lifecycle()](crate::s3::client::Client::delete_bucket_lifecycle) API
|
||||
pub type DeleteBucketLifecycleResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_lifecycle()](crate::s3::client::Client::get_bucket_lifecycle) API
|
||||
pub struct GetBucketLifecycleResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -663,11 +702,14 @@ pub struct GetBucketLifecycleResponse {
|
||||
pub config: LifecycleConfig,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_lifecycle()](crate::s3::client::Client::set_bucket_lifecycle) API
|
||||
pub type SetBucketLifecycleResponse = BucketResponse;
|
||||
|
||||
/// Response of [delete_bucket_notification()](crate::s3::client::Client::delete_bucket_notification) API
|
||||
pub type DeleteBucketNotificationResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_notification()](crate::s3::client::Client::get_bucket_notification) API
|
||||
pub struct GetBucketNotificationResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -675,11 +717,14 @@ pub struct GetBucketNotificationResponse {
|
||||
pub config: NotificationConfig,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_notification()](crate::s3::client::Client::set_bucket_notification) API
|
||||
pub type SetBucketNotificationResponse = BucketResponse;
|
||||
|
||||
/// Response of [delete_bucket_policy()](crate::s3::client::Client::delete_bucket_policy) API
|
||||
pub type DeleteBucketPolicyResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_policy()](crate::s3::client::Client::get_bucket_policy) API
|
||||
pub struct GetBucketPolicyResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -687,11 +732,14 @@ pub struct GetBucketPolicyResponse {
|
||||
pub config: String,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API
|
||||
pub type SetBucketPolicyResponse = BucketResponse;
|
||||
|
||||
/// Response of [delete_bucket_replication()](crate::s3::client::Client::delete_bucket_replication) API
|
||||
pub type DeleteBucketReplicationResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_replication()](crate::s3::client::Client::get_bucket_replication) API
|
||||
pub struct GetBucketReplicationResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -699,11 +747,14 @@ pub struct GetBucketReplicationResponse {
|
||||
pub config: ReplicationConfig,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_replication()](crate::s3::client::Client::set_bucket_replication) API
|
||||
pub type SetBucketReplicationResponse = BucketResponse;
|
||||
|
||||
/// Response of [delete_bucket_tags()](crate::s3::client::Client::delete_bucket_tags) API
|
||||
pub type DeleteBucketTagsResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_tags()](crate::s3::client::Client::get_bucket_tags) API
|
||||
pub struct GetBucketTagsResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -711,9 +762,11 @@ pub struct GetBucketTagsResponse {
|
||||
pub tags: std::collections::HashMap<String, String>,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_tags()](crate::s3::client::Client::set_bucket_tags) API
|
||||
pub type SetBucketTagsResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_bucket_versioning()](crate::s3::client::Client::get_bucket_versioning) API
|
||||
pub struct GetBucketVersioningResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -722,11 +775,14 @@ pub struct GetBucketVersioningResponse {
|
||||
pub mfa_delete: Option<bool>,
|
||||
}
|
||||
|
||||
/// Response of [set_bucket_versioning()](crate::s3::client::Client::set_bucket_versioning) API
|
||||
pub type SetBucketVersioningResponse = BucketResponse;
|
||||
|
||||
/// Response of [delete_object_lock_config()](crate::s3::client::Client::delete_object_lock_config) API
|
||||
pub type DeleteObjectLockConfigResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_object_lock_config()](crate::s3::client::Client::get_object_lock_config) API
|
||||
pub struct GetObjectLockConfigResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -734,9 +790,11 @@ pub struct GetObjectLockConfigResponse {
|
||||
pub config: ObjectLockConfig,
|
||||
}
|
||||
|
||||
/// Response of [set_object_lock_config()](crate::s3::client::Client::set_object_lock_config) API
|
||||
pub type SetObjectLockConfigResponse = BucketResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_object_retention()](crate::s3::client::Client::get_object_retention) API
|
||||
pub struct GetObjectRetentionResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -747,11 +805,14 @@ pub struct GetObjectRetentionResponse {
|
||||
pub retain_until_date: Option<UtcTime>,
|
||||
}
|
||||
|
||||
/// Response of [set_object_retention()](crate::s3::client::Client::set_object_retention) API
|
||||
pub type SetObjectRetentionResponse = ObjectResponse;
|
||||
|
||||
/// Response of [delete_object_tags()](crate::s3::client::Client::delete_object_tags) API
|
||||
pub type DeleteObjectTagsResponse = ObjectResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_object_tags()](crate::s3::client::Client::get_object_tags) API
|
||||
pub struct GetObjectTagsResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
@ -761,9 +822,11 @@ pub struct GetObjectTagsResponse {
|
||||
pub tags: std::collections::HashMap<String, String>,
|
||||
}
|
||||
|
||||
/// Response of [set_object_tags()](crate::s3::client::Client::set_object_tags) API
|
||||
pub type SetObjectTagsResponse = ObjectResponse;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [get_presigned_object_url()](crate::s3::client::Client::get_presigned_object_url) API
|
||||
pub struct GetPresignedObjectUrlResponse {
|
||||
pub region: String,
|
||||
pub bucket_name: String,
|
||||
@ -773,6 +836,7 @@ pub struct GetPresignedObjectUrlResponse {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Response of [download_object()](crate::s3::client::Client::download_object) API
|
||||
pub struct DownloadObjectResponse {
|
||||
pub headers: HeaderMap,
|
||||
pub region: String,
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Signature V4 for S3 API
|
||||
|
||||
use crate::s3::utils::{
|
||||
get_canonical_headers, get_canonical_query_string, sha256_hash, to_amz_date, to_signer_date,
|
||||
Multimap, UtcTime,
|
||||
@ -22,16 +24,19 @@ use hmac::{Hmac, Mac};
|
||||
use hyper::http::Method;
|
||||
use sha2::Sha256;
|
||||
|
||||
/// Returns HMAC hash for given key and data
|
||||
pub fn hmac_hash(key: &[u8], data: &[u8]) -> Vec<u8> {
|
||||
let mut hasher = Hmac::<Sha256>::new_from_slice(key).expect("HMAC can take key of any size");
|
||||
hasher.update(data);
|
||||
hasher.finalize().into_bytes().to_vec()
|
||||
}
|
||||
|
||||
/// Returns hex encoded HMAC hash for given key and data
|
||||
pub fn hmac_hash_hex(key: &[u8], data: &[u8]) -> String {
|
||||
hexencode(hmac_hash(key, data))
|
||||
}
|
||||
|
||||
/// Returns scope value of given date, region and service name
|
||||
pub fn get_scope(date: UtcTime, region: &str, service_name: &str) -> String {
|
||||
format!(
|
||||
"{}/{}/{}/aws4_request",
|
||||
@ -41,6 +46,7 @@ pub fn get_scope(date: UtcTime, region: &str, service_name: &str) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns hex encoded SHA256 hash of canonical request
|
||||
pub fn get_canonical_request_hash(
|
||||
method: &Method,
|
||||
uri: &str,
|
||||
@ -63,6 +69,7 @@ pub fn get_canonical_request_hash(
|
||||
return sha256_hash(canonical_request.as_bytes());
|
||||
}
|
||||
|
||||
/// Returns string-to-sign value of given date, scope and canonical request hash
|
||||
pub fn get_string_to_sign(date: UtcTime, scope: &str, canonical_request_hash: &str) -> String {
|
||||
format!(
|
||||
"AWS4-HMAC-SHA256\n{}\n{}\n{}",
|
||||
@ -72,6 +79,7 @@ pub fn get_string_to_sign(date: UtcTime, scope: &str, canonical_request_hash: &s
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns signing key of given secret key, date, region and service name
|
||||
pub fn get_signing_key(
|
||||
secret_key: &str,
|
||||
date: UtcTime,
|
||||
@ -87,10 +95,12 @@ pub fn get_signing_key(
|
||||
return hmac_hash(date_region_service_key.as_slice(), b"aws4_request");
|
||||
}
|
||||
|
||||
/// Returns signature value for given signing key and string-to-sign
|
||||
pub fn get_signature(signing_key: &[u8], string_to_sign: &[u8]) -> String {
|
||||
hmac_hash_hex(signing_key, string_to_sign)
|
||||
}
|
||||
|
||||
/// Returns authorization value for given access key, scope, signed headers and signature
|
||||
pub fn get_authorization(
|
||||
access_key: &str,
|
||||
scope: &str,
|
||||
@ -103,6 +113,7 @@ pub fn get_authorization(
|
||||
)
|
||||
}
|
||||
|
||||
/// Signs and updates headers for given parameters
|
||||
pub fn sign_v4(
|
||||
service_name: &str,
|
||||
method: &Method,
|
||||
@ -134,6 +145,7 @@ pub fn sign_v4(
|
||||
headers.insert("Authorization".to_string(), authorization);
|
||||
}
|
||||
|
||||
/// Signs and updates headers for given parameters for S3 request
|
||||
pub fn sign_v4_s3(
|
||||
method: &Method,
|
||||
uri: &str,
|
||||
@ -159,6 +171,7 @@ pub fn sign_v4_s3(
|
||||
)
|
||||
}
|
||||
|
||||
/// Signs and updates headers for given parameters for STS request
|
||||
pub fn sign_v4_sts(
|
||||
method: &Method,
|
||||
uri: &str,
|
||||
@ -184,6 +197,7 @@ pub fn sign_v4_sts(
|
||||
)
|
||||
}
|
||||
|
||||
/// Signs and updates headers for given parameters for pre-sign request
|
||||
pub fn presign_v4(
|
||||
method: &Method,
|
||||
host: &str,
|
||||
@ -230,6 +244,7 @@ pub fn presign_v4(
|
||||
query_params.insert("X-Amz-Signature".to_string(), signature);
|
||||
}
|
||||
|
||||
/// Signs and updates headers for given parameters for pre-sign POST request
|
||||
pub fn post_presign_v4(
|
||||
string_to_sign: &str,
|
||||
secret_key: &str,
|
||||
|
||||
@ -13,9 +13,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Server side encryption definitions
|
||||
|
||||
use crate::s3::utils;
|
||||
use std::any::Any;
|
||||
|
||||
/// Base server side encryption
|
||||
pub trait Sse: std::fmt::Debug {
|
||||
fn headers(&self) -> utils::Multimap;
|
||||
fn copy_headers(&self) -> utils::Multimap;
|
||||
@ -24,6 +27,7 @@ pub trait Sse: std::fmt::Debug {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Server side encryption customer key type
|
||||
pub struct SseCustomerKey {
|
||||
headers: utils::Multimap,
|
||||
copy_headers: utils::Multimap,
|
||||
@ -88,6 +92,7 @@ impl Sse for SseCustomerKey {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Server side encryption KMS type
|
||||
pub struct SseKms {
|
||||
headers: utils::Multimap,
|
||||
}
|
||||
@ -133,6 +138,7 @@ impl Sse for SseKms {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Server side encryption S3 type
|
||||
pub struct SseS3 {
|
||||
headers: utils::Multimap,
|
||||
}
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Various types for S3 API requests and responses
|
||||
|
||||
use crate::s3::error::Error;
|
||||
use crate::s3::utils::{
|
||||
from_iso8601utc, get_default_text, get_option_text, get_text, to_iso8601utc, UtcTime,
|
||||
@ -23,6 +25,7 @@ use std::fmt;
|
||||
use xmltree::Element;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Contains information of an item of [list_objects()](crate::s3::client::Client::list_objects) API
|
||||
pub struct Item {
|
||||
pub name: String,
|
||||
pub last_modified: Option<UtcTime>,
|
||||
@ -40,18 +43,21 @@ pub struct Item {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Contains bucket name and creation date
|
||||
pub struct Bucket {
|
||||
pub name: String,
|
||||
pub creation_date: UtcTime,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Contains part number and etag of multipart upload
|
||||
pub struct Part {
|
||||
pub number: u16,
|
||||
pub etag: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Contains retention mode information
|
||||
pub enum RetentionMode {
|
||||
GOVERNANCE,
|
||||
COMPLIANCE,
|
||||
@ -77,11 +83,13 @@ impl fmt::Display for RetentionMode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Contains retention mode and retain until date
|
||||
pub struct Retention {
|
||||
pub mode: RetentionMode,
|
||||
pub retain_until_date: UtcTime,
|
||||
}
|
||||
|
||||
/// Parses legal hold string value
|
||||
pub fn parse_legal_hold(s: &str) -> Result<bool, Error> {
|
||||
match s {
|
||||
"ON" => Ok(true),
|
||||
@ -91,12 +99,14 @@ pub fn parse_legal_hold(s: &str) -> Result<bool, Error> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
/// Contains delete object name and optional version ID
|
||||
pub struct DeleteObject<'a> {
|
||||
pub name: &'a str,
|
||||
pub version_id: Option<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Compression types
|
||||
pub enum CompressionType {
|
||||
NONE,
|
||||
GZIP,
|
||||
@ -114,6 +124,7 @@ impl fmt::Display for CompressionType {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// File header information types
|
||||
pub enum FileHeaderInfo {
|
||||
USE,
|
||||
IGNORE,
|
||||
@ -131,6 +142,7 @@ impl fmt::Display for FileHeaderInfo {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// JSON document types
|
||||
pub enum JsonType {
|
||||
DOCUMENT,
|
||||
LINES,
|
||||
@ -146,6 +158,7 @@ impl fmt::Display for JsonType {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Quote fields types
|
||||
pub enum QuoteFields {
|
||||
ALWAYS,
|
||||
ASNEEDED,
|
||||
@ -161,6 +174,7 @@ impl fmt::Display for QuoteFields {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// CSV input serialization definitions
|
||||
pub struct CsvInputSerialization {
|
||||
pub compression_type: Option<CompressionType>,
|
||||
pub allow_quoted_record_delimiter: bool,
|
||||
@ -173,15 +187,18 @@ pub struct CsvInputSerialization {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// JSON input serialization definitions
|
||||
pub struct JsonInputSerialization {
|
||||
pub compression_type: Option<CompressionType>,
|
||||
pub json_type: Option<JsonType>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Parque input serialization definitions
|
||||
pub struct ParquetInputSerialization;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// CSV output serialization definitions
|
||||
pub struct CsvOutputSerialization {
|
||||
pub field_delimiter: Option<char>,
|
||||
pub quote_character: Option<char>,
|
||||
@ -191,11 +208,13 @@ pub struct CsvOutputSerialization {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// JSON output serialization definitions
|
||||
pub struct JsonOutputSerialization {
|
||||
pub record_delimiter: Option<char>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
/// Select request for [select_object_content()](crate::s3::client::Client::select_object_content) API
|
||||
pub struct SelectRequest<'a> {
|
||||
pub expr: &'a str,
|
||||
pub csv_input: Option<CsvInputSerialization>,
|
||||
@ -456,6 +475,7 @@ impl<'a> SelectRequest<'a> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Progress information of [select_object_content()](crate::s3::client::Client::select_object_content) API
|
||||
pub struct SelectProgress {
|
||||
pub bytes_scanned: usize,
|
||||
pub bytes_progressed: usize,
|
||||
@ -463,14 +483,17 @@ pub struct SelectProgress {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// User identity contains principal ID
|
||||
pub struct UserIdentity {
|
||||
#[serde(alias = "principalId")]
|
||||
pub principal_id: Option<String>,
|
||||
}
|
||||
|
||||
/// Owner identity contains principal ID
|
||||
pub type OwnerIdentity = UserIdentity;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// Request parameters contain principal ID, region and source IP address
|
||||
pub struct RequestParameters {
|
||||
#[serde(alias = "principalId")]
|
||||
pub principal_id: Option<String>,
|
||||
@ -481,6 +504,7 @@ pub struct RequestParameters {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// Response elements information
|
||||
pub struct ResponseElements {
|
||||
#[serde(alias = "content-length")]
|
||||
pub content_length: Option<String>,
|
||||
@ -493,6 +517,7 @@ pub struct ResponseElements {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// S3 bucket information
|
||||
pub struct S3Bucket {
|
||||
#[serde(alias = "name")]
|
||||
pub name: Option<String>,
|
||||
@ -503,6 +528,7 @@ pub struct S3Bucket {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// S3 object information
|
||||
pub struct S3Object {
|
||||
#[serde(alias = "key")]
|
||||
pub key: Option<String>,
|
||||
@ -519,6 +545,7 @@ pub struct S3Object {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// S3 definitions for NotificationRecord
|
||||
pub struct S3 {
|
||||
#[serde(alias = "s3SchemaVersion")]
|
||||
pub s3_schema_version: Option<String>,
|
||||
@ -531,6 +558,7 @@ pub struct S3 {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// Source information
|
||||
pub struct Source {
|
||||
#[serde(alias = "host")]
|
||||
pub host: Option<String>,
|
||||
@ -541,6 +569,7 @@ pub struct Source {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// Notification record information
|
||||
pub struct NotificationRecord {
|
||||
#[serde(alias = "eventVersion")]
|
||||
pub event_version: Option<String>,
|
||||
@ -565,12 +594,14 @@ pub struct NotificationRecord {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// Contains notification records
|
||||
pub struct NotificationRecords {
|
||||
#[serde(alias = "Records")]
|
||||
pub records: Vec<NotificationRecord>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Directive types
|
||||
pub enum Directive {
|
||||
Copy,
|
||||
Replace,
|
||||
@ -596,6 +627,7 @@ impl fmt::Display for Directive {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Server-side information configuration
|
||||
pub struct SseConfig {
|
||||
pub sse_algorithm: String,
|
||||
pub kms_master_key_id: Option<String>,
|
||||
@ -636,18 +668,21 @@ impl SseConfig {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Contains key and value
|
||||
pub struct Tag {
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// And operator contains prefix and tags
|
||||
pub struct AndOperator {
|
||||
pub prefix: Option<String>,
|
||||
pub tags: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Filter information
|
||||
pub struct Filter {
|
||||
pub and_operator: Option<AndOperator>,
|
||||
pub prefix: Option<String>,
|
||||
@ -763,6 +798,7 @@ impl Filter {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Lifecycle rule information
|
||||
pub struct LifecycleRule {
|
||||
pub abort_incomplete_multipart_upload_days_after_initiation: Option<usize>,
|
||||
pub expiration_date: Option<UtcTime>,
|
||||
@ -900,6 +936,7 @@ impl LifecycleRule {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Lifecycle configuration
|
||||
pub struct LifecycleConfig {
|
||||
pub rules: Vec<LifecycleRule>,
|
||||
}
|
||||
@ -1155,6 +1192,7 @@ fn to_xml_common_notification_config(
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Prefix filter rule
|
||||
pub struct PrefixFilterRule {
|
||||
pub value: String,
|
||||
}
|
||||
@ -1164,6 +1202,7 @@ impl PrefixFilterRule {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Suffix filter rule
|
||||
pub struct SuffixFilterRule {
|
||||
pub value: String,
|
||||
}
|
||||
@ -1173,6 +1212,7 @@ impl SuffixFilterRule {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Cloud function configuration information
|
||||
pub struct CloudFuncConfig {
|
||||
pub events: Vec<String>,
|
||||
pub id: Option<String>,
|
||||
@ -1223,6 +1263,7 @@ impl CloudFuncConfig {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Queue configuration information
|
||||
pub struct QueueConfig {
|
||||
pub events: Vec<String>,
|
||||
pub id: Option<String>,
|
||||
@ -1273,6 +1314,7 @@ impl QueueConfig {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Topic configuration information
|
||||
pub struct TopicConfig {
|
||||
pub events: Vec<String>,
|
||||
pub id: Option<String>,
|
||||
@ -1323,6 +1365,7 @@ impl TopicConfig {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Notification configuration information
|
||||
pub struct NotificationConfig {
|
||||
pub cloud_func_config_list: Option<Vec<CloudFuncConfig>>,
|
||||
pub queue_config_list: Option<Vec<QueueConfig>>,
|
||||
@ -1413,6 +1456,7 @@ impl NotificationConfig {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Access control translation information
|
||||
pub struct AccessControlTranslation {
|
||||
pub owner: String,
|
||||
}
|
||||
@ -1432,11 +1476,13 @@ impl Default for AccessControlTranslation {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Encryption configuration information
|
||||
pub struct EncryptionConfig {
|
||||
pub replica_kms_key_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Metrics information
|
||||
pub struct Metrics {
|
||||
pub event_threshold_minutes: Option<i32>,
|
||||
pub status: bool,
|
||||
@ -1452,6 +1498,7 @@ impl Metrics {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Replication time information
|
||||
pub struct ReplicationTime {
|
||||
pub time_minutes: Option<i32>,
|
||||
pub status: bool,
|
||||
@ -1467,6 +1514,7 @@ impl ReplicationTime {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Destination information
|
||||
pub struct Destination {
|
||||
pub bucket_arn: String,
|
||||
pub access_control_translation: Option<AccessControlTranslation>,
|
||||
@ -1601,11 +1649,13 @@ impl Destination {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Source selection criteria information
|
||||
pub struct SourceSelectionCriteria {
|
||||
pub sse_kms_encrypted_objects_status: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Replication rule information
|
||||
pub struct ReplicationRule {
|
||||
pub destination: Destination,
|
||||
pub delete_marker_replication_status: Option<bool>,
|
||||
@ -1750,6 +1800,7 @@ impl ReplicationRule {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Replication configuration information
|
||||
pub struct ReplicationConfig {
|
||||
pub role: Option<String>,
|
||||
pub rules: Vec<ReplicationRule>,
|
||||
@ -1794,6 +1845,7 @@ impl ReplicationConfig {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Object lock configuration information
|
||||
pub struct ObjectLockConfig {
|
||||
pub retention_mode: Option<RetentionMode>,
|
||||
pub retention_duration_days: Option<i32>,
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Various utility and helper functions
|
||||
|
||||
use crate::s3::error::Error;
|
||||
use base64::engine::general_purpose::STANDARD as BASE64;
|
||||
use base64::engine::Engine as _;
|
||||
@ -29,14 +31,18 @@ pub use urlencoding::decode as urldecode;
|
||||
pub use urlencoding::encode as urlencode;
|
||||
use xmltree::Element;
|
||||
|
||||
/// Date and time with UTC timezone
|
||||
pub type UtcTime = DateTime<Utc>;
|
||||
|
||||
/// Multimap for string key and string value
|
||||
pub type Multimap = MultiMap<String, String>;
|
||||
|
||||
/// Encodes data using base64 algorithm
|
||||
pub fn b64encode<T: AsRef<[u8]>>(input: T) -> String {
|
||||
BASE64.encode(input)
|
||||
}
|
||||
|
||||
/// Merges two multimaps.
|
||||
pub fn merge(m1: &mut Multimap, m2: &Multimap) {
|
||||
for (key, values) in m2.iter_all() {
|
||||
for value in values {
|
||||
@ -45,36 +51,44 @@ pub fn merge(m1: &mut Multimap, m2: &Multimap) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes CRC32 of given data.
|
||||
pub fn crc32(data: &[u8]) -> u32 {
|
||||
Crc::<u32>::new(&CRC_32_ISO_HDLC).checksum(data)
|
||||
}
|
||||
|
||||
/// Converts data array into 32 bit unsigned int
|
||||
pub fn uint32(mut data: &[u8]) -> Result<u32, std::io::Error> {
|
||||
data.read_u32::<BigEndian>()
|
||||
}
|
||||
|
||||
/// Gets hex encoded SHA256 hash of given data
|
||||
pub fn sha256_hash(data: &[u8]) -> String {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(data);
|
||||
format!("{:x}", hasher.finalize())
|
||||
}
|
||||
|
||||
/// Gets bas64 encoded MD5 hash of given data
|
||||
pub fn md5sum_hash(data: &[u8]) -> String {
|
||||
b64encode(md5compute(data).as_slice())
|
||||
}
|
||||
|
||||
/// Gets current UTC time
|
||||
pub fn utc_now() -> UtcTime {
|
||||
chrono::offset::Utc::now()
|
||||
}
|
||||
|
||||
/// Gets signer date value of given time
|
||||
pub fn to_signer_date(time: UtcTime) -> String {
|
||||
time.format("%Y%m%d").to_string()
|
||||
}
|
||||
|
||||
/// Gets AMZ date value of given time
|
||||
pub fn to_amz_date(time: UtcTime) -> String {
|
||||
time.format("%Y%m%dT%H%M%SZ").to_string()
|
||||
}
|
||||
|
||||
/// Gets HTTP header value of given time
|
||||
pub fn to_http_header_value(time: UtcTime) -> String {
|
||||
format!(
|
||||
"{}, {} {} {} GMT",
|
||||
@ -99,10 +113,12 @@ pub fn to_http_header_value(time: UtcTime) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
/// Gets ISO8601 UTC formatted value of given time
|
||||
pub fn to_iso8601utc(time: UtcTime) -> String {
|
||||
time.format("%Y-%m-%dT%H:%M:%S.%3fZ").to_string()
|
||||
}
|
||||
|
||||
/// Parses ISO8601 UTC formatted value to time
|
||||
pub fn from_iso8601utc(s: &str) -> Result<UtcTime, ParseError> {
|
||||
Ok(DateTime::<Utc>::from_naive_utc_and_offset(
|
||||
match NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S.%3fZ") {
|
||||
@ -113,6 +129,7 @@ pub fn from_iso8601utc(s: &str) -> Result<UtcTime, ParseError> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Parses HTTP header value to time
|
||||
pub fn from_http_header_value(s: &str) -> Result<UtcTime, ParseError> {
|
||||
Ok(DateTime::<Utc>::from_naive_utc_and_offset(
|
||||
NaiveDateTime::parse_from_str(s, "%a, %d %b %Y %H:%M:%S GMT")?,
|
||||
@ -120,6 +137,7 @@ pub fn from_http_header_value(s: &str) -> Result<UtcTime, ParseError> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Converts multimap to HTTP headers
|
||||
pub fn to_http_headers(map: &Multimap) -> Vec<String> {
|
||||
let mut headers: Vec<String> = Vec::new();
|
||||
for (key, values) in map.iter_all() {
|
||||
@ -134,6 +152,7 @@ pub fn to_http_headers(map: &Multimap) -> Vec<String> {
|
||||
headers
|
||||
}
|
||||
|
||||
/// Converts multimap to HTTP query string
|
||||
pub fn to_query_string(map: &Multimap) -> String {
|
||||
let mut query = String::new();
|
||||
for (key, values) in map.iter_all() {
|
||||
@ -149,6 +168,7 @@ pub fn to_query_string(map: &Multimap) -> String {
|
||||
query
|
||||
}
|
||||
|
||||
/// Converts multimap to canonical query string
|
||||
pub fn get_canonical_query_string(map: &Multimap) -> String {
|
||||
let mut keys: Vec<String> = Vec::new();
|
||||
for (key, _) in map.iter() {
|
||||
@ -176,6 +196,7 @@ pub fn get_canonical_query_string(map: &Multimap) -> String {
|
||||
query
|
||||
}
|
||||
|
||||
/// Converts multimap to signed headers and canonical headers
|
||||
pub fn get_canonical_headers(map: &Multimap) -> (String, String) {
|
||||
lazy_static! {
|
||||
static ref MULTI_SPACE_REGEX: Regex = Regex::new("( +)").unwrap();
|
||||
@ -223,6 +244,7 @@ pub fn get_canonical_headers(map: &Multimap) -> (String, String) {
|
||||
(signed_headers, canonical_headers)
|
||||
}
|
||||
|
||||
/// Validates given bucket name
|
||||
pub fn check_bucket_name(bucket_name: &str, strict: bool) -> Result<(), Error> {
|
||||
if bucket_name.trim().is_empty() {
|
||||
return Err(Error::InvalidBucketName(String::from(
|
||||
@ -277,6 +299,7 @@ pub fn check_bucket_name(bucket_name: &str, strict: bool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets text value of given XML element for given tag.
|
||||
pub fn get_text(element: &Element, tag: &str) -> Result<String, Error> {
|
||||
Ok(element
|
||||
.get_child(tag)
|
||||
@ -286,6 +309,7 @@ pub fn get_text(element: &Element, tag: &str) -> Result<String, Error> {
|
||||
.to_string())
|
||||
}
|
||||
|
||||
/// Gets optional text value of given XML element for given tag.
|
||||
pub fn get_option_text(element: &Element, tag: &str) -> Option<String> {
|
||||
if let Some(v) = element.get_child(tag) {
|
||||
return Some(v.get_text().unwrap_or_default().to_string());
|
||||
@ -294,12 +318,14 @@ pub fn get_option_text(element: &Element, tag: &str) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Gets default text value of given XML element for given tag.
|
||||
pub fn get_default_text(element: &Element, tag: &str) -> String {
|
||||
element.get_child(tag).map_or(String::new(), |v| {
|
||||
v.get_text().unwrap_or_default().to_string()
|
||||
})
|
||||
}
|
||||
|
||||
/// Copies source byte slice into destination byte slice
|
||||
pub fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
|
||||
let mut c = 0;
|
||||
for (d, s) in dst.iter_mut().zip(src.iter()) {
|
||||
|
||||
@ -567,7 +567,7 @@ impl<'a> ClientTest<'_> {
|
||||
};
|
||||
|
||||
let spawned_task = task::spawn(listen_task());
|
||||
task::sleep(std::time::Duration::from_millis(100)).await;
|
||||
task::sleep(std::time::Duration::from_millis(200)).await;
|
||||
|
||||
let size = 16_usize;
|
||||
self.client
|
||||
@ -1059,10 +1059,14 @@ impl<'a> ClientTest<'_> {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut args = SetObjectRetentionArgs::new(&bucket_name, &object_name).unwrap();
|
||||
args.retention_mode = Some(RetentionMode::GOVERNANCE);
|
||||
let retain_until_date = utc_now() + Duration::days(1);
|
||||
args.retain_until_date = Some(retain_until_date);
|
||||
let args = SetObjectRetentionArgs::new(
|
||||
&bucket_name,
|
||||
&object_name,
|
||||
Some(RetentionMode::GOVERNANCE),
|
||||
Some(retain_until_date),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
self.client.set_object_retention(&args).await.unwrap();
|
||||
|
||||
@ -1080,7 +1084,7 @@ impl<'a> ClientTest<'_> {
|
||||
_ => false,
|
||||
},);
|
||||
|
||||
let mut args = SetObjectRetentionArgs::new(&bucket_name, &object_name).unwrap();
|
||||
let mut args = SetObjectRetentionArgs::new(&bucket_name, &object_name, None, None).unwrap();
|
||||
args.bypass_governance_mode = true;
|
||||
self.client.set_object_retention(&args).await.unwrap();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user