diff --git a/rust/cubestore/Cargo.lock b/rust/cubestore/Cargo.lock index 35ab1e27d594f..786a03876540e 100644 --- a/rust/cubestore/Cargo.lock +++ b/rust/cubestore/Cargo.lock @@ -600,7 +600,7 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-creds" version = "0.38.0" -source = "git+https://github.com/cube-js/rust-s3.git?rev=c662b9c66c2929da185c46084fc5f455030ad75f#c662b9c66c2929da185c46084fc5f455030ad75f" +source = "git+https://github.com/cube-js/rust-s3.git?rev=9deb3475c7963deaa6c30de59771e61af5b15b8f#9deb3475c7963deaa6c30de59771e61af5b15b8f" dependencies = [ "attohttpc", "home", @@ -3676,7 +3676,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if 1.0.0", - "windows-targets 0.48.5", + "windows-targets 0.52.4", ] [[package]] @@ -5565,7 +5565,7 @@ dependencies = [ [[package]] name = "rust-s3" version = "0.32.3" -source = "git+https://github.com/cube-js/rust-s3.git?rev=c662b9c66c2929da185c46084fc5f455030ad75f#c662b9c66c2929da185c46084fc5f455030ad75f" +source = "git+https://github.com/cube-js/rust-s3.git?rev=9deb3475c7963deaa6c30de59771e61af5b15b8f#9deb3475c7963deaa6c30de59771e61af5b15b8f" dependencies = [ "async-trait", "aws-creds", @@ -6815,7 +6815,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 0.1.10", "rand 0.7.3", "static_assertions", ] diff --git a/rust/cubestore/cubestore/Cargo.toml b/rust/cubestore/cubestore/Cargo.toml index 335c4957488e7..6d8fc623f54eb 100644 --- a/rust/cubestore/cubestore/Cargo.toml +++ b/rust/cubestore/cubestore/Cargo.toml @@ -63,7 +63,8 @@ bigdecimal = { version = "0.2.0", features = ["serde"] } # Tracking PR with backports: https://github.com/cube-js/rust-s3/pull/1 # The fork also includes a fix for AWS_STS_REGIONAL_ENDPOINTS # See https://github.com/cube-js/rust-s3/pull/1/commits for more details -rust-s3 = { git = "https://github.com/cube-js/rust-s3.git", rev = "c662b9c66c2929da185c46084fc5f455030ad75f", default-features = false, features = ["tokio", "tokio-native-tls"] } +# rev = cubestore-0.32.3-backport tip incl. per-operation SSE header (https://github.com/cube-js/rust-s3/pull/2) +rust-s3 = { git = "https://github.com/cube-js/rust-s3.git", rev = "9deb3475c7963deaa6c30de59771e61af5b15b8f", default-features = false, features = ["tokio", "tokio-native-tls"] } deadqueue = "0.2.4" reqwest = { version = "0.12.5", features = ["json", "rustls-tls", "stream", "http2"], default-features = false } nanoid = "0.3.0" diff --git a/rust/cubestore/cubestore/src/remotefs/s3.rs b/rust/cubestore/cubestore/src/remotefs/s3.rs index 98de7ef7837ad..23c08174752d5 100644 --- a/rust/cubestore/cubestore/src/remotefs/s3.rs +++ b/rust/cubestore/cubestore/src/remotefs/s3.rs @@ -33,9 +33,11 @@ pub struct S3RemoteFs { /// STS AssumeRoleWithWebIdentity with the JWT inside it. web_identity_token_file: Option, web_identity_role_arn: Option, - /// When set, every request carries `x-amz-server-side-encryption` with this - /// value. Some AWS Organizations SCPs deny `s3:PutObject` unless the header - /// is present, even when the bucket has default encryption. + /// When set, object-storing requests (PutObject / multipart initiation) + /// carry `x-amz-server-side-encryption` with this value. Some AWS + /// Organizations SCPs deny `s3:PutObject` unless the header is present, + /// even when the bucket has default encryption. Never sent on read/list + /// operations — S3 rejects it there. server_side_encryption: Option, } @@ -142,9 +144,9 @@ fn new_bucket( server_side_encryption: &Option, ) -> Result { let mut bucket = Bucket::new(bucket_name, region, credentials)?; - if let Some(sse) = server_side_encryption { - bucket.add_header("x-amz-server-side-encryption", sse); - } + // Applied per-operation by rust-s3 (PutObject / multipart initiation only) + // — S3 rejects the header on read/list operations. + bucket.set_server_side_encryption(server_side_encryption.clone()); Ok(bucket) } @@ -588,7 +590,7 @@ mod tests { } #[test] - fn new_bucket_applies_sse_header() { + fn new_bucket_configures_per_operation_sse() { let credentials = Credentials::new(Some("key"), Some("secret"), None, None, None).unwrap(); let bucket = new_bucket( "test-bucket", @@ -597,13 +599,14 @@ mod tests { &Some("AES256".to_string()), ) .unwrap(); - assert_eq!( - bucket - .extra_headers() - .get("x-amz-server-side-encryption") - .map(|v| v.to_str().unwrap()), - Some("AES256") - ); + assert_eq!(bucket.server_side_encryption(), Some("AES256")); + // The header must NOT be bucket-wide: S3 rejects it on read/list + // operations. rust-s3 applies it per-operation (PutObject / + // InitiateMultipartUpload only). + assert!(bucket + .extra_headers() + .get("x-amz-server-side-encryption") + .is_none()); } #[test] @@ -616,6 +619,7 @@ mod tests { &None, ) .unwrap(); + assert_eq!(bucket.server_side_encryption(), None); assert!(bucket .extra_headers() .get("x-amz-server-side-encryption")