diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a67e30c..db690b4 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -23,8 +23,10 @@ jobs: - name: Run tests run: | - ./start-server.sh + ./tests/start-server.sh export SERVER_ENDPOINT=localhost:9000 export ACCESS_KEY=minioadmin export SECRET_KEY=minioadmin + export ENABLE_HTTPS=1 + export SSL_CERT_FILE=./tests/public.crt cargo test --verbose -- --nocapture diff --git a/Cargo.toml b/Cargo.toml index c2bf013..c79072c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ crc = "3.0.0" byteorder = "1.4.3" hmac = "0.12.1" hex = "0.4.3" -reqwest = { version = "0.11.11", features = ["stream"] } futures-core = "0.3.21" bytes = "1.2.0" futures-util = "0.3.21" @@ -28,3 +27,7 @@ xmltree = "0.10.3" http = "0.2.8" dashmap = "5.3.4" rand = "0.8.5" + +[dependencies.reqwest] +version = "0.11.11" +features = ["native-tls", "blocking", "rustls-tls", "stream"] diff --git a/src/s3/client.rs b/src/s3/client.rs index 598933b..30a5a80 100644 --- a/src/s3/client.rs +++ b/src/s3/client.rs @@ -30,6 +30,8 @@ use dashmap::DashMap; use hyper::http::Method; use reqwest::header::HeaderMap; use std::collections::HashMap; +use std::fs::File; +use std::io::Read; use xmltree::Element; fn url_decode( @@ -202,10 +204,10 @@ fn parse_list_objects_common_prefixes( pub struct Client<'a> { base_url: BaseUrl, provider: Option<&'a dyn Provider>, - ssl_cert_file: String, - ignore_cert_check: bool, + pub ssl_cert_file: String, + pub ignore_cert_check: bool, + pub user_agent: String, region_map: DashMap, - user_agent: String, debug: bool, } @@ -214,10 +216,10 @@ impl<'a> Client<'a> { Client { base_url: base_url, provider: provider, - ssl_cert_file: String::new(), // TODO: use specified ssl_cert_file + ssl_cert_file: String::new(), ignore_cert_check: false, + user_agent: String::new(), region_map: DashMap::new(), - user_agent: String::new(), // TODO: use specified user_agent debug: false, } } @@ -456,17 +458,15 @@ impl<'a> Client<'a> { .build_url(&method, region, query_params, bucket_name, object_name)?; self.build_headers(headers, query_params, region, &url, &method, body); - let client; - if object_name.unwrap_or_default().to_string().is_empty() && method == Method::GET { - client = reqwest::Client::builder() - .no_gzip() // needed to ensure no automatic decompression on GetObject - .danger_accept_invalid_certs(self.ignore_cert_check) - .build()?; - } else { - client = reqwest::Client::builder() - .danger_accept_invalid_certs(self.ignore_cert_check) - .build()?; - } + let mut buf = Vec::new(); + File::open(self.ssl_cert_file.to_string())?.read_to_end(&mut buf)?; + let cert = reqwest::Certificate::from_pem(&buf)?; + + let client = reqwest::Client::builder() + .no_gzip() + .add_root_certificate(cert) + .danger_accept_invalid_certs(self.ignore_cert_check) + .build()?; let mut req = client.request(method.clone(), url.to_string()); diff --git a/start-server.sh b/start-server.sh deleted file mode 100755 index a108d55..0000000 --- a/start-server.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -wget --quiet https://dl.min.io/server/minio/release/linux-amd64/minio && \ - chmod +x minio && \ - mkdir -p ~/.minio/certs && \ - cp ./tests/public.crt ./tests/private.key ~/.minio/certs/ && \ - sudo cp ./tests/public.crt /usr/local/share/ca-certificates/ && \ - sudo update-ca-certificates - -MINIO_CI_CD=true ./minio server /tmp/test-xl/{1...4}/ & -sleep 10 diff --git a/tests/private.key b/tests/private.key new file mode 100644 index 0000000..ffe1b17 --- /dev/null +++ b/tests/private.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgs92/22T2vIGJCIHR +6KL78f37XJXTJCpIlyVozmEo9iahRANCAATWlbZ1mHD8YeMKa2kM7E7hptGcl+6h +mmq4ugD3bbJCh22wLTxHobqadlCnq976H91Z2yM2cXmZLByz8Epgg/9w +-----END PRIVATE KEY----- diff --git a/tests/public.crt b/tests/public.crt new file mode 100644 index 0000000..9d49164 --- /dev/null +++ b/tests/public.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5zCCAY2gAwIBAgIQGDcDELutI2jM7kTgfeESPzAKBggqhkjOPQQDAjA7MRww +GgYDVQQKExNDZXJ0Z2VuIERldmVsb3BtZW50MRswGQYDVQQLDBJoYXJzaGFAbmFu +byAobmFubykwHhcNMjIwODIzMDgxMDQwWhcNMjMwODIzMDgxMDQwWjA7MRwwGgYD +VQQKExNDZXJ0Z2VuIERldmVsb3BtZW50MRswGQYDVQQLDBJoYXJzaGFAbmFubyAo +bmFubykwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWlbZ1mHD8YeMKa2kM7E7h +ptGcl+6hmmq4ugD3bbJCh22wLTxHobqadlCnq976H91Z2yM2cXmZLByz8Epgg/9w +o3MwcTAOBgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUE9fw8e+S5H5lOzreN8FFcBP3r2gwGgYDVR0R +BBMwEYIJbG9jYWxob3N0hwR/AAABMAoGCCqGSM49BAMCA0gAMEUCIBHcFxnYVTIu +KI9AcywtvtFIINknZ0dSVrR0nzUMSOskAiEAqbj+BqVogZzO8GC+1l71K/R+j4yP +NOwfeX1Aq+3fDQ0= +-----END CERTIFICATE----- diff --git a/tests/start-server.sh b/tests/start-server.sh new file mode 100755 index 0000000..e9c7b1a --- /dev/null +++ b/tests/start-server.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -x +set -e + +wget --quiet https://dl.min.io/server/minio/release/linux-amd64/minio && \ + chmod +x minio && \ + mkdir -p /tmp/certs && \ + cp ./tests/public.crt ./tests/private.key /tmp/certs/ && \ + +MINIO_CI_CD=true ./minio server /tmp/test-xl/{1...4}/ --certs-dir /tmp/certs/ & +sleep 10 diff --git a/tests/tests.rs b/tests/tests.rs index 9265015..f5b931b 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -401,6 +401,8 @@ async fn s3_tests() -> Result<(), Box> { let access_key = std::env::var("ACCESS_KEY")?; let secret_key = std::env::var("SECRET_KEY")?; let secure = std::env::var("ENABLE_HTTPS").is_ok(); + let ssl_cert_file = std::env::var("SSL_CERT_FILE")?; + let ignore_cert_check = std::env::var("IGNORE_CERT_CHECK").is_ok(); let region = std::env::var("SERVER_REGION").ok(); let mut burl = BaseUrl::from_string(host).unwrap(); @@ -410,7 +412,9 @@ async fn s3_tests() -> Result<(), Box> { } let provider = StaticProvider::new(&access_key, &secret_key, None); - let client = Client::new(burl.clone(), Some(&provider)); + let mut client = Client::new(burl.clone(), Some(&provider)); + client.ignore_cert_check = ignore_cert_check; + client.ssl_cert_file = ssl_cert_file; let test_bucket = rand_bucket_name(); client