1
16
17 package transport
18
19 import (
20 "context"
21 "crypto/tls"
22 "net"
23 "net/http"
24 "net/url"
25 "reflect"
26 "testing"
27 )
28
29 func TestTLSConfigKey(t *testing.T) {
30
31 identicalConfigurations := map[string]*Config{
32 "empty": {},
33 "basic": {Username: "bob", Password: "password"},
34 "bearer": {BearerToken: "token"},
35 "user agent": {UserAgent: "useragent"},
36 "transport": {Transport: http.DefaultTransport},
37 "wrap transport": {WrapTransport: func(http.RoundTripper) http.RoundTripper { return nil }},
38 }
39 for nameA, valueA := range identicalConfigurations {
40 for nameB, valueB := range identicalConfigurations {
41 keyA, canCache, err := tlsConfigKey(valueA)
42 if err != nil {
43 t.Errorf("Unexpected error for %q: %v", nameA, err)
44 continue
45 }
46 if !canCache {
47 t.Errorf("Unexpected canCache=false")
48 continue
49 }
50 keyB, canCache, err := tlsConfigKey(valueB)
51 if err != nil {
52 t.Errorf("Unexpected error for %q: %v", nameB, err)
53 continue
54 }
55 if !canCache {
56 t.Errorf("Unexpected canCache=false")
57 continue
58 }
59 if keyA != keyB {
60 t.Errorf("Expected identical cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
61 continue
62 }
63 if keyA != (tlsCacheKey{}) {
64 t.Errorf("Expected empty cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
65 continue
66 }
67 }
68 }
69
70
71 dialer := net.Dialer{}
72 getCert := &GetCertHolder{GetCert: func() (*tls.Certificate, error) { return nil, nil }}
73 uniqueConfigurations := map[string]*Config{
74 "proxy": {Proxy: func(request *http.Request) (*url.URL, error) { return nil, nil }},
75 "no tls": {},
76 "dialer": {DialHolder: &DialHolder{Dial: dialer.DialContext}},
77 "dialer2": {DialHolder: &DialHolder{Dial: func(ctx context.Context, network, address string) (net.Conn, error) { return nil, nil }}},
78 "insecure": {TLS: TLSConfig{Insecure: true}},
79 "cadata 1": {TLS: TLSConfig{CAData: []byte{1}}},
80 "cadata 2": {TLS: TLSConfig{CAData: []byte{2}}},
81 "cert 1, key 1": {
82 TLS: TLSConfig{
83 CertData: []byte{1},
84 KeyData: []byte{1},
85 },
86 },
87 "cert 1, key 1, servername 1": {
88 TLS: TLSConfig{
89 CertData: []byte{1},
90 KeyData: []byte{1},
91 ServerName: "1",
92 },
93 },
94 "cert 1, key 1, servername 2": {
95 TLS: TLSConfig{
96 CertData: []byte{1},
97 KeyData: []byte{1},
98 ServerName: "2",
99 },
100 },
101 "cert 1, key 2": {
102 TLS: TLSConfig{
103 CertData: []byte{1},
104 KeyData: []byte{2},
105 },
106 },
107 "cert 2, key 1": {
108 TLS: TLSConfig{
109 CertData: []byte{2},
110 KeyData: []byte{1},
111 },
112 },
113 "cert 2, key 2": {
114 TLS: TLSConfig{
115 CertData: []byte{2},
116 KeyData: []byte{2},
117 },
118 },
119 "cadata 1, cert 1, key 1": {
120 TLS: TLSConfig{
121 CAData: []byte{1},
122 CertData: []byte{1},
123 KeyData: []byte{1},
124 },
125 },
126 "getCert1": {
127 TLS: TLSConfig{
128 KeyData: []byte{1},
129 GetCertHolder: getCert,
130 },
131 },
132 "getCert2": {
133 TLS: TLSConfig{
134 KeyData: []byte{1},
135 GetCertHolder: &GetCertHolder{GetCert: func() (*tls.Certificate, error) { return nil, nil }},
136 },
137 },
138 "getCert1, key 2": {
139 TLS: TLSConfig{
140 KeyData: []byte{2},
141 GetCertHolder: getCert,
142 },
143 },
144 "http2, http1.1": {TLS: TLSConfig{NextProtos: []string{"h2", "http/1.1"}}},
145 "http1.1-only": {TLS: TLSConfig{NextProtos: []string{"http/1.1"}}},
146 }
147 for nameA, valueA := range uniqueConfigurations {
148 for nameB, valueB := range uniqueConfigurations {
149 keyA, canCacheA, err := tlsConfigKey(valueA)
150 if err != nil {
151 t.Errorf("Unexpected error for %q: %v", nameA, err)
152 continue
153 }
154 keyB, canCacheB, err := tlsConfigKey(valueB)
155 if err != nil {
156 t.Errorf("Unexpected error for %q: %v", nameB, err)
157 continue
158 }
159
160 shouldCacheA := valueA.Proxy == nil
161 if shouldCacheA != canCacheA {
162 t.Errorf("Unexpected canCache=false for " + nameA)
163 }
164
165 configIsNotEmpty := !reflect.DeepEqual(*valueA, Config{})
166 if keyA == (tlsCacheKey{}) && shouldCacheA && configIsNotEmpty {
167 t.Errorf("Expected non-empty cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
168 continue
169 }
170
171
172 if nameA == nameB {
173 if keyA != keyB {
174 t.Errorf("Expected identical cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
175 }
176 if canCacheA != canCacheB {
177 t.Errorf("Expected identical canCache %q and %q, got:\n\t%v\n\t%v", nameA, nameB, canCacheA, canCacheB)
178 }
179 continue
180 }
181
182 if canCacheA && canCacheB {
183 if keyA == keyB {
184 t.Errorf("Expected unique cache keys for %q and %q, got:\n\t%s\n\t%s", nameA, nameB, keyA, keyB)
185 continue
186 }
187 }
188 }
189 }
190 }
191
View as plain text