Skip to content

Commit 0765ba8

Browse files
roycaihwliggitt
andcommitted
don't cache transports for incomparable configs
Co-authored-by: Jordan Liggitt <[email protected]>
1 parent c1ce63a commit 0765ba8

File tree

2 files changed

+47
-48
lines changed

2 files changed

+47
-48
lines changed

staging/src/k8s.io/client-go/transport/cache.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,35 +47,34 @@ type tlsCacheKey struct {
4747
keyData string
4848
certFile string
4949
keyFile string
50-
getCert string
5150
serverName string
5251
nextProtos string
53-
dial string
5452
disableCompression bool
55-
proxy string
5653
}
5754

5855
func (t tlsCacheKey) String() string {
5956
keyText := "<none>"
6057
if len(t.keyData) > 0 {
6158
keyText = "<redacted>"
6259
}
63-
return fmt.Sprintf("insecure:%v, caData:%#v, certData:%#v, keyData:%s, getCert: %s, serverName:%s, dial:%s disableCompression:%t, proxy: %s", t.insecure, t.caData, t.certData, keyText, t.getCert, t.serverName, t.dial, t.disableCompression, t.proxy)
60+
return fmt.Sprintf("insecure:%v, caData:%#v, certData:%#v, keyData:%s, serverName:%s, disableCompression:%t", t.insecure, t.caData, t.certData, keyText, t.serverName, t.disableCompression)
6461
}
6562

6663
func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
67-
key, err := tlsConfigKey(config)
64+
key, canCache, err := tlsConfigKey(config)
6865
if err != nil {
6966
return nil, err
7067
}
7168

72-
// Ensure we only create a single transport for the given TLS options
73-
c.mu.Lock()
74-
defer c.mu.Unlock()
69+
if canCache {
70+
// Ensure we only create a single transport for the given TLS options
71+
c.mu.Lock()
72+
defer c.mu.Unlock()
7573

76-
// See if we already have a custom transport for this config
77-
if t, ok := c.transports[key]; ok {
78-
return t, nil
74+
// See if we already have a custom transport for this config
75+
if t, ok := c.transports[key]; ok {
76+
return t, nil
77+
}
7978
}
8079

8180
// Get the TLS options for this client config
@@ -110,33 +109,41 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
110109
proxy = config.Proxy
111110
}
112111

