mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 23:36:52 +08:00
Add builder style constructor for Client (#50)
This commit is contained in:
parent
4958c01f4c
commit
e9aea2ada6
2
.github/workflows/rust.yml
vendored
2
.github/workflows/rust.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cargo fmt --all -- --check
|
cargo fmt --all -- --check
|
||||||
cargo clippy --all-targets --all-features -- -A clippy::result_large_err -A clippy::type_complexity -A clippy::too_many_arguments
|
cargo clippy --all-targets --all-features -- -A clippy::result_large_err -A clippy::type_complexity -A clippy::too_many_arguments
|
||||||
cargo build --verbose
|
cargo build --bins --examples --tests --benches --verbose
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
123
src/s3/client.rs
123
src/s3/client.rs
@ -40,6 +40,7 @@ use std::collections::{HashMap, VecDeque};
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use xmltree::Element;
|
use xmltree::Element;
|
||||||
|
|
||||||
@ -203,6 +204,92 @@ fn parse_list_objects_common_prefixes(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Client Builder manufactures a Client using given parameters.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ClientBuilder {
|
||||||
|
base_url: BaseUrl,
|
||||||
|
provider: Option<Arc<Box<(dyn Provider + Send + Sync + 'static)>>>,
|
||||||
|
ssl_cert_file: Option<PathBuf>,
|
||||||
|
ignore_cert_check: Option<bool>,
|
||||||
|
app_info: Option<(String, String)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientBuilder {
|
||||||
|
/// Creates a builder given a base URL for the MinIO service or other AWS S3
|
||||||
|
/// compatible object storage service.
|
||||||
|
pub fn new(base_url: BaseUrl) -> Self {
|
||||||
|
let mut c = ClientBuilder::default();
|
||||||
|
c.base_url = base_url;
|
||||||
|
c
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the credential provider. If not set anonymous access is used.
|
||||||
|
pub fn provider(
|
||||||
|
mut self,
|
||||||
|
provider: Option<Box<(dyn Provider + Send + Sync + 'static)>>,
|
||||||
|
) -> Self {
|
||||||
|
self.provider = provider.map(Arc::new);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the app info as an Option of (app_name, app_version) pair. This will
|
||||||
|
/// show up in the client's user-agent.
|
||||||
|
pub fn app_info(mut self, app_info: Option<(String, String)>) -> Self {
|
||||||
|
self.app_info = app_info;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set file for loading a trust certificate.
|
||||||
|
pub fn ssl_cert_file(mut self, ssl_cert_file: Option<&Path>) -> Self {
|
||||||
|
self.ssl_cert_file = ssl_cert_file.map(PathBuf::from);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set flag to ignore certificate check.
|
||||||
|
pub fn ignore_cert_check(mut self, ignore_cert_check: Option<bool>) -> Self {
|
||||||
|
self.ignore_cert_check = ignore_cert_check;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build the Client.
|
||||||
|
pub fn build(self) -> Result<Client, Error> {
|
||||||
|
let mut builder = reqwest::Client::builder().no_gzip();
|
||||||
|
|
||||||
|
let info = os_info::get();
|
||||||
|
let mut user_agent = String::from("MinIO (")
|
||||||
|
+ &info.os_type().to_string()
|
||||||
|
+ "; "
|
||||||
|
+ info.architecture().unwrap_or("unknown")
|
||||||
|
+ ") minio-rs/"
|
||||||
|
+ env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
if let Some((app_name, app_version)) = self.app_info {
|
||||||
|
user_agent.push_str(format!(" {app_name}/{app_version}").as_str());
|
||||||
|
builder = builder.user_agent(user_agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(v) = self.ignore_cert_check {
|
||||||
|
builder = builder.danger_accept_invalid_certs(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(v) = self.ssl_cert_file {
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
File::open(v)?.read_to_end(&mut buf)?;
|
||||||
|
let cert = reqwest::Certificate::from_pem(&buf)?;
|
||||||
|
builder = builder.add_root_certificate(cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = builder.build()?;
|
||||||
|
|
||||||
|
Ok(Client {
|
||||||
|
client,
|
||||||
|
base_url: self.base_url,
|
||||||
|
provider: self.provider,
|
||||||
|
region_map: DashMap::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Simple Storage Service (aka S3) client to perform bucket and object operations.
|
/// Simple Storage Service (aka S3) client to perform bucket and object operations.
|
||||||
///
|
///
|
||||||
/// If credential provider is passed, all S3 operation requests are signed using
|
/// If credential provider is passed, all S3 operation requests are signed using
|
||||||
@ -235,38 +322,14 @@ impl Client {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
base_url: BaseUrl,
|
base_url: BaseUrl,
|
||||||
provider: Option<Box<(dyn Provider + Send + Sync + 'static)>>,
|
provider: Option<Box<(dyn Provider + Send + Sync + 'static)>>,
|
||||||
ssl_cert_file: Option<String>,
|
ssl_cert_file: Option<&Path>,
|
||||||
ignore_cert_check: Option<bool>,
|
ignore_cert_check: Option<bool>,
|
||||||
) -> Result<Client, Error> {
|
) -> Result<Client, Error> {
|
||||||
let info = os_info::get();
|
ClientBuilder::new(base_url)
|
||||||
let user_agent = String::from("MinIO (")
|
.provider(provider)
|
||||||
+ &info.os_type().to_string()
|
.ssl_cert_file(ssl_cert_file)
|
||||||
+ "; "
|
.ignore_cert_check(ignore_cert_check)
|
||||||
+ info.architecture().unwrap_or("unknown")
|
.build()
|
||||||
+ ") minio-rs/"
|
|
||||||
+ env!("CARGO_PKG_VERSION");
|
|
||||||
|
|
||||||
let mut builder = reqwest::Client::builder()
|
|
||||||
.no_gzip()
|
|
||||||
.user_agent(user_agent.to_string());
|
|
||||||
if let Some(v) = ignore_cert_check {
|
|
||||||
builder = builder.danger_accept_invalid_certs(v);
|
|
||||||
}
|
|
||||||
if let Some(v) = ssl_cert_file {
|
|
||||||
let mut buf = Vec::new();
|
|
||||||
File::open(v.to_string())?.read_to_end(&mut buf)?;
|
|
||||||
let cert = reqwest::Certificate::from_pem(&buf)?;
|
|
||||||
builder = builder.add_root_certificate(cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
let client = builder.build()?;
|
|
||||||
|
|
||||||
Ok(Client {
|
|
||||||
client,
|
|
||||||
base_url,
|
|
||||||
provider: provider.map(|v| Arc::new(v)),
|
|
||||||
region_map: DashMap::new(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_headers(
|
fn build_headers(
|
||||||
|
|||||||
@ -21,6 +21,7 @@ use rand::distributions::{Alphanumeric, DistString};
|
|||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ struct ClientTest {
|
|||||||
access_key: String,
|
access_key: String,
|
||||||
secret_key: String,
|
secret_key: String,
|
||||||
ignore_cert_check: Option<bool>,
|
ignore_cert_check: Option<bool>,
|
||||||
ssl_cert_file: Option<String>,
|
ssl_cert_file: Option<PathBuf>,
|
||||||
client: Client,
|
client: Client,
|
||||||
test_bucket: String,
|
test_bucket: String,
|
||||||
}
|
}
|
||||||
@ -92,7 +93,7 @@ impl ClientTest {
|
|||||||
secret_key: String,
|
secret_key: String,
|
||||||
static_provider: StaticProvider,
|
static_provider: StaticProvider,
|
||||||
ignore_cert_check: Option<bool>,
|
ignore_cert_check: Option<bool>,
|
||||||
ssl_cert_file: Option<String>,
|
ssl_cert_file: Option<&Path>,
|
||||||
) -> ClientTest {
|
) -> ClientTest {
|
||||||
let client = Client::new(
|
let client = Client::new(
|
||||||
base_url.clone(),
|
base_url.clone(),
|
||||||
@ -107,7 +108,7 @@ impl ClientTest {
|
|||||||
access_key,
|
access_key,
|
||||||
secret_key,
|
secret_key,
|
||||||
ignore_cert_check,
|
ignore_cert_check,
|
||||||
ssl_cert_file,
|
ssl_cert_file: ssl_cert_file.map(PathBuf::from),
|
||||||
client,
|
client,
|
||||||
test_bucket: rand_bucket_name(),
|
test_bucket: rand_bucket_name(),
|
||||||
}
|
}
|
||||||
@ -537,10 +538,11 @@ impl ClientTest {
|
|||||||
|
|
||||||
let listen_task = move || async move {
|
let listen_task = move || async move {
|
||||||
let static_provider = StaticProvider::new(&access_key, &secret_key, None);
|
let static_provider = StaticProvider::new(&access_key, &secret_key, None);
|
||||||
|
let ssl_cert_file = &ssl_cert_file;
|
||||||
let client = Client::new(
|
let client = Client::new(
|
||||||
base_url,
|
base_url,
|
||||||
Some(Box::new(static_provider)),
|
Some(Box::new(static_provider)),
|
||||||
ssl_cert_file,
|
ssl_cert_file.as_deref(),
|
||||||
ignore_cert_check,
|
ignore_cert_check,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1150,7 +1152,7 @@ async fn s3_tests() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
let value = std::env::var("SSL_CERT_FILE")?;
|
let value = std::env::var("SSL_CERT_FILE")?;
|
||||||
let mut ssl_cert_file = None;
|
let mut ssl_cert_file = None;
|
||||||
if !value.is_empty() {
|
if !value.is_empty() {
|
||||||
ssl_cert_file = Some(value);
|
ssl_cert_file = Some(Path::new(&value));
|
||||||
}
|
}
|
||||||
let ignore_cert_check = std::env::var("IGNORE_CERT_CHECK").is_ok();
|
let ignore_cert_check = std::env::var("IGNORE_CERT_CHECK").is_ok();
|
||||||
let region = std::env::var("SERVER_REGION").ok();
|
let region = std::env::var("SERVER_REGION").ok();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user