From 514cddb4f5ccad6fc99577b633f08e26a1130753 Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Mon, 5 Aug 2024 19:23:50 +0100 Subject: [PATCH 1/4] Refactor User-Agent construction in Marshaller.cs Updated `SetUserAgentHeader` to improve User-Agent string construction: - Initialize `StringBuilder` with a capacity of 256. - Append `UserAgent` after replacing invalid characters. - Append `ClientAppId` after replacing invalid characters. - Use `ToUserAgentHeaderString` for retry mode conversion. - Append `IsAsync` and initialization config directly. - Append `UserAgentAddition` after replacing invalid characters. - Removed redundant call to `ReplaceInvalidUserAgentCharacters`. - Added `ToUserAgentHeaderString` method for `RequestRetryMode`. --- .../Pipeline/Handlers/Marshaller.cs | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs b/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs index 839d09fd4173..182c0767529f 100644 --- a/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs +++ b/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs @@ -106,29 +106,28 @@ private static void SetRecursionDetectionHeader(IDictionary head private static void SetUserAgentHeader(IRequestContext requestContext) { - var sb = new StringBuilder(requestContext.ClientConfig.UserAgent); + var sb = new StringBuilder(256); + + sb.Append(InternalSDKUtils.ReplaceInvalidUserAgentCharacters(requestContext.ClientConfig.UserAgent)); var clientAppId = requestContext.ClientConfig.ClientAppId; if (!string.IsNullOrEmpty(clientAppId)) - sb.AppendFormat(" app/{0}", clientAppId); + sb.Append(" app/").Append(InternalSDKUtils.ReplaceInvalidUserAgentCharacters(clientAppId)); - var retryMode = requestContext.ClientConfig.RetryMode.ToString().ToLower(); - sb.AppendFormat(" cfg/retry-mode#{0}", retryMode); + sb.Append(" cfg/retry-mode#}").Append(ToUserAgentHeaderString(requestContext.ClientConfig.RetryMode)); - sb.AppendFormat(" md/{0}", requestContext.IsAsync ? "ClientAsync" : "ClientSync"); + sb.Append(" md/").Append(IsAsync ? "ClientAsync" : "ClientSync"); - sb.AppendFormat(" cfg/init-coll#{0}", AWSConfigs.InitializeCollections ? "1" : "0"); + sb.Append(" cfg/init-coll#").Append(InitializeCollections ? '1' : '0'); var userAgentAddition = requestContext.OriginalRequest.UserAgentAddition; if (!string.IsNullOrEmpty(userAgentAddition)) { - sb.AppendFormat(" {0}", userAgentAddition); + sb.Append(' ').Append(InternalSDKUtils.ReplaceInvalidUserAgentCharacters(userAgentAddition)); } var userAgent = sb.ToString(); - userAgent = InternalSDKUtils.ReplaceInvalidUserAgentCharacters(userAgent); - if (requestContext.ClientConfig.UseAlternateUserAgentHeader) { requestContext.Request.Headers[HeaderKeys.XAmzUserAgentHeader] = userAgent; @@ -138,5 +137,13 @@ private static void SetUserAgentHeader(IRequestContext requestContext) requestContext.Request.Headers[HeaderKeys.UserAgentHeader] = userAgent; } } + + private static string ToUserAgentHeaderString(RequestRetryMode requestRetryMode) + { + if (requestRetryMode == RequestRetryMode.Adaptive) + return "adaptive"; + else + return "standard"; + } } } From a61d3cfe53eecb6bc2e2d3f522a0ae7d98cc5d3b Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Tue, 6 Aug 2024 17:54:05 +0100 Subject: [PATCH 2/4] Improve user agent string construction in Marshaller.cs Added a `using System.Diagnostics;` directive. Introduced a `retryMode` variable and added a `Debug.Assert` to ensure its correctness. Updated user agent string logic to use `retryMode` and `requestContext.IsAsync`. Changed initialization collections flag to `AWSConfigs.InitializeCollections`. --- .../Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs b/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs index 182c0767529f..6ead057028a8 100644 --- a/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs +++ b/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs @@ -15,6 +15,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.Text; using Amazon.Runtime.Telemetry; @@ -114,11 +115,13 @@ private static void SetUserAgentHeader(IRequestContext requestContext) if (!string.IsNullOrEmpty(clientAppId)) sb.Append(" app/").Append(InternalSDKUtils.ReplaceInvalidUserAgentCharacters(clientAppId)); - sb.Append(" cfg/retry-mode#}").Append(ToUserAgentHeaderString(requestContext.ClientConfig.RetryMode)); + var retryMode = ToUserAgentHeaderString(requestContext.ClientConfig.RetryMode); + Debug.Assert(retryMode != requestContext.ClientConfig.RetryMode.ToString().ToLower(), "Invalid RetryMode string."); + sb.Append(" cfg/retry-mode#}").Append(retryMode); - sb.Append(" md/").Append(IsAsync ? "ClientAsync" : "ClientSync"); + sb.Append(" md/").Append(requestContext.IsAsync ? "ClientAsync" : "ClientSync"); - sb.Append(" cfg/init-coll#").Append(InitializeCollections ? '1' : '0'); + sb.Append(" cfg/init-coll#").Append(AWSConfigs.InitializeCollections ? '1' : '0'); var userAgentAddition = requestContext.OriginalRequest.UserAgentAddition; if (!string.IsNullOrEmpty(userAgentAddition)) From 951bcad601ad21368ef2596d352fffbfeb4015fe Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Wed, 7 Aug 2024 19:41:29 +0100 Subject: [PATCH 3/4] Refactor ToUserAgentHeaderString and add new test Refactored the ToUserAgentHeaderString method in Marshaller.cs to use a switch statement instead of if-else statements, including a default case for converting requestRetryMode to lowercase. Removed Debug.Assert for retryMode and directly appended it to the StringBuilder object. Added LookForRequestRetryModeChanges test in StaticCheckTests.cs to verify the integrity of the RequestRetryMode enum. --- .../Pipeline/Handlers/Marshaller.cs | 17 ++++++++++------- .../UnitTests/Custom/StaticCheckTests.cs | 10 ++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs b/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs index 6ead057028a8..3b7fc0315665 100644 --- a/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs +++ b/sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs @@ -115,9 +115,7 @@ private static void SetUserAgentHeader(IRequestContext requestContext) if (!string.IsNullOrEmpty(clientAppId)) sb.Append(" app/").Append(InternalSDKUtils.ReplaceInvalidUserAgentCharacters(clientAppId)); - var retryMode = ToUserAgentHeaderString(requestContext.ClientConfig.RetryMode); - Debug.Assert(retryMode != requestContext.ClientConfig.RetryMode.ToString().ToLower(), "Invalid RetryMode string."); - sb.Append(" cfg/retry-mode#}").Append(retryMode); + sb.Append(" cfg/retry-mode#}").Append(ToUserAgentHeaderString(requestContext.ClientConfig.RetryMode)); sb.Append(" md/").Append(requestContext.IsAsync ? "ClientAsync" : "ClientSync"); @@ -143,10 +141,15 @@ private static void SetUserAgentHeader(IRequestContext requestContext) private static string ToUserAgentHeaderString(RequestRetryMode requestRetryMode) { - if (requestRetryMode == RequestRetryMode.Adaptive) - return "adaptive"; - else - return "standard"; + switch (requestRetryMode) + { + case RequestRetryMode.Standard: + return "standard"; + case RequestRetryMode.Adaptive: + return "adaptive"; + default: + return requestRetryMode.ToString().ToLowerInvariant(); + } } } } diff --git a/sdk/test/Services/SecurityToken/UnitTests/Custom/StaticCheckTests.cs b/sdk/test/Services/SecurityToken/UnitTests/Custom/StaticCheckTests.cs index 1f516a944cfd..1b576b6ae127 100644 --- a/sdk/test/Services/SecurityToken/UnitTests/Custom/StaticCheckTests.cs +++ b/sdk/test/Services/SecurityToken/UnitTests/Custom/StaticCheckTests.cs @@ -83,5 +83,15 @@ public void EnsureCredentialProfileDetectorSetup() // the properties are used at least once. Assert.IsTrue(profileOptionsProperties.SetEquals(referencedProfileOptionsProperties)); } + + [TestMethod] + public void LookForRequestRetryModeChanges() + { + var expectedHash = "2FC699DB6A4284C5D53F3B7FA4E64165576FD1F6AE458BC737AE503F06DFBE4C"; + AssertExtensions.AssertEnumUnchanged( + typeof(RequestRetryMode), + expectedHash, + "The Amazon.Runtime.Internal.Marshaller.ToUserAgentHeaderString method implementation may need to be updated."); + } } } \ No newline at end of file From 8dc4639001bb8504313b6946f8d07390cafad059 Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Fri, 16 Aug 2024 09:51:29 -0400 Subject: [PATCH 4/4] Add devConfig and suppress NormalizeStringsToUppercase warning in ToUserAgentHeaderString --- .../aabf4e64-a7dd-4ee3-95a7-c8466c22a7e3.json | 9 +++++++++ sdk/src/Core/GlobalSuppressions.cs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 generator/.DevConfigs/aabf4e64-a7dd-4ee3-95a7-c8466c22a7e3.json diff --git a/generator/.DevConfigs/aabf4e64-a7dd-4ee3-95a7-c8466c22a7e3.json b/generator/.DevConfigs/aabf4e64-a7dd-4ee3-95a7-c8466c22a7e3.json new file mode 100644 index 000000000000..a0f861467e75 --- /dev/null +++ b/generator/.DevConfigs/aabf4e64-a7dd-4ee3-95a7-c8466c22a7e3.json @@ -0,0 +1,9 @@ +{ + "core": { + "changeLogMessages": [ + "Improve user agent string construction in Marshaller.cs" + ], + "type": "patch", + "updateMinimum": true + } +} \ No newline at end of file diff --git a/sdk/src/Core/GlobalSuppressions.cs b/sdk/src/Core/GlobalSuppressions.cs index 476b7e93d6d5..359bd1bc2926 100644 --- a/sdk/src/Core/GlobalSuppressions.cs +++ b/sdk/src/Core/GlobalSuppressions.cs @@ -191,9 +191,9 @@ [module: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Amazon.Runtime.Internal.Auth.AWS4Signer.#CanonicalizeHeaders(System.Collections.Generic.ICollection`1>)")] [module: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Amazon.Runtime.Internal.Auth.S3Signer.#BuildCanonicalizedHeaders(System.Collections.Generic.IDictionary`2)")] [module: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Amazon.Runtime.Internal.Auth.AWS4Signer.#DetermineSigningRegion(Amazon.Runtime.IClientConfig,System.String,Amazon.RegionEndpoint,Amazon.Runtime.Internal.IRequest)")] - [module: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Amazon.Runtime.Internal.Auth.AWS4Signer.#CanonicalizeHeaders(System.Collections.Generic.IDictionary`2)")] [module: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Amazon.Runtime.Internal.Auth.AWS4Signer.#CanonicalizeHeaderNames(System.Collections.Generic.IDictionary`2)")] +[module: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Amazon.Runtime.Internal.Marshaller.#ToUserAgentHeaderString(Amazon.Runtime.RequestRetryMode)")] // Types names matching namespaces [module: SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces", Scope = "type", Target = "Amazon.Auth.AccessControlPolicy.Policy")]