Skip to content

Commit 72c76b2

Browse files
committed
Reuse a single http.Transport for all AWS clients
While parsing the X.509 roots once is the real winner, we might as well reuse this thing that the Go docs tell you to reuse as much as possible.
1 parent d088f51 commit 72c76b2

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

internal/awsconfig/awsconfig.go

+20-16
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,14 @@ type Option = func(*config.LoadOptions) error
3535
// New creates a new AWS client configuration using reasonable default settings
3636
// for timeouts and retries.
3737
func New(ctx context.Context) (aws.Config, error) {
38-
transport := http.DefaultTransport.(*http.Transport).Clone()
38+
transport := http.DefaultTransport
3939

4040
// This option is recommended in AWS Lambda deployments due to the
4141
// significant reduction in cold start latency (see getEmbeddedCertPool).
4242
// It can be enabled for standard server deployments if desired, but is far
4343
// less beneficial.
4444
if os.Getenv("AWS_CLIENT_EMBEDDED_TLS_ROOTS") == "1" {
45-
transport.TLSClientConfig = &tls.Config{
46-
RootCAs: getEmbeddedCertPool(),
47-
}
45+
transport = getEmbeddedCertTransport()
4846
}
4947

5048
cfg, err := config.LoadDefaultConfig(ctx,
@@ -73,21 +71,27 @@ func New(ctx context.Context) (aws.Config, error) {
7371
return cfg, nil
7472
}
7573

74+
// getEmbeddedCertTransport returns an HTTP transport that trusts only the root
75+
// CAs operated by Amazon Trust Services, which all AWS service endpoints chain
76+
// from.
77+
//
78+
// When the randomizer runs on AWS Lambda in the recommended configuration, this
79+
// limited set of roots is so much cheaper to parse than a typical set of system
80+
// roots that it cuts cold start invocation time roughly in half (by around
81+
// 500ms). This is a large enough difference for a human to notice, and accounts
82+
// for about 15% of the 3 second response time limit that Slack imposes on slash
83+
// commands.
84+
var getEmbeddedCertTransport = sync.OnceValue(func() *http.Transport {
85+
transport := http.DefaultTransport.(*http.Transport).Clone()
86+
transport.TLSClientConfig = &tls.Config{RootCAs: loadEmbeddedCertPool()}
87+
return transport
88+
})
89+
7690
//go:generate ./refresh-amazon-trust-roots.sh
7791
//go:embed amazon-trust.cer
7892
var embeddedRootsDER []byte
7993

80-
// getEmbeddedCertPool returns a cert pool containing only the root CAs
81-
// operated by Amazon Trust Services, which all AWS service endpoints chain
82-
// from.
83-
//
84-
// When the randomizer runs on AWS Lambda in the recommended configuration,
85-
// this limited set of roots is so much cheaper to parse than the full set of
86-
// roots trusted by Amazon Linux 2 that it cuts invocation time on cold starts
87-
// approximately in half (by around 500ms). This is a large enough difference
88-
// for a human to notice, and accounts for about 15% of the 3 second response
89-
// time limit that Slack imposes on slash commands.
90-
var getEmbeddedCertPool = sync.OnceValue(func() *x509.CertPool {
94+
func loadEmbeddedCertPool() *x509.CertPool {
9195
certs, err := x509.ParseCertificates(embeddedRootsDER)
9296
if err != nil {
9397
panic(fmt.Errorf("failed to parse embedded TLS roots: %v", err))
@@ -97,4 +101,4 @@ var getEmbeddedCertPool = sync.OnceValue(func() *x509.CertPool {
97101
pool.AddCert(cert)
98102
}
99103
return pool
100-
})
104+
}

0 commit comments

Comments
 (0)