Skip to content

Commit 17ed221

Browse files
Populate User Agent Details
1 parent f8194c5 commit 17ed221

File tree

10 files changed

+68
-32
lines changed

10 files changed

+68
-32
lines changed

Diff for: sdk/src/Core/Amazon.Runtime/CredentialManagement/AWSCredentialsFactory.cs

+33-29
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,16 @@ private static AWSCredentials GetAWSCredentialsInternal(
199199
{
200200
if (profileType.HasValue)
201201
{
202+
AWSCredentials awsCredentials = null;
202203
switch (profileType)
203204
{
204205
case CredentialProfileType.Basic:
205-
var basicCredentials = new BasicAWSCredentials(options.AccessKey, options.SecretKey, options.AwsAccountId);
206-
basicCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE);
207-
return basicCredentials;
206+
awsCredentials = new BasicAWSCredentials(options.AccessKey, options.SecretKey, options.AwsAccountId);
207+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE);
208+
break;
208209
case CredentialProfileType.Session:
209-
return new SessionAWSCredentials(options.AccessKey, options.SecretKey, options.Token, options.AwsAccountId);
210+
awsCredentials = new SessionAWSCredentials(options.AccessKey, options.SecretKey, options.Token, options.AwsAccountId);
211+
break;
210212
case CredentialProfileType.AssumeRole:
211213
case CredentialProfileType.AssumeRoleExternal:
212214
case CredentialProfileType.AssumeRoleMFA:
@@ -252,10 +254,10 @@ private static AWSCredentials GetAWSCredentialsInternal(
252254
MfaSerialNumber = options.MfaSerial
253255
};
254256

255-
var assumeRoleCredentials = new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
256-
assumeRoleCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_SOURCE_PROFILE);
257-
return assumeRoleCredentials;
258-
257+
awsCredentials = new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
258+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_SOURCE_PROFILE);
259+
break;
260+
259261
case CredentialProfileType.AssumeRoleCredentialSource:
260262
case CredentialProfileType.AssumeRoleCredentialSourceSessionName:
261263
// get credentials specified by credentialSource
@@ -276,34 +278,30 @@ private static AWSCredentials GetAWSCredentialsInternal(
276278
roleSessionName = options.RoleSessionName ?? RoleSessionNamePrefix + AWSSDKUtils.CorrectedUtcNow.Ticks;
277279
assumeRoleOptions = new AssumeRoleAWSCredentialsOptions();
278280

279-
var assumeRoleSourceCredentials = new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
280-
assumeRoleSourceCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_NAMED_PROVIDER);
281-
return assumeRoleSourceCredentials;
282-
281+
awsCredentials = new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
282+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_NAMED_PROVIDER);
283+
break;
284+
283285
case CredentialProfileType.AssumeRoleWithWebIdentity:
284286
case CredentialProfileType.AssumeRoleWithWebIdentitySessionName:
285-
var assumeRoleWebIdentityCredentials = new AssumeRoleWithWebIdentityCredentials(options.WebIdentityTokenFile, options.RoleArn, options.RoleSessionName);
286-
assumeRoleWebIdentityCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN);
287-
return assumeRoleWebIdentityCredentials;
288-
287+
awsCredentials = new AssumeRoleWithWebIdentityCredentials(options.WebIdentityTokenFile, options.RoleArn, options.RoleSessionName);
288+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN);
289+
break;
290+
289291
case CredentialProfileType.SSO:
290-
{
291-
var ssoCredentialsOptions = new SSOAWSCredentialsOptions
292-
{
292+
var ssoCredentialsOptions = new SSOAWSCredentialsOptions
293+
{
293294
SessionName = options.SsoSession,
294295
Scopes = options.SsoRegistrationScopes?.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToList()
295296
};
296297

297298
var isLegacyFormat = string.IsNullOrEmpty(options.SsoSession);
298-
var ssoCredentials = new SSOAWSCredentials(options.SsoAccountId, options.SsoRegion, options.SsoRoleName, options.SsoStartUrl, ssoCredentialsOptions);
299-
ssoCredentials.FeatureIdSources.Add(isLegacyFormat ? UserAgentFeatureId.CREDENTIALS_PROFILE_SSO_LEGACY : UserAgentFeatureId.CREDENTIALS_PROFILE_SSO);
299+
awsCredentials = new SSOAWSCredentials(options.SsoAccountId, options.SsoRegion, options.SsoRoleName, options.SsoStartUrl, ssoCredentialsOptions);
300+
awsCredentials.FeatureIdSources.Add(isLegacyFormat ? UserAgentFeatureId.CREDENTIALS_PROFILE_SSO_LEGACY : UserAgentFeatureId.CREDENTIALS_PROFILE_SSO);
301+
break;
300302

301-
return ssoCredentials;
302-
}
303-
304303
case CredentialProfileType.SAMLRole:
305304
case CredentialProfileType.SAMLRoleUserIdentity:
306-
307305
if (UserCrypto.IsUserCryptAvailable)
308306
{
309307
var federatedOptions = new FederatedAWSCredentialsOptions()
@@ -312,17 +310,18 @@ private static AWSCredentials GetAWSCredentialsInternal(
312310
UserIdentity = options.UserIdentity,
313311
ProfileName = profileName
314312
};
315-
return new FederatedAWSCredentials(new SAMLEndpointManager().GetEndpoint(options.EndpointName),
313+
awsCredentials = new FederatedAWSCredentials(new SAMLEndpointManager().GetEndpoint(options.EndpointName),
316314
options.RoleArn, federatedOptions);
315+
break;
317316
}
318317
else
319318
{
320319
return ThrowOrReturnNull("Federated credentials are not available on this platform.", null, throwIfInvalid);
321320
}
322321
case CredentialProfileType.CredentialProcess:
323-
var processCredentials = new ProcessAWSCredentials(options.CredentialProcess, options.AwsAccountId);
324-
processCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_PROCESS);
325-
return processCredentials;
322+
awsCredentials = new ProcessAWSCredentials(options.CredentialProcess, options.AwsAccountId);
323+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_PROCESS);
324+
break;
326325

