Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix minor regression on custom User-Agent #990

Merged
merged 4 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<!-- markdownlint-disable single-title -->
# v2.0.0 (Unreleased)

BUG FIXES

* Correctly handles user agents passed using `TF_APPEND_USER_AGENT` which contain `/`, `(`, `)`, or space ([#990](https://github.com/hashicorp/aws-sdk-go-base/pull/990))

# v2.0.0-beta.50 (2024-03-19)

BUG FIXES
Expand Down
5 changes: 2 additions & 3 deletions aws_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/defaults"
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
"github.com/aws/aws-sdk-go-v2/aws/ratelimit"
"github.com/aws/aws-sdk-go-v2/aws/retry"
"github.com/aws/aws-sdk-go-v2/config"
Expand Down Expand Up @@ -357,7 +356,7 @@ func commonLoadOptions(ctx context.Context, c *Config) ([]func(*config.LoadOptio
}

if len(c.UserAgent) > 0 {
apiOptions = append(apiOptions, withUserAgentAppender(c.UserAgent))
apiOptions = append(apiOptions, withUserAgentAppender(c.UserAgent.BuildUserAgentString()))
}

apiOptions = append(apiOptions, func(stack *middleware.Stack) error {
Expand All @@ -369,7 +368,7 @@ func commonLoadOptions(ctx context.Context, c *Config) ([]func(*config.LoadOptio
"source": fmt.Sprintf("envvar(%q)", constants.AppendUserAgentEnvVar),
"value": v,
})
apiOptions = append(apiOptions, awsmiddleware.AddUserAgentKey(v))
apiOptions = append(apiOptions, withUserAgentAppender(v))
}

if !c.SuppressDebugLog {
Expand Down
55 changes: 50 additions & 5 deletions internal/test/user_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type UserAgentTestCase struct {
}

func TestUserAgentProducts(t *testing.T, awsSdkGoUserAgent func() string, testUserAgentProducts func(t *testing.T, testCase UserAgentTestCase)) {
t.Helper()

testCases := map[string]UserAgentTestCase{
"standard User-Agent": {
Config: &config.Config{
Expand All @@ -29,17 +31,55 @@ func TestUserAgentProducts(t *testing.T, awsSdkGoUserAgent func() string, testUs
},
ExpectedUserAgent: awsSdkGoUserAgent(),
},
"customized User-Agent TF_APPEND_USER_AGENT": {

"customized User-Agent TF_APPEND_USER_AGENT product": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Region: "us-east-1",
SecretKey: servicemocks.MockStaticSecretKey,
},
EnvironmentVariables: map[string]string{
constants.AppendUserAgentEnvVar: "Env",
},
ExpectedUserAgent: awsSdkGoUserAgent() + " Env",
},

"customized User-Agent TF_APPEND_USER_AGENT product version": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Region: "us-east-1",
SecretKey: servicemocks.MockStaticSecretKey,
},
EnvironmentVariables: map[string]string{
constants.AppendUserAgentEnvVar: "Last",
constants.AppendUserAgentEnvVar: "Env/1.2",
},
ExpectedUserAgent: awsSdkGoUserAgent() + " Last",
ExpectedUserAgent: awsSdkGoUserAgent() + " Env/1.2",
},

"customized User-Agent TF_APPEND_USER_AGENT multi product": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Region: "us-east-1",
SecretKey: servicemocks.MockStaticSecretKey,
},
EnvironmentVariables: map[string]string{
constants.AppendUserAgentEnvVar: "Env1/1.2 Env2",
},
ExpectedUserAgent: awsSdkGoUserAgent() + " Env1/1.2 Env2",
},

"customized User-Agent TF_APPEND_USER_AGENT with comment": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Region: "us-east-1",
SecretKey: servicemocks.MockStaticSecretKey,
},
EnvironmentVariables: map[string]string{
constants.AppendUserAgentEnvVar: "Env1/1.2 (comment) Env2",
},
ExpectedUserAgent: awsSdkGoUserAgent() + " Env1/1.2 (comment) Env2",
},

"APN User-Agent Products": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Expand All @@ -62,6 +102,7 @@ func TestUserAgentProducts(t *testing.T, awsSdkGoUserAgent func() string, testUs
},
ExpectedUserAgent: "APN/1.0 partner/1.0 first/1.2.3 second/1.0.2 (a comment) " + awsSdkGoUserAgent(),
},

"APN User-Agent Products and TF_APPEND_USER_AGENT": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Expand All @@ -82,10 +123,11 @@ func TestUserAgentProducts(t *testing.T, awsSdkGoUserAgent func() string, testUs
},
},
EnvironmentVariables: map[string]string{
constants.AppendUserAgentEnvVar: "Last",
constants.AppendUserAgentEnvVar: "Last/9.0.0",
},
ExpectedUserAgent: "APN/1.0 partner/1.0 first/1.2.3 second/1.0.2 " + awsSdkGoUserAgent() + " Last",
ExpectedUserAgent: "APN/1.0 partner/1.0 first/1.2.3 second/1.0.2 " + awsSdkGoUserAgent() + " Last/9.0.0",
},

"User-Agent Products": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Expand All @@ -105,6 +147,7 @@ func TestUserAgentProducts(t *testing.T, awsSdkGoUserAgent func() string, testUs
},
ExpectedUserAgent: awsSdkGoUserAgent() + " first/1.2.3 second/1.0.2 (a comment)",
},

"APN and User-Agent Products": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Expand Down Expand Up @@ -137,6 +180,7 @@ func TestUserAgentProducts(t *testing.T, awsSdkGoUserAgent func() string, testUs
},
ExpectedUserAgent: "APN/1.0 partner/1.0 first/1.2.3 second/1.0.2 (a comment) " + awsSdkGoUserAgent() + " third/4.5.6 fourth/2.1",
},

"context": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Expand All @@ -156,6 +200,7 @@ func TestUserAgentProducts(t *testing.T, awsSdkGoUserAgent func() string, testUs
},
ExpectedUserAgent: awsSdkGoUserAgent() + " first/1.2.3 second/1.0.2 (a comment)",
},

"User-Agent Products and context": {
Config: &config.Config{
AccessKey: servicemocks.MockStaticAccessKey,
Expand Down
8 changes: 4 additions & 4 deletions user_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,21 @@ func prependUserAgentHeader(request *smithyhttp.Request, value string) {
request.Header["User-Agent"] = append(request.Header["User-Agent"][:0], current)
}

func withUserAgentAppender(foo UserAgentProducts) func(*middleware.Stack) error {
func withUserAgentAppender(ua string) func(*middleware.Stack) error {
return func(stack *middleware.Stack) error {
return stack.Build.Add(userAgentMiddleware(foo), middleware.After)
return stack.Build.Add(userAgentMiddleware(ua), middleware.After)
}
}

func userAgentMiddleware(foo UserAgentProducts) middleware.BuildMiddleware {
func userAgentMiddleware(ua string) middleware.BuildMiddleware {
return middleware.BuildMiddlewareFunc("tfUserAgentAppender",
func(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) (middleware.BuildOutput, middleware.Metadata, error) {
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return middleware.BuildOutput{}, middleware.Metadata{}, fmt.Errorf("unknown request type %T", in.Request)
}

appendUserAgentHeader(request, foo.BuildUserAgentString())
appendUserAgentHeader(request, ua)

return next.HandleBuild(ctx, in)
},
Expand Down