Skip to content

Commit 27b4d14

Browse files
Feature: Request Compression for operations modeled with the @requestCompression trait (#3647)
2 parents 68933b7 + f730c9a commit 27b4d14

File tree

37 files changed

+2131
-34
lines changed

37 files changed

+2131
-34
lines changed

CHANGELOG.next.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,23 @@ message = "Update MSRV to `1.76.0`"
6565
references = ["smithy-rs#3653"]
6666
meta = { "breaking" = true, "tada" = true, "bug" = false, "target" = "all" }
6767
author = "landonxjames"
68+
69+
[[smithy-rs]]
70+
message = """
71+
Compression is now supported for operations modeled with the `@requestCompression` trait.
72+
73+
[**For more details, see the long-form changelog discussion**](https://github.com/smithy-lang/smithy-rs/discussions/3646).
74+
"""
75+
references = ["smithy-rs#2891"]
76+
meta = { "breaking" = false, "bug" = false, "tada" = true, "target" = "client" }
77+
author = "Velfi"
78+
79+
[[aws-sdk-rust]]
80+
message = """
81+
Compression is now supported for operations modeled with the `@requestCompression` trait.
82+
83+
[**For more details, see the long-form changelog discussion**](https://github.com/smithy-lang/smithy-rs/discussions/3646).
84+
"""
85+
references = ["smithy-rs#2891"]
86+
meta = { "breaking" = false, "bug" = false, "tada" = true }
87+
author = "Velfi"

aws/rust-runtime/aws-config/Cargo.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aws-config"
3-
version = "1.4.1"
3+
version = "1.5.0"
44
authors = [
55
"AWS Rust SDK Team <aws-sdk-rust@amazon.com>",
66
"Russell Cohen <rcoh@amazon.com>",
@@ -14,12 +14,11 @@ repository = "https://github.com/smithy-lang/smithy-rs"
1414
[features]
1515
behavior-version-latest = []
1616
client-hyper = ["aws-smithy-runtime/connector-hyper-0-14-x"]
17-
rustls = ["aws-smithy-runtime/tls-rustls", "client-hyper"]
18-
rt-tokio = ["aws-smithy-async/rt-tokio", "aws-smithy-runtime/rt-tokio", "tokio/rt"]
19-
sso = ["dep:aws-sdk-sso", "dep:aws-sdk-ssooidc", "dep:ring", "dep:hex", "dep:zeroize", "aws-smithy-runtime-api/http-auth"]
2017
credentials-process = ["tokio/process"]
21-
2218
default = ["client-hyper", "rustls", "rt-tokio", "credentials-process", "sso"]
19+
rt-tokio = ["aws-smithy-async/rt-tokio", "aws-smithy-runtime/rt-tokio", "tokio/rt"]
20+
rustls = ["aws-smithy-runtime/tls-rustls", "client-hyper"]
21+
sso = ["dep:aws-sdk-sso", "dep:aws-sdk-ssooidc", "dep:ring", "dep:hex", "dep:zeroize", "aws-smithy-runtime-api/http-auth"]
2322

2423
# deprecated: this feature does nothing
2524
allow-compilation = []

aws/rust-runtime/aws-config/src/default_provider.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,9 @@ pub mod ignore_configured_endpoint_urls;
5757

5858
/// Default endpoint URL provider chain
5959
pub mod endpoint_url;
60+
61+
/// Default "disable request compression" provider chain
62+
pub mod disable_request_compression;
63+
64+
/// Default "request minimum compression size bytes" provider chain
65+
pub mod request_min_compression_size_bytes;
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
use crate::environment::parse_bool;
7+
use crate::provider_config::ProviderConfig;
8+
use aws_runtime::env_config::EnvConfigValue;
9+
use aws_smithy_types::error::display::DisplayErrorContext;
10+
11+
mod env {
12+
pub(super) const DISABLE_REQUEST_COMPRESSION: &str = "AWS_DISABLE_REQUEST_COMPRESSION";
13+
}
14+
15+
mod profile_key {
16+
pub(super) const DISABLE_REQUEST_COMPRESSION: &str = "disable_request_compression";
17+
}
18+
19+
/// Load the value for "disable request compression".
20+
///
21+
/// This checks the following sources:
22+
/// 1. The environment variable `AWS_DISABLE_REQUEST_COMPRESSION=true/false`
23+
/// 2. The profile key `disable_request_compression=true/false`
24+
///
25+
/// If invalid values are found, the provider will return None and an error will be logged.
26+
pub(crate) async fn disable_request_compression_provider(
27+
provider_config: &ProviderConfig,
28+
) -> Option<bool> {
29+
let env = provider_config.env();
30+
let profiles = provider_config.profile().await;
31+
32+
EnvConfigValue::new()
33+
.env(env::DISABLE_REQUEST_COMPRESSION)
34+
.profile(profile_key::DISABLE_REQUEST_COMPRESSION)
35+
.validate(&env, profiles, parse_bool)
36+
.map_err(
37+
|err| tracing::warn!(err = %DisplayErrorContext(&err), "invalid value for `disable request compression` setting"),
38+
)
39+
.unwrap_or(None)
40+
}
41+
42+
#[cfg(test)]
43+
mod test {
44+
use super::disable_request_compression_provider;
45+
#[allow(deprecated)]
46+
use crate::profile::profile_file::{ProfileFileKind, ProfileFiles};
47+
use crate::provider_config::ProviderConfig;
48+
use aws_types::os_shim_internal::{Env, Fs};
49+
use tracing_test::traced_test;
50+
51+
#[tokio::test]
52+
#[traced_test]
53+
async fn log_error_on_invalid_value() {
54+
let conf = ProviderConfig::empty().with_env(Env::from_slice(&[(
55+
"AWS_DISABLE_REQUEST_COMPRESSION",
56+
"not-a-boolean",
57+
)]));
58+
assert_eq!(disable_request_compression_provider(&conf).await, None);
59+
assert!(logs_contain(
60+
"invalid value for `disable request compression` setting"
61+
));
62+
assert!(logs_contain("AWS_DISABLE_REQUEST_COMPRESSION"));
63+
}
64+
65+
#[tokio::test]
66+
#[traced_test]
67+
async fn environment_priority() {
68+
let conf = ProviderConfig::empty()
69+
.with_env(Env::from_slice(&[(
70+
"AWS_DISABLE_REQUEST_COMPRESSION",
71+
"TRUE",
72+
)]))
73+
.with_profile_config(
74+
Some(
75+
#[allow(deprecated)]
76+
ProfileFiles::builder()
77+
.with_file(
78+
#[allow(deprecated)]
79+
ProfileFileKind::Config,
80+
"conf",
81+
)
82+
.build(),
83+
),
84+
None,
85+
)
86+
.with_fs(Fs::from_slice(&[(
87+
"conf",
88+
"[default]\ndisable_request_compression = false",
89+
)]));
90+
assert_eq!(
91+
disable_request_compression_provider(&conf).await,
92+
Some(true)
93+
);
94+
}
95+
96+
#[tokio::test]
97+
#[traced_test]
98+
async fn profile_config_works() {
99+
let conf = ProviderConfig::empty()
100+
.with_profile_config(
101+
Some(
102+
#[allow(deprecated)]
103+
ProfileFiles::builder()
104+
.with_file(
105+
#[allow(deprecated)]
106+
ProfileFileKind::Config,
107+
"conf",
108+
)
109+
.build(),
110+
),
111+
None,
112+
)
113+
.with_fs(Fs::from_slice(&[(
114+
"conf",
115+
"[default]\ndisable_request_compression = true",
116+
)]));
117+
assert_eq!(
118+
disable_request_compression_provider(&conf).await,
119+
Some(true)
120+
);
121+
}
122+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
use crate::environment::parse_uint;
7+
use crate::provider_config::ProviderConfig;
8+
use aws_runtime::env_config::EnvConfigValue;
9+
use aws_smithy_types::error::display::DisplayErrorContext;
10+
11+
mod env {
12+
pub(super) const REQUEST_MIN_COMPRESSION_SIZE_BYTES: &str =
13+
"AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES";
14+
}
15+
16+
mod profile_key {
17+
pub(super) const REQUEST_MIN_COMPRESSION_SIZE_BYTES: &str =
18+
"request_min_compression_size_bytes";
19+
}
20+
21+
/// Load the value for "request minimum compression size bytes".
22+
///
23+
/// This checks the following sources:
24+
/// 1. The environment variable `AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES=10240`
25+
/// 2. The profile key `request_min_compression_size_bytes=10240`
26+
///
27+
/// If invalid values are found, the provider will return None and an error will be logged.
28+
pub(crate) async fn request_min_compression_size_bytes_provider(
29+
provider_config: &ProviderConfig,
30+
) -> Option<u32> {
31+
let env = provider_config.env();
32+
let profiles = provider_config.profile().await;
33+
34+
EnvConfigValue::new()
35+
.env(env::REQUEST_MIN_COMPRESSION_SIZE_BYTES)
36+
.profile(profile_key::REQUEST_MIN_COMPRESSION_SIZE_BYTES)
37+
.validate(&env, profiles, parse_uint)
38+
.map_err(
39+
|err| tracing::warn!(err = %DisplayErrorContext(&err), "invalid value for `request minimum compression size bytes` setting"),
40+
)
41+
.unwrap_or(None)
42+
}
43+
44+
#[cfg(test)]
45+
mod test {
46+
use super::request_min_compression_size_bytes_provider;
47+
#[allow(deprecated)]
48+
use crate::profile::profile_file::{ProfileFileKind, ProfileFiles};
49+
use crate::provider_config::ProviderConfig;
50+
use aws_types::os_shim_internal::{Env, Fs};
51+
use tracing_test::traced_test;
52+
53+
#[tokio::test]
54+
#[traced_test]
55+
async fn log_error_on_invalid_value() {
56+
let conf = ProviderConfig::empty().with_env(Env::from_slice(&[(
57+
"AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES",
58+
"not-a-uint",
59+
)]));
60+
assert_eq!(
61+
request_min_compression_size_bytes_provider(&conf).await,
62+
None
63+
);
64+
assert!(logs_contain(
65+
"invalid value for `request minimum compression size bytes` setting"
66+
));
67+
assert!(logs_contain("AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES"));
68+
}
69+
70+
#[tokio::test]
71+
#[traced_test]
72+
async fn environment_priority() {
73+
let conf = ProviderConfig::empty()
74+
.with_env(Env::from_slice(&[(
75+
"AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES",
76+
"99",
77+
)]))
78+
.with_profile_config(
79+
Some(
80+
#[allow(deprecated)]
81+
ProfileFiles::builder()
82+
.with_file(
83+
#[allow(deprecated)]
84+
ProfileFileKind::Config,
85+
"conf",
86+
)
87+
.build(),
88+
),
89+
None,
90+
)
91+
.with_fs(Fs::from_slice(&[(
92+
"conf",
93+
"[default]\nrequest_min_compression_size_bytes = 100",
94+
)]));
95+
assert_eq!(
96+
request_min_compression_size_bytes_provider(&conf).await,
97+
Some(99)
98+
);
99+
}
100+
101+
#[tokio::test]
102+
#[traced_test]
103+
async fn profile_config_works() {
104+
let conf = ProviderConfig::empty()
105+
.with_profile_config(
106+
Some(
107+
#[allow(deprecated)]
108+
ProfileFiles::builder()
109+
.with_file(
110+
#[allow(deprecated)]
111+
ProfileFileKind::Config,
112+
"conf",
113+
)
114+
.build(),
115+
),
116+
None,
117+
)
118+
.with_fs(Fs::from_slice(&[(
119+
"conf",
120+
"[default]\nrequest_min_compression_size_bytes = 22",
121+
)]));
122+
assert_eq!(
123+
request_min_compression_size_bytes_provider(&conf).await,
124+
Some(22)
125+
);
126+
}
127+
}

aws/rust-runtime/aws-config/src/environment/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ pub(crate) fn parse_bool(value: &str) -> Result<bool, InvalidBooleanValue> {
4141
}
4242
}
4343

44+
#[derive(Debug)]
45+
pub(crate) struct InvalidUintValue {
46+
value: String,
47+
}
48+
49+
impl fmt::Display for InvalidUintValue {
50+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51+
write!(f, "{} is not a valid u32", self.value)
52+
}
53+
}
54+
55+
impl Error for InvalidUintValue {}
56+
57+
pub(crate) fn parse_uint(value: &str) -> Result<u32, InvalidUintValue> {
58+
value.parse::<u32>().map_err(|_| InvalidUintValue {
59+
value: value.to_string(),
60+
})
61+
}
62+
4463
#[derive(Debug)]
4564
pub(crate) struct InvalidUrlValue {
4665
value: String,

0 commit comments

Comments
 (0)