327326
default:
328327
var defaultMessage = profileName == null
@@ -333,6 +332,11 @@ private static AWSCredentials GetAWSCredentialsInternal(
333332

334333
return ThrowOrReturnNull(defaultMessage, null, throwIfInvalid);
335334
}
335+
336+
if (profileSource is NetSDKCredentialsFile)
337+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_AWS_SDK_STORE);
338+
339+
return awsCredentials;
336340
}
337341
else
338342
{

Diff for: sdk/src/Core/Amazon.Runtime/Credentials/BasicAWSCredentials.cs

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public BasicAWSCredentials(string accessKey, string secretKey) : this (accessKey
5353
/// <param name="accountId">The account id for the credentials. The account id is your 12 digit account number with no hyphens. For example: 123456789012</param>
5454
public BasicAWSCredentials(string accessKey, string secretKey, string accountId)
5555
{
56+
if (string.IsNullOrEmpty(accountId)) FeatureIdSources.Add(UserAgentFeatureId.RESOLVED_ACCOUNT_ID);
5657
if (!string.IsNullOrEmpty(accessKey))
5758
{
5859
_credentials = new ImmutableCredentials(accessKey, secretKey, null, accountId);

Diff for: sdk/src/Core/Amazon.Runtime/Credentials/ProcessAWSCredentials.cs

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public ProcessAWSCredentials(string processCredentialInfo, string accountId)
103103
PreemptExpiryTime = TimeSpan.FromMinutes(15);
104104

105105
FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROCESS);
106+
if (string.IsNullOrEmpty(accountId)) FeatureIdSources.Add(UserAgentFeatureId.RESOLVED_ACCOUNT_ID);
106107
}
107108

108109
#endregion

Diff for: sdk/src/Core/Amazon.Runtime/Credentials/SessionAWSCredentials.cs

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public SessionAWSCredentials(string awsAccessKeyId, string awsSecretAccessKey, s
5454
if (string.IsNullOrEmpty(token)) throw new ArgumentNullException("token");
5555
_lastCredentials = new ImmutableCredentials(awsAccessKeyId, awsSecretAccessKey, token, accountId);
5656
FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_STS_SESSION_TOKEN);
57+
if (string.IsNullOrEmpty(accountId)) FeatureIdSources.Add(UserAgentFeatureId.RESOLVED_ACCOUNT_ID);
5758
}
5859

5960
#endregion

Diff for: sdk/src/Core/Amazon.Runtime/IClientConfig.cs

+7
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,13 @@ public partial interface IClientConfig
387387
/// </summary>
388388
ResponseChecksumValidation ResponseChecksumValidation { get; }
389389

390+
/// <summary>
391+
/// Controls whether the resolved endpoint will include the account id. This allows for direct routing of traffic
392+
/// to the cell responsible for a given account, which avoids the additional latency of extra backend hops and reduces
393+
/// complexity in the routing layer.
394+
/// </summary>
395+
public AccountIdEndpointMode AccountIdEndpointMode { get; }
396+
390397
#if BCL
391398
/// <summary>
392399
/// Gets the TCP keep-alive values to use for service requests. Enabling TCP keep-alive sends periodic TCP keep-alive probe packets, to prevent disconnection due to

Diff for: sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/BaseEndpointResolver.cs

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Amazon.Runtime.Internal.Auth;
2121
using Amazon.Runtime.Telemetry;
2222
using Amazon.Runtime.Telemetry.Metrics;
23+
using Amazon.Runtime.Internal.UserAgent;
2324

2425
namespace Amazon.Runtime.Internal
2526
{
@@ -73,6 +74,10 @@ public virtual void ProcessRequestHandlers(IExecutionContext executionContext)
7374
};
7475
requestContext.Request.Endpoint = uriBuilder.Uri;
7576
}
77+
if (!string.IsNullOrEmpty(requestContext.ClientConfig.ServiceURL))
78+
{
79+
executionContext.RequestContext.UserAgentDetails.AddFeature(UserAgentFeatureId.ENDPOINT_OVERRIDE);
80+
}
7681

7782
// set authentication parameters and headers
7883
SetAuthenticationAndHeaders(requestContext.Request, endpoint);

Diff for: sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs

-2
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ private static void SetRecursionDetectionHeader(IDictionary<string, string> head
126126

127127
private static void UpdateUserAgentDetails(IRequestContext requestContext)
128128
{
129-
var sb = new StringBuilder(256);
130-
131129
requestContext.UserAgentDetails.AddUserAgentComponent(InternalSDKUtils.ReplaceInvalidUserAgentCharacters(requestContext.ClientConfig.UserAgent));
132130

133131
var clientAppId = requestContext.ClientConfig.ClientAppId;

Diff for: sdk/src/Core/Amazon.Runtime/Pipeline/HttpHandler/HttpHandler.cs

+13
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
using System.Net;
2727
using System.Reflection;
2828
using System.Text;
29+
using Amazon.Runtime.Internal.UserAgent;
2930

3031
namespace Amazon.Runtime.Internal
3132
{
@@ -489,6 +490,18 @@ private static System.IO.Stream GetInputStream(IRequestContext requestContext, S
489490

490491
private void SetUserAgentHeader(IRequestContext requestContext)
491492
{
493+
var accountIdMode = requestContext.ClientConfig.AccountIdEndpointMode;
494+
if (accountIdMode == AccountIdEndpointMode.DISABLED)
495+
requestContext.UserAgentDetails.AddFeature(UserAgentFeatureId.ACCOUNT_ID_MODE_DISABLED);
496+
else if (accountIdMode == AccountIdEndpointMode.PREFERRED)
497+
requestContext.UserAgentDetails.AddFeature(UserAgentFeatureId.ACCOUNT_ID_MODE_PREFERRED);
498+
else if (accountIdMode == AccountIdEndpointMode.REQUIRED)
499+
requestContext.UserAgentDetails.AddFeature(UserAgentFeatureId.ACCOUNT_ID_MODE_REQUIRED);
500+
501+
if (requestContext.Request.SignatureVersion == SignatureVersion.SigV4a)
502+
requestContext.UserAgentDetails.AddFeature(UserAgentFeatureId.SIGV4A_SIGNING);
503+
504+
492505
var metricsUserAgent = requestContext.UserAgentDetails.GenerateUserAgentWithMetrics();
493506
Logger.DebugFormat("User-Agent Header: {0}", metricsUserAgent);
494507

Diff for: sdk/src/Services/S3/Custom/Internal/AmazonS3PostMarshallHandler.cs

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
using Amazon.Util;
2525
using Amazon.S3.Util;
2626
using Amazon.S3.Model;
27+
using Amazon.Runtime.Internal.UserAgent;
2728

2829
#pragma warning disable 1591
2930

@@ -66,6 +67,9 @@ protected virtual void PreInvoke(IExecutionContext executionContext)
6667

6768
private static void ProcessPreRequestHandlers(IExecutionContext executionContext)
6869
{
70+
if (executionContext.RequestContext.Request.IsDirectoryBucket())
71+
executionContext.RequestContext.UserAgentDetails.AddFeature(UserAgentFeatureId.S3_EXPRESS_BUCKET);
72+
6973
var originalRequest = executionContext.RequestContext.OriginalRequest;
7074
if (SetStreamChecksum(originalRequest, executionContext.RequestContext.Request))
7175
return;

Diff for: sdk/test/UnitTests/Custom/EndpointsTests.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ public void EndpointResolverHttpsServiceURLVsUseHttp()
6868
ServiceURL = serviceURL,
6969
UseHttp = true
7070
};
71+
var originalRequest = new MockAmazonWebServiceRequest();
7172
var requestContext = new RequestContext(false, new NullSigner())
7273
{
7374
ClientConfig = config,
74-
Request = new DefaultRequest(new MockAmazonWebServiceRequest(), "test-service")
75+
Request = new DefaultRequest(originalRequest, "test-service"),
76+
OriginalRequest = originalRequest,
7577
};
7678

7779
var executionContext = new ExecutionContext(requestContext, null);

0 commit comments

Comments
 (0)