diff --git a/aws/session/cabundle_transport.go b/aws/session/cabundle_transport.go new file mode 100644 index 00000000000..ea9ebb6f6a2 --- /dev/null +++ b/aws/session/cabundle_transport.go @@ -0,0 +1,26 @@ +// +build go1.7 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} diff --git a/aws/session/cabundle_transport_1_5.go b/aws/session/cabundle_transport_1_5.go new file mode 100644 index 00000000000..fec39dfc126 --- /dev/null +++ b/aws/session/cabundle_transport_1_5.go @@ -0,0 +1,22 @@ +// +build !go1.6,go1.5 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + } +} diff --git a/aws/session/cabundle_transport_1_6.go b/aws/session/cabundle_transport_1_6.go new file mode 100644 index 00000000000..1c5a5391e65 --- /dev/null +++ b/aws/session/cabundle_transport_1_6.go @@ -0,0 +1,23 @@ +// +build !go1.7,go1.6 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} diff --git a/aws/session/custom_ca_bundle_test.go b/aws/session/custom_ca_bundle_test.go index 68b59682ad9..ae25c483ca9 100644 --- a/aws/session/custom_ca_bundle_test.go +++ b/aws/session/custom_ca_bundle_test.go @@ -140,6 +140,36 @@ func TestNewSession_WithCustomCABundle_Option(t *testing.T) { } } +func TestNewSession_WithCustomCABundle_HTTPProxyAvailable(t *testing.T) { + skipTravisTest(t) + + oldEnv := initSessionTestEnv() + defer awstesting.PopEnv(oldEnv) + + s, err := NewSessionWithOptions(Options{ + Config: aws.Config{ + HTTPClient: &http.Client{}, + Region: aws.String("mock-region"), + Credentials: credentials.AnonymousCredentials, + }, + CustomCABundle: bytes.NewReader(awstesting.TLSBundleCA), + }) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } + if s == nil { + t.Fatalf("expect session to be created, got none") + } + + tr := s.Config.HTTPClient.Transport.(*http.Transport) + if tr.Proxy == nil { + t.Fatalf("expect transport proxy, was nil") + } + if tr.TLSClientConfig.RootCAs == nil { + t.Fatalf("expect TLS config to have root CAs") + } +} + func TestNewSession_WithCustomCABundle_OptionPriority(t *testing.T) { skipTravisTest(t) diff --git a/aws/session/session.go b/aws/session/session.go index 9bdbafd65cc..be4b5f07772 100644 --- a/aws/session/session.go +++ b/aws/session/session.go @@ -407,7 +407,10 @@ func loadCustomCABundle(s *Session, bundle io.Reader) error { } } if t == nil { - t = &http.Transport{} + // Nil transport implies `http.DefaultTransport` should be used. Since + // the SDK cannot modify, nor copy the `DefaultTransport` specifying + // the values the next closest behavior. + t = getCABundleTransport() } p, err := loadCertPool(bundle)