From 4676ae8a57e8d1df1a2eb9e6de8b9160b0782e38 Mon Sep 17 00:00:00 2001 From: Aditya Manthramurthy Date: Mon, 25 Sep 2023 18:11:48 -0700 Subject: [PATCH] Remove lifetime parameter from client (#48) This change lets the Client struct take ownership of the Provider trait object so that we are remove the lifetime parameter from the Client. This change simplifies usage of the Client object. Without this it is difficult to pass the Client object to a thread. --- src/s3/args.rs | 4 ++-- src/s3/client.rs | 27 ++++++++++++++------------- tests/tests.rs | 16 ++++++++-------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/s3/args.rs b/src/s3/args.rs index 12ea28e..d67dfb4 100644 --- a/src/s3/args.rs +++ b/src/s3/args.rs @@ -677,7 +677,7 @@ impl<'a> PutObjectArgs<'a> { /// /// # Examples /// - /// ``` + /// ```no_run /// use minio::s3::args::*; /// use std::fs::File; /// let filename = "asiaphotos-2015.zip"; @@ -2632,7 +2632,7 @@ impl<'a> UploadObjectArgs<'a> { /// /// # Examples /// - /// ``` + /// ```no_run /// use minio::s3::args::*; /// let args = UploadObjectArgs::new("my-bucket", "my-object", "asiaphotos-2015.zip").unwrap(); /// ``` diff --git a/src/s3/client.rs b/src/s3/client.rs index 0cdd63d..1ff76c5 100644 --- a/src/s3/client.rs +++ b/src/s3/client.rs @@ -40,6 +40,7 @@ use std::collections::{HashMap, VecDeque}; use std::fs::File; use std::io::prelude::*; use std::io::Read; +use std::sync::Arc; use xmltree::Element; fn url_decode( @@ -202,19 +203,19 @@ fn parse_list_objects_common_prefixes( Ok(()) } -#[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> { +/// If credential provider is passed, all S3 operation requests are signed using +/// AWS Signature Version 4; else they are performed anonymously. +#[derive(Clone, Debug, Default)] +pub struct Client { client: reqwest::Client, base_url: BaseUrl, - provider: Option<&'a (dyn Provider + Send + Sync)>, + provider: Option>>, region_map: DashMap, } -impl<'a> Client<'a> { +impl Client { /// Returns a S3 client with given base URL. /// /// # Examples @@ -229,11 +230,11 @@ impl<'a> Client<'a> { /// "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", /// None, /// ); - /// let client = Client::new(base_url.clone(), Some(&static_provider), None, None).unwrap(); + /// let client = Client::new(base_url.clone(), Some(Box::new(static_provider)), None, None).unwrap(); /// ``` pub fn new( base_url: BaseUrl, - provider: Option<&(dyn Provider + Send + Sync)>, + provider: Option>, ssl_cert_file: Option, ignore_cert_check: Option, ) -> Result { @@ -263,7 +264,7 @@ impl<'a> Client<'a> { Ok(Client { client, base_url, - provider, + provider: provider.map(|v| Arc::new(v)), region_map: DashMap::new(), }) } @@ -317,7 +318,7 @@ impl<'a> Client<'a> { let date = utc_now(); headers.insert(String::from("x-amz-date"), to_amz_date(date)); - if let Some(p) = self.provider { + if let Some(p) = &self.provider { let creds = p.fetch(); if creds.session_token.is_some() { headers.insert( @@ -797,7 +798,7 @@ impl<'a> Client<'a> { }) } - async fn calculate_part_count( + async fn calculate_part_count<'a>( &self, sources: &'a mut Vec>, ) -> Result { @@ -2205,7 +2206,7 @@ impl<'a> Client<'a> { Some(args.object), )?; - if let Some(p) = self.provider { + if let Some(p) = &self.provider { let creds = p.fetch(); if let Some(t) = creds.session_token { query_params.insert(String::from("X-Amz-Security-Token"), t); @@ -2251,7 +2252,7 @@ impl<'a> Client<'a> { } let region = self.get_region(policy.bucket, policy.region).await?; - let creds = self.provider.unwrap().fetch(); + let creds = self.provider.as_ref().unwrap().fetch(); policy.form_data( creds.access_key, creds.secret_key, diff --git a/tests/tests.rs b/tests/tests.rs index 13c2f06..a3a0db2 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -73,30 +73,30 @@ fn rand_object_name() -> String { Alphanumeric.sample_string(&mut rand::thread_rng(), 8) } -struct ClientTest<'a> { +struct ClientTest { base_url: BaseUrl, access_key: String, secret_key: String, ignore_cert_check: Option, ssl_cert_file: Option, - client: Client<'a>, + client: Client, test_bucket: String, } -impl<'a> ClientTest<'_> { +impl ClientTest { const SQS_ARN: &str = "arn:minio:sqs::miniojavatest:webhook"; fn new( base_url: BaseUrl, access_key: String, secret_key: String, - static_provider: &'a StaticProvider, + static_provider: StaticProvider, ignore_cert_check: Option, ssl_cert_file: Option, - ) -> ClientTest<'a> { + ) -> ClientTest { let client = Client::new( base_url.clone(), - Some(static_provider), + Some(Box::new(static_provider)), ssl_cert_file.as_ref().cloned(), ignore_cert_check, ) @@ -539,7 +539,7 @@ impl<'a> ClientTest<'_> { let static_provider = StaticProvider::new(&access_key, &secret_key, None); let client = Client::new( base_url, - Some(&static_provider), + Some(Box::new(static_provider)), ssl_cert_file, ignore_cert_check, ) @@ -1166,7 +1166,7 @@ async fn s3_tests() -> Result<(), Box> { base_url, access_key, secret_key, - &static_provider, + static_provider, Some(ignore_cert_check), ssl_cert_file, );