113-
// Cache a single transport for these options
114-
c.transports[key] = utilnet.SetTransportDefaults(&http.Transport{
112+
transport := utilnet.SetTransportDefaults(&http.Transport{
115113
Proxy: proxy,
116114
TLSHandshakeTimeout: 10 * time.Second,
117115
TLSClientConfig: tlsConfig,
118116
MaxIdleConnsPerHost: idleConnsPerHost,
119117
DialContext: dial,
120118
DisableCompression: config.DisableCompression,
121119
})
122-
return c.transports[key], nil
120+
121+
if canCache {
122+
// Cache a single transport for these options
123+
c.transports[key] = transport
124+
}
125+
126+
return transport, nil
123127
}
124128

125129
// tlsConfigKey returns a unique key for tls.Config objects returned from TLSConfigFor
126-
func tlsConfigKey(c *Config) (tlsCacheKey, error) {
130+
func tlsConfigKey(c *Config) (tlsCacheKey, bool, error) {
127131
// Make sure ca/key/cert content is loaded
128132
if err := loadTLSFiles(c); err != nil {
129-
return tlsCacheKey{}, err
133+
return tlsCacheKey{}, false, err
130134
}
135+
136+
if c.TLS.GetCert != nil || c.Dial != nil || c.Proxy != nil {
137+
// cannot determine equality for functions
138+
return tlsCacheKey{}, false, nil
139+
}
140+
131141
k := tlsCacheKey{
132142
insecure: c.TLS.Insecure,
133143
caData: string(c.TLS.CAData),
134-
getCert: fmt.Sprintf("%p", c.TLS.GetCert),
135144
serverName: c.TLS.ServerName,
136145
nextProtos: strings.Join(c.TLS.NextProtos, ","),
137-
dial: fmt.Sprintf("%p", c.Dial),
138146
disableCompression: c.DisableCompression,
139-
proxy: fmt.Sprintf("%p", c.Proxy),
140147
}
141148

142149
if c.TLS.ReloadTLSFiles {
@@ -147,5 +154,5 @@ func tlsConfigKey(c *Config) (tlsCacheKey, error) {
147154
k.keyData = string(c.TLS.KeyData)
148155
}
149156

150-
return k, nil
157+
return k, true, nil
151158
}

staging/src/k8s.io/client-go/transport/cache_test.go

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"crypto/tls"
2222
"net"
2323
"net/http"
24-
"net/url"
2524
"testing"
2625
)
2726

@@ -37,16 +36,24 @@ func TestTLSConfigKey(t *testing.T) {
3736
}
3837
for nameA, valueA := range identicalConfigurations {
3938
for nameB, valueB := range identicalConfigurations {
40-
keyA, err := tlsConfigKey(valueA)
39+
keyA, canCache, err := tlsConfigKey(valueA)
4140
if err != nil {
4241
t.Errorf("Unexpected error for %q: %v", nameA, err)
4342
continue
4443
}
45-
keyB, err := tlsConfigKey(valueB)
44+
if !canCache {
45+
t.Errorf("Unexpected canCache=false")
46+
continue
47+
}
48+
keyB, canCache, err := tlsConfigKey(valueB)
4649
if err != nil {
4750
t.Errorf("Unexpected error for %q: %v", nameB, err)
4851
continue
4952
}
53+
if !canCache {
54+
t.Errorf("Unexpected canCache=false")
55+
continue
56+
}
5057
if keyA != keyB {
5158
t.Errorf("Expected identical cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
5259
continue
@@ -132,12 +139,12 @@ func TestTLSConfigKey(t *testing.T) {
132139
}
133140
for nameA, valueA := range uniqueConfigurations {
134141
for nameB, valueB := range uniqueConfigurations {
135-
keyA, err := tlsConfigKey(valueA)
142+
keyA, canCacheA, err := tlsConfigKey(valueA)
136143
if err != nil {
137144
t.Errorf("Unexpected error for %q: %v", nameA, err)
138145
continue
139146
}
140-
keyB, err := tlsConfigKey(valueB)
147+
keyB, canCacheB, err := tlsConfigKey(valueB)
141148
if err != nil {
142149
t.Errorf("Unexpected error for %q: %v", nameB, err)
143150
continue
@@ -148,33 +155,18 @@ func TestTLSConfigKey(t *testing.T) {
148155
if keyA != keyB {
149156
t.Errorf("Expected identical cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
150157
}
158+
if canCacheA != canCacheB {
159+
t.Errorf("Expected identical canCache %q and %q, got:\n\t%v\n\t%v", nameA, nameB, canCacheA, canCacheB)
160+
}
151161
continue
152162
}
153163

154-
if keyA == keyB {
155-
t.Errorf("Expected unique cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
156-
continue
164+
if canCacheA && canCacheB {
165+
if keyA == keyB {
166+
t.Errorf("Expected unique cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
167+
continue
168+
}
157169
}
158170
}
159171
}
160172
}
161-
162-
func TestTLSConfigKeyFuncPtr(t *testing.T) {
163-
keys := make(map[tlsCacheKey]struct{})
164-
makeKey := func(p func(*http.Request) (*url.URL, error)) tlsCacheKey {
165-
key, err := tlsConfigKey(&Config{Proxy: p})
166-
if err != nil {
167-
t.Fatalf("Unexpected error creating cache key: %v", err)
168-
}
169-
return key
170-
}
171-
172-
keys[makeKey(http.ProxyFromEnvironment)] = struct{}{}
173-
keys[makeKey(http.ProxyFromEnvironment)] = struct{}{}
174-
keys[makeKey(http.ProxyURL(nil))] = struct{}{}
175-
keys[makeKey(nil)] = struct{}{}
176-
177-
if got, want := len(keys), 3; got != want {
178-
t.Fatalf("Unexpected number of keys: got=%d want=%d", got, want)
179-
}
180-
}

0 commit comments

Comments
 (0)