mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 23:36:52 +08:00
Add FromStr instance to BaseURL (#51)
This commit is contained in:
parent
e5f6b16051
commit
4958c01f4c
57
README.md
57
README.md
@ -5,64 +5,9 @@ MinIO Rust SDK is Simple Storage Service (aka S3) client to perform bucket and o
|
|||||||
For a complete list of APIs and examples, please take a look at the [MinIO Rust Client API Reference](https://minio-rs.min.io/)
|
For a complete list of APIs and examples, please take a look at the [MinIO Rust Client API Reference](https://minio-rs.min.io/)
|
||||||
|
|
||||||
## Example:: file-uploader.rs
|
## Example:: file-uploader.rs
|
||||||
```rust
|
|
||||||
use minio::s3::args::{BucketExistsArgs, MakeBucketArgs, UploadObjectArgs};
|
|
||||||
use minio::s3::client::Client;
|
|
||||||
use minio::s3::creds::StaticProvider;
|
|
||||||
use minio::s3::http::BaseUrl;
|
|
||||||
|
|
||||||
#[tokio::main]
|
[Upload a file to MinIO](examples/file-uploader.rs)
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
||||||
let base_url = BaseUrl::from_string("https://play.min.io".to_string()).unwrap();
|
|
||||||
|
|
||||||
let static_provider = StaticProvider::new(
|
|
||||||
"Q3AM3UQ867SPQQA43P2F",
|
|
||||||
"zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
let client = Client::new(
|
|
||||||
base_url.clone(),
|
|
||||||
Some(Box::new(static_provider)),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let bucket_name = "asiatrip";
|
|
||||||
|
|
||||||
// Check 'asiatrip' bucket exist or not.
|
|
||||||
let exists = client
|
|
||||||
.bucket_exists(&BucketExistsArgs::new(&bucket_name).unwrap())
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Make 'asiatrip' bucket if not exist.
|
|
||||||
if !exists {
|
|
||||||
client
|
|
||||||
.make_bucket(&MakeBucketArgs::new(&bucket_name).unwrap())
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload '/home/user/Photos/asiaphotos.zip' as object name
|
|
||||||
// 'asiaphotos-2015.zip' to bucket 'asiatrip'.
|
|
||||||
client
|
|
||||||
.upload_object(
|
|
||||||
&mut UploadObjectArgs::new(
|
|
||||||
&bucket_name,
|
|
||||||
"asiaphotos-2015.zip",
|
|
||||||
"/home/user/Photos/asiaphotos.zip",
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
println!("'/home/user/Photos/asiaphotos.zip' is successfully uploaded as object 'asiaphotos-2015.zip' to bucket 'asiatrip'.");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This SDK is distributed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0), see [LICENSE](https://github.com/minio/minio-rs/blob/master/LICENSE) for more information.
|
This SDK is distributed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0), see [LICENSE](https://github.com/minio/minio-rs/blob/master/LICENSE) for more information.
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use minio::s3::http::BaseUrl;
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let base_url = BaseUrl::from_string("https://play.min.io".to_string()).unwrap();
|
let base_url = "https://play.min.io".parse::<BaseUrl>()?;
|
||||||
|
|
||||||
let static_provider = StaticProvider::new(
|
let static_provider = StaticProvider::new(
|
||||||
"Q3AM3UQ867SPQQA43P2F",
|
"Q3AM3UQ867SPQQA43P2F",
|
||||||
|
|||||||
@ -224,7 +224,7 @@ impl Client {
|
|||||||
/// use minio::s3::client::Client;
|
/// use minio::s3::client::Client;
|
||||||
/// use minio::s3::creds::StaticProvider;
|
/// use minio::s3::creds::StaticProvider;
|
||||||
/// use minio::s3::http::BaseUrl;
|
/// use minio::s3::http::BaseUrl;
|
||||||
/// let mut base_url = BaseUrl::from_string("play.min.io".to_string()).unwrap();
|
/// let mut base_url: BaseUrl = "play.min.io".parse().unwrap();
|
||||||
/// let static_provider = StaticProvider::new(
|
/// let static_provider = StaticProvider::new(
|
||||||
/// "Q3AM3UQ867SPQQA43P2F",
|
/// "Q3AM3UQ867SPQQA43P2F",
|
||||||
/// "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
|
/// "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
|
||||||
|
|||||||
194
src/s3/http.rs
194
src/s3/http.rs
@ -24,6 +24,7 @@ use hyper::Uri;
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
const AWS_S3_PREFIX: &str = r"^(((bucket\.|accesspoint\.)vpce(-[a-z_\d]+)+\.s3\.)|([a-z_\d-]{1,63}\.)s3-control(-[a-z_\d]+)*\.|(s3(-[a-z_\d]+)*\.))";
|
const AWS_S3_PREFIX: &str = r"^(((bucket\.|accesspoint\.)vpce(-[a-z_\d]+)+\.s3\.)|([a-z_\d-]{1,63}\.)s3-control(-[a-z_\d]+)*\.|(s3(-[a-z_\d]+)*\.))";
|
||||||
|
|
||||||
@ -217,6 +218,107 @@ pub struct BaseUrl {
|
|||||||
pub virtual_style: bool,
|
pub virtual_style: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for BaseUrl {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
/// Convert a string to a BaseUrl.
|
||||||
|
///
|
||||||
|
/// Enables use of [`str`]'s [`parse`] method to create a [`BaseUrl`].
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use minio::s3::http::BaseUrl;
|
||||||
|
/// use std::str::FromStr;
|
||||||
|
///
|
||||||
|
/// // Get base URL from host name
|
||||||
|
/// let base_url = "play.min.io".parse::<BaseUrl>().unwrap();
|
||||||
|
/// let base_url = BaseUrl::from_str("play.min.io").unwrap();
|
||||||
|
/// // Get base URL from host:port
|
||||||
|
/// let base_url: BaseUrl = "play.minio.io:9000".parse().unwrap();
|
||||||
|
/// // Get base URL from IPv4 address
|
||||||
|
/// let base_url: BaseUrl = "http://192.168.124.63:9000".parse().unwrap();
|
||||||
|
/// // Get base URL from IPv6 address
|
||||||
|
/// let base_url: BaseUrl = "[0:0:0:0:0:ffff:c0a8:7c3f]:9000".parse().unwrap();
|
||||||
|
/// ```
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let url = s.parse::<Uri>()?;
|
||||||
|
|
||||||
|
let https = match url.scheme() {
|
||||||
|
None => true,
|
||||||
|
Some(scheme) => match scheme.as_str() {
|
||||||
|
"http" => false,
|
||||||
|
"https" => true,
|
||||||
|
_ => {
|
||||||
|
return Err(Error::InvalidBaseUrl(String::from(
|
||||||
|
"scheme must be http or https",
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut host = match url.host() {
|
||||||
|
Some(h) => h,
|
||||||
|
_ => {
|
||||||
|
return Err(Error::InvalidBaseUrl(String::from(
|
||||||
|
"valid host must be provided",
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ipv6host = "[".to_string() + host + "]";
|
||||||
|
if host.parse::<std::net::Ipv6Addr>().is_ok() {
|
||||||
|
host = &ipv6host;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut port = match url.port() {
|
||||||
|
Some(p) => p.as_u16(),
|
||||||
|
_ => 0u16,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (https && port == 443) || (!https && port == 80) {
|
||||||
|
port = 0u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if url.path() != "/" && url.path() != "" {
|
||||||
|
return Err(Error::InvalidBaseUrl(String::from(
|
||||||
|
"path must be empty for base URL",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if url.query().is_some() {
|
||||||
|
return Err(Error::InvalidBaseUrl(String::from(
|
||||||
|
"query must be none for base URL",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut region = String::new();
|
||||||
|
let mut aws_s3_prefix = String::new();
|
||||||
|
let mut aws_domain_suffix = String::new();
|
||||||
|
let mut dualstack: bool = false;
|
||||||
|
get_aws_info(
|
||||||
|
&host.to_string(),
|
||||||
|
https,
|
||||||
|
&mut region,
|
||||||
|
&mut aws_s3_prefix,
|
||||||
|
&mut aws_domain_suffix,
|
||||||
|
&mut dualstack,
|
||||||
|
)?;
|
||||||
|
let virtual_style = !aws_domain_suffix.is_empty() || host.ends_with("aliyuncs.com");
|
||||||
|
|
||||||
|
Ok(BaseUrl {
|
||||||
|
https,
|
||||||
|
host: host.to_string(),
|
||||||
|
port,
|
||||||
|
region,
|
||||||
|
aws_s3_prefix,
|
||||||
|
aws_domain_suffix,
|
||||||
|
dualstack,
|
||||||
|
virtual_style,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl BaseUrl {
|
impl BaseUrl {
|
||||||
/// Checks base URL is AWS host
|
/// Checks base URL is AWS host
|
||||||
pub fn is_aws_host(&self) -> bool {
|
pub fn is_aws_host(&self) -> bool {
|
||||||
@ -363,96 +465,4 @@ impl BaseUrl {
|
|||||||
|
|
||||||
Ok(url)
|
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>()?;
|
|
||||||
|
|
||||||
let https = match url.scheme() {
|
|
||||||
None => true,
|
|
||||||
Some(scheme) => match scheme.as_str() {
|
|
||||||
"http" => false,
|
|
||||||
"https" => true,
|
|
||||||
_ => {
|
|
||||||
return Err(Error::InvalidBaseUrl(String::from(
|
|
||||||
"scheme must be http or https",
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut host = match url.host() {
|
|
||||||
Some(h) => h,
|
|
||||||
_ => {
|
|
||||||
return Err(Error::InvalidBaseUrl(String::from(
|
|
||||||
"valid host must be provided",
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let ipv6host = "[".to_string() + host + "]";
|
|
||||||
if host.parse::<std::net::Ipv6Addr>().is_ok() {
|
|
||||||
host = &ipv6host;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut port = match url.port() {
|
|
||||||
Some(p) => p.as_u16(),
|
|
||||||
_ => 0u16,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (https && port == 443) || (!https && port == 80) {
|
|
||||||
port = 0u16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if url.path() != "/" && url.path() != "" {
|
|
||||||
return Err(Error::InvalidBaseUrl(String::from(
|
|
||||||
"path must be empty for base URL",
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if url.query().is_some() {
|
|
||||||
return Err(Error::InvalidBaseUrl(String::from(
|
|
||||||
"query must be none for base URL",
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut region = String::new();
|
|
||||||
let mut aws_s3_prefix = String::new();
|
|
||||||
let mut aws_domain_suffix = String::new();
|
|
||||||
let mut dualstack: bool = false;
|
|
||||||
get_aws_info(
|
|
||||||
&host.to_string(),
|
|
||||||
https,
|
|
||||||
&mut region,
|
|
||||||
&mut aws_s3_prefix,
|
|
||||||
&mut aws_domain_suffix,
|
|
||||||
&mut dualstack,
|
|
||||||
)?;
|
|
||||||
let virtual_style = !aws_domain_suffix.is_empty() || host.ends_with("aliyuncs.com");
|
|
||||||
|
|
||||||
Ok(BaseUrl {
|
|
||||||
https,
|
|
||||||
host: host.to_string(),
|
|
||||||
port,
|
|
||||||
region,
|
|
||||||
aws_s3_prefix,
|
|
||||||
aws_domain_suffix,
|
|
||||||
dualstack,
|
|
||||||
virtual_style,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1155,7 +1155,7 @@ async fn s3_tests() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
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();
|
||||||
|
|
||||||
let mut base_url = BaseUrl::from_string(host).unwrap();
|
let mut base_url: BaseUrl = host.parse().unwrap();
|
||||||
base_url.https = secure;
|
base_url.https = secure;
|
||||||
if let Some(v) = region {
|
if let Some(v) = region {
|
||||||
base_url.region = v;
|
base_url.region = v;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user