Skip to content

Commit 96c6451

Browse files
committed
fix: ensure Bucket::exists() honors dangerous SSL config (PR #415)
- Renamed list_buckets_ to _list_buckets for consistency - Fixed error variant configuration for InvalidHeaderName - Added test coverage for dangerous SSL config with exists() method
1 parent 57e89f6 commit 96c6451

File tree

2 files changed

+89
-6
lines changed

2 files changed

+89
-6
lines changed

s3/src/bucket.rs

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,15 +438,13 @@ impl Bucket {
438438
credentials: Credentials,
439439
) -> Result<crate::bucket_ops::ListBucketsResponse, S3Error> {
440440
let dummy_bucket = Bucket::new("", region, credentials)?.with_path_style();
441-
dummy_bucket.list_buckets_().await
441+
dummy_bucket._list_buckets().await
442442
}
443443

444444
/// Internal helper method that performs the actual bucket listing operation.
445445
/// Used by the public `list_buckets` method to retrieve the list of buckets for the configured client.
446446
#[maybe_async::maybe_async]
447-
async fn list_buckets_(
448-
&self
449-
) -> Result<crate::bucket_ops::ListBucketsResponse, S3Error> {
447+
async fn _list_buckets(&self) -> Result<crate::bucket_ops::ListBucketsResponse, S3Error> {
450448
let request = RequestImpl::new(self, "", Command::ListBuckets).await?;
451449
let response = request.response_data(false).await?;
452450

@@ -491,7 +489,7 @@ impl Bucket {
491489
let mut dummy_bucket = self.clone();
492490
dummy_bucket.name = "".into();
493491

494-
let response = dummy_bucket.list_buckets_().await?;
492+
let response = dummy_bucket._list_buckets().await?;
495493

496494
Ok(response
497495
.bucket_names()
@@ -3877,4 +3875,89 @@ mod test {
38773875
.unwrap();
38783876
assert_eq!(response.status_code(), 204);
38793877
}
3878+
3879+
#[ignore]
3880+
#[cfg(any(feature = "tokio-native-tls", feature = "tokio-rustls-tls"))]
3881+
#[maybe_async::test(
3882+
feature = "sync",
3883+
async(all(not(feature = "sync"), feature = "with-tokio"), tokio::test),
3884+
async(
3885+
all(not(feature = "sync"), feature = "with-async-std"),
3886+
async_std::test
3887+
)
3888+
)]
3889+
async fn test_bucket_exists_with_dangerous_config() {
3890+
init();
3891+
3892+
// This test verifies that Bucket::exists() honors the dangerous SSL config
3893+
// which allows connections with invalid SSL certificates
3894+
3895+
// Create a bucket with dangerous config enabled
3896+
// Note: This test requires a test environment with self-signed or invalid certs
3897+
// For CI, we'll test with a regular bucket but verify the config is preserved
3898+
3899+
let credentials = test_aws_credentials();
3900+
let region = "eu-central-1".parse().unwrap();
3901+
let bucket_name = "rust-s3-test";
3902+
3903+
// Create bucket with dangerous config
3904+
let bucket = Bucket::new(bucket_name, region, credentials)
3905+
.unwrap()
3906+
.with_path_style();
3907+
3908+
// Set dangerous config (allow invalid certs, allow invalid hostnames)
3909+
let bucket = bucket.set_dangereous_config(true, true).unwrap();
3910+
3911+
// Test that exists() works with the dangerous config
3912+
// This should not panic or fail due to SSL certificate issues
3913+
let exists_result = bucket.exists().await;
3914+
3915+
// The bucket should exist (assuming test bucket is set up)
3916+
assert!(
3917+
exists_result.is_ok(),
3918+
"Bucket::exists() failed with dangerous config"
3919+
);
3920+
let exists = exists_result.unwrap();
3921+
assert!(exists, "Test bucket should exist");
3922+
3923+
// Verify that the dangerous config is preserved in the cloned bucket
3924+
// by checking if we can perform other operations
3925+
let list_result = bucket.list("".to_string(), Some("/".to_string())).await;
3926+
assert!(
3927+
list_result.is_ok(),
3928+
"List operation should work with dangerous config"
3929+
);
3930+
}
3931+
3932+
#[ignore]
3933+
#[maybe_async::test(
3934+
feature = "sync",
3935+
async(all(not(feature = "sync"), feature = "with-tokio"), tokio::test),
3936+
async(
3937+
all(not(feature = "sync"), feature = "with-async-std"),
3938+
async_std::test
3939+
)
3940+
)]
3941+
async fn test_bucket_exists_without_dangerous_config() {
3942+
init();
3943+
3944+
// This test verifies normal behavior without dangerous config
3945+
let credentials = test_aws_credentials();
3946+
let region = "eu-central-1".parse().unwrap();
3947+
let bucket_name = "rust-s3-test";
3948+
3949+
// Create bucket without dangerous config
3950+
let bucket = Bucket::new(bucket_name, region, credentials)
3951+
.unwrap()
3952+
.with_path_style();
3953+
3954+
// Test that exists() works normally
3955+
let exists_result = bucket.exists().await;
3956+
assert!(
3957+
exists_result.is_ok(),
3958+
"Bucket::exists() should work without dangerous config"
3959+
);
3960+
let exists = exists_result.unwrap();
3961+
assert!(exists, "Test bucket should exist");
3962+
}
38803963
}

s3/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub enum S3Error {
3939
SerdeXml(#[from] quick_xml::de::DeError),
4040
#[error("invalid header value: {0}")]
4141
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
42-
#[cfg(feature = "with-async-std")]
42+
#[cfg(any(feature = "with-async-std", feature = "with-tokio"))]
4343
#[error("invalid header name: {0}")]
4444
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
4545
#[cfg(feature = "with-async-std")]

0 commit comments

Comments
 (0)