Skip to content

Commit 0180ca7

Browse files
committed
Update user agent parsing and added new UA for updating sigv4 override
1 parent 03c8495 commit 0180ca7

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

src/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -632,45 +632,62 @@ void AWSAuthV4Signer::UpdateUserAgentWithCredentialFeatures(Aws::Http::HttpReque
632632
}
633633

634634
Aws::StringStream credentialFeatures;
635-
bool first = true;
636635
for (const auto& feature : features) {
637636
Aws::String featureStr;
638637
switch (feature) {
639638
case Aws::Client::UserAgentFeature::CREDENTIALS_ENV_VARS:
640639
featureStr = "g";
641640
break;
642641
case Aws::Client::UserAgentFeature::CREDENTIALS_SIGV4_SIGNER:
643-
featureStr = "MD";
642+
if (request.HasHeader(USER_AGENT)) {
643+
auto userAgentParts = Aws::Utils::StringUtils::Split(request.GetHeaderValue(USER_AGENT), ' ');
644+
645+
// Find position to insert metadata (before metrics section)
646+
auto metricsIt = std::find_if(userAgentParts.begin(), userAgentParts.end(),
647+
[](const Aws::String& part) { return part.find("m/") == 0; });
648+
649+
// Insert metadata at appropriate position
650+
userAgentParts.insert(metricsIt, "md/override_get_credentials");
651+
652+
// Reassemble with spaces
653+
Aws::String newUserAgent = userAgentParts.front();
654+
for (auto it = std::next(userAgentParts.begin()); it != userAgentParts.end(); ++it) {
655+
newUserAgent += " " + *it;
656+
}
657+
request.SetHeaderValue(USER_AGENT, newUserAgent);
658+
}
644659
break;
645660
default:
646661
break;
647662
}
663+
648664
if (!featureStr.empty()) {
649-
if (!first) {
665+
if (!credentialFeatures.str().empty()) {
650666
credentialFeatures << ",";
651667
}
652668
credentialFeatures << featureStr;
653-
first = false;
654669
}
655670
}
656671

657672
if (!credentialFeatures.str().empty()) {
658-
Aws::String existingUA = request.GetHeaderValue(USER_AGENT);
659-
size_t mPos = existingUA.find(" m/");
673+
Aws::String userAgent = request.GetHeaderValue(USER_AGENT);
674+
auto userAgentParsed = Aws::Utils::StringUtils::Split(userAgent, ' ');
675+
auto metricsSegment = std::find_if(userAgentParsed.begin(), userAgentParsed.end(),
676+
[](const Aws::String& value) { return value.find("m/") != Aws::String::npos; });
660677

661-
if (mPos != Aws::String::npos) {
662-
// "m/" section already exists, find where to insert our metrics
663-
size_t metricsStart = mPos + 3; // Position after "m/"
664-
size_t nextSectionPos = existingUA.find(" ", metricsStart);
665-
666-
// Insert our metrics with comma separator at the end of existing metrics
667-
Aws::String newUA = existingUA;
668-
newUA.insert(nextSectionPos != Aws::String::npos ? nextSectionPos : existingUA.length(),
669-
"," + credentialFeatures.str());
670-
request.SetUserAgent(newUA);
678+
if (metricsSegment != userAgentParsed.end()) {
679+
// Add new metrics to existing metrics section
680+
*metricsSegment = Aws::String{*metricsSegment + "," + credentialFeatures.str()};
671681
} else {
672-
// No existing "m/" section, add it
673-
request.SetUserAgent(existingUA + " m/" + credentialFeatures.str());
682+
// No metrics section exists, add new one
683+
userAgentParsed.push_back("m/" + credentialFeatures.str());
684+
}
685+
686+
// Reassemble all parts with spaces
687+
Aws::String newUserAgent = userAgentParsed.front();
688+
for (auto it = std::next(userAgentParsed.begin()); it != userAgentParsed.end(); ++it) {
689+
newUserAgent += " " + *it;
674690
}
691+
request.SetUserAgent(newUserAgent);
675692
}
676693
}

tests/aws-cpp-sdk-core-tests/aws/auth/CredentialTrackingTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,9 @@ TEST_F(CredentialTrackingTest, TestLegacySigV4SignerTracking)
177177
}
178178
EXPECT_EQ(1, mSectionCount);
179179

180-
// Check for legacy SigV4 signer business metric (MD) in user agent
180+
// Check for legacy SigV4 signer business metric (md/override_get_credentials) in user agent
181181
auto businessMetrics = std::find_if(userAgentParsed.begin(), userAgentParsed.end(),
182-
[](const Aws::String& value) { return value.find("m/") != Aws::String::npos && value.find("MD") != Aws::String::npos; });
182+
[](const Aws::String& value) { return value.find("md/override_get_credentials") != Aws::String::npos; });
183183

184184
EXPECT_TRUE(businessMetrics != userAgentParsed.end());
185185
}

0 commit comments

Comments
 (0)