@@ -22,9 +22,7 @@ const (
22
22
defaultPath = "/v2"
23
23
)
24
24
25
- func fillInsecureOpts (host string , c config.RegistryConfig , h docker.RegistryHost ) ([]docker.RegistryHost , error ) {
26
- var hosts []docker.RegistryHost
27
-
25
+ func fillInsecureOpts (host string , c config.RegistryConfig , h docker.RegistryHost ) (* docker.RegistryHost , error ) {
28
26
tc , err := loadTLSConfig (c )
29
27
if err != nil {
30
28
return nil , err
@@ -40,33 +38,31 @@ func fillInsecureOpts(host string, c config.RegistryConfig, h docker.RegistryHos
40
38
}
41
39
}
42
40
43
- if isHTTP {
44
- h2 := h
45
- h2 .Scheme = "http"
46
- hosts = append (hosts , h2 )
47
- }
41
+ httpsTransport := newDefaultTransport ()
42
+ httpsTransport .TLSClientConfig = tc
43
+
48
44
if c .Insecure != nil && * c .Insecure {
49
45
h2 := h
50
- transport := newDefaultTransport ()
51
- transport .TLSClientConfig = tc
46
+
47
+ var transport http.RoundTripper = httpsTransport
48
+ if isHTTP {
49
+ transport = & httpFallback {super : transport }
50
+ }
52
51
h2 .Client = & http.Client {
53
52
Transport : tracing .NewTransport (transport ),
54
53
}
55
54
tc .InsecureSkipVerify = true
56
- hosts = append (hosts , h2 )
55
+ return & h2 , nil
56
+ } else if isHTTP {
57
+ h2 := h
58
+ h2 .Scheme = "http"
59
+ return & h2 , nil
57
60
}
58
61
59
- if len (hosts ) == 0 {
60
- transport := newDefaultTransport ()
61
- transport .TLSClientConfig = tc
62
-
63
- h .Client = & http.Client {
64
- Transport : tracing .NewTransport (transport ),
65
- }
66
- hosts = append (hosts , h )
62
+ h .Client = & http.Client {
63
+ Transport : tracing .NewTransport (httpsTransport ),
67
64
}
68
-
69
- return hosts , nil
65
+ return & h , nil
70
66
}
71
67
72
68
func loadTLSConfig (c config.RegistryConfig ) (* tls.Config , error ) {
@@ -133,12 +129,12 @@ func NewRegistryConfig(m map[string]config.RegistryConfig) docker.RegistryHosts
133
129
for _ , rawMirror := range c .Mirrors {
134
130
h := newMirrorRegistryHost (rawMirror )
135
131
mirrorHost := h .Host
136
- hosts , err := fillInsecureOpts (mirrorHost , m [mirrorHost ], h )
132
+ host , err := fillInsecureOpts (mirrorHost , m [mirrorHost ], h )
137
133
if err != nil {
138
134
return nil , err
139
135
}
140
136
141
- out = append (out , hosts ... )
137
+ out = append (out , * host )
142
138
}
143
139
144
140
if host == "docker.io" {
@@ -158,7 +154,8 @@ func NewRegistryConfig(m map[string]config.RegistryConfig) docker.RegistryHosts
158
154
return nil , err
159
155
}
160
156
161
- out = append (out , hosts ... )
157
+ out = append (out , * hosts )
158
+
162
159
return out , nil
163
160
},
164
161
docker .ConfigureDefaultRegistries (
@@ -210,3 +207,29 @@ func newDefaultTransport() *http.Transport {
210
207
TLSNextProto : make (map [string ]func (authority string , c * tls.Conn ) http.RoundTripper ),
211
208
}
212
209
}
210
+
211
+ type httpFallback struct {
212
+ super http.RoundTripper
213
+ fallback bool
214
+ }
215
+
216
+ func (f * httpFallback ) RoundTrip (r * http.Request ) (* http.Response , error ) {
217
+ if ! f .fallback {
218
+ resp , err := f .super .RoundTrip (r )
219
+ var tlsErr tls.RecordHeaderError
220
+ if errors .As (err , & tlsErr ) && string (tlsErr .RecordHeader [:]) == "HTTP/" {
221
+ // Server gave HTTP response to HTTPS client
222
+ f .fallback = true
223
+ } else {
224
+ return resp , err
225
+ }
226
+ }
227
+
228
+ plainHTTPUrl := * r .URL
229
+ plainHTTPUrl .Scheme = "http"
230
+
231
+ plainHTTPRequest := * r
232
+ plainHTTPRequest .URL = & plainHTTPUrl
233
+
234
+ return f .super .RoundTrip (& plainHTTPRequest )
235
+ }
0 commit comments