@@ -122,8 +122,13 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
122122 hosts [len (hosts )- 1 ].capabilities = docker .HostCapabilityPull | docker .HostCapabilityResolve | docker .HostCapabilityPush
123123 }
124124
125+ // explicitTLS indicates that TLS was explicitly configured and HTTP endpoints should
126+ // attempt to use the TLS configuration before falling back to HTTP
127+ var explicitTLS bool
128+
125129 var defaultTLSConfig * tls.Config
126130 if options .DefaultTLS != nil {
131+ explicitTLS = true
127132 defaultTLSConfig = options .DefaultTLS
128133 } else {
129134 defaultTLSConfig = & tls.Config {}
@@ -161,14 +166,11 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
161166
162167 rhosts := make ([]docker.RegistryHost , len (hosts ))
163168 for i , host := range hosts {
164-
165- rhosts [i ].Scheme = host .scheme
166- rhosts [i ].Host = host .host
167- rhosts [i ].Path = host .path
168- rhosts [i ].Capabilities = host .capabilities
169- rhosts [i ].Header = host .header
169+ // Allow setting for each host as well
170+ explicitTLS := explicitTLS
170171
171172 if host .caCerts != nil || host .clientPairs != nil || host .skipVerify != nil {
173+ explicitTLS = true
172174 tr := defaultTransport .Clone ()
173175 tlsConfig := tr .TLSClientConfig
174176 if host .skipVerify != nil {
@@ -232,6 +234,21 @@ func ConfigureHosts(ctx context.Context, options HostOptions) docker.RegistryHos
232234 rhosts [i ].Client = client
233235 rhosts [i ].Authorizer = authorizer
234236 }
237+
238+ // When TLS has been explicitly configured for the operation or host, use the
239+ // docker.HTTPFallback roundtripper to catch TLS errors and re-attempt the request as http.
240+ // This allows preference for https when configured but also catches TLS errors early enough
241+ // in the request to avoid sending the request twice or consuming the request body.
242+ if host .scheme == "http" && explicitTLS {
243+ host .scheme = "https"
244+ rhosts [i ].Client .Transport = docker.HTTPFallback {RoundTripper : rhosts [i ].Client .Transport }
245+ }
246+
247+ rhosts [i ].Scheme = host .scheme
248+ rhosts [i ].Host = host .host
249+ rhosts [i ].Path = host .path
250+ rhosts [i ].Capabilities = host .capabilities
251+ rhosts [i ].Header = host .header
235252 }
236253
237254 return rhosts , nil
0 commit comments