Skip to content

Commit 9af2b21

Browse files
authored
Add compile-time env var to add additional info to user agent header (#3285)
This PR adds a `AWS_SDK_RUST_BUILD_UA_METADATA` environment variable to allow additional metadata to be added to the SDK user agent header at compile time. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
1 parent 04aa4c8 commit 9af2b21

File tree

1 file changed

+56
-29
lines changed

1 file changed

+56
-29
lines changed

aws/rust-runtime/aws-http/src/user_agent.rs

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub struct AwsUserAgent {
2727
config_metadata: Vec<ConfigMetadata>,
2828
framework_metadata: Vec<FrameworkMetadata>,
2929
app_name: Option<AppName>,
30+
build_env_additional_metadata: Option<AdditionalMetadata>,
3031
}
3132

3233
impl AwsUserAgent {
@@ -49,6 +50,11 @@ impl AwsUserAgent {
4950
.get("AWS_EXECUTION_ENV")
5051
.ok()
5152
.map(|name| ExecEnvMetadata { name });
53+
54+
// Retrieve additional metadata at compile-time from the AWS_SDK_RUST_BUILD_UA_METADATA env var
55+
let build_env_additional_metadata = option_env!("AWS_SDK_RUST_BUILD_UA_METADATA")
56+
.and_then(|value| AdditionalMetadata::new(value).ok());
57+
5258
AwsUserAgent {
5359
sdk_metadata,
5460
api_metadata,
@@ -63,6 +69,7 @@ impl AwsUserAgent {
6369
config_metadata: Default::default(),
6470
framework_metadata: Default::default(),
6571
app_name: Default::default(),
72+
build_env_additional_metadata,
6673
}
6774
}
6875

@@ -93,6 +100,7 @@ impl AwsUserAgent {
93100
config_metadata: Vec::new(),
94101
framework_metadata: Vec::new(),
95102
app_name: None,
103+
build_env_additional_metadata: None,
96104
}
97105
}
98106

@@ -188,6 +196,9 @@ impl AwsUserAgent {
188196
if let Some(app_name) = &self.app_name {
189197
write!(ua_value, "app/{}", app_name).unwrap();
190198
}
199+
if let Some(additional_metadata) = &self.build_env_additional_metadata {
200+
write!(ua_value, "{}", additional_metadata).unwrap();
201+
}
191202
if ua_value.ends_with(' ') {
192203
ua_value.truncate(ua_value.len() - 1);
193204
}
@@ -662,39 +673,55 @@ mod test {
662673
"aws-sdk-rust/0.1 os/macos/1.15 lang/rust/1.50.0"
663674
);
664675
}
676+
677+
#[test]
678+
fn generate_a_valid_ua_with_build_env_additional_metadata() {
679+
let mut ua = AwsUserAgent::for_tests();
680+
ua.build_env_additional_metadata = Some(AdditionalMetadata::new("asdf").unwrap());
681+
assert_eq!(
682+
ua.aws_ua_header(),
683+
"aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0 md/asdf"
684+
);
685+
assert_eq!(
686+
ua.ua_header(),
687+
"aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0"
688+
);
689+
}
665690
}
666691

667692
/*
668693
Appendix: User Agent ABNF
669-
sdk-ua-header = "x-amz-user-agent:" OWS ua-string OWS
670-
ua-pair = ua-name ["/" ua-value]
671-
ua-name = token
672-
ua-value = token
673-
version = token
674-
name = token
675-
service-id = token
676-
sdk-name = java / ruby / php / dotnet / python / cli / kotlin / rust / js / cpp / go / go-v2
677-
os-family = windows / linux / macos / android / ios / other
678-
config = retry-mode
679-
additional-metadata = "md/" ua-pair
680-
sdk-metadata = "aws-sdk-" sdk-name "/" version
681-
api-metadata = "api/" service-id "/" version
682-
os-metadata = "os/" os-family ["/" version]
683-
language-metadata = "lang/" language "/" version *(RWS additional-metadata)
684-
env-metadata = "exec-env/" name
685-
feat-metadata = "ft/" name ["/" version] *(RWS additional-metadata)
686-
config-metadata = "cfg/" config ["/" value]
687-
framework-metadata = "lib/" name ["/" version] *(RWS additional-metadata)
688-
appId = "app/" name
689-
ua-string = sdk-metadata RWS
690-
[api-metadata RWS]
691-
os-metadata RWS
692-
language-metadata RWS
693-
[env-metadata RWS]
694-
*(feat-metadata RWS)
695-
*(config-metadata RWS)
696-
*(framework-metadata RWS)
697-
[appId]
694+
sdk-ua-header = "x-amz-user-agent:" OWS ua-string OWS
695+
ua-pair = ua-name ["/" ua-value]
696+
ua-name = token
697+
ua-value = token
698+
version = token
699+
name = token
700+
service-id = token
701+
sdk-name = java / ruby / php / dotnet / python / cli / kotlin / rust / js / cpp / go / go-v2
702+
os-family = windows / linux / macos / android / ios / other
703+
config = retry-mode
704+
additional-metadata = "md/" ua-pair
705+
sdk-metadata = "aws-sdk-" sdk-name "/" version
706+
api-metadata = "api/" service-id "/" version
707+
os-metadata = "os/" os-family ["/" version]
708+
language-metadata = "lang/" language "/" version *(RWS additional-metadata)
709+
env-metadata = "exec-env/" name
710+
feat-metadata = "ft/" name ["/" version] *(RWS additional-metadata)
711+
config-metadata = "cfg/" config ["/" value]
712+
framework-metadata = "lib/" name ["/" version] *(RWS additional-metadata)
713+
app-id = "app/" name
714+
build-env-additional-metadata = "md/" value
715+
ua-string = sdk-metadata RWS
716+
[api-metadata RWS]
717+
os-metadata RWS
718+
language-metadata RWS
719+
[env-metadata RWS]
720+
*(feat-metadata RWS)
721+
*(config-metadata RWS)
722+
*(framework-metadata RWS)
723+
[app-id]
724+
[build-env-additional-metadata]
698725
699726
# New metadata field might be added in the future and they must follow this format
700727
prefix = token

0 commit comments

Comments
 (0)