From f696a1b3b3ea5eaba29958d2dceee85b4af9bc12 Mon Sep 17 00:00:00 2001 From: Djordje Lukic Date: Wed, 12 Apr 2023 13:00:48 +0200 Subject: [PATCH] Fix error checking when pulling from an insecure registry The call to an unsecure registry doesn't return an error saying that the "server gave an HTTP response to an HTTPS client" but a tls.RecordHeaderError saying that the "first record does not look like a TLS handshake", this changeset looks for the right error for that case. This fixes the http fallback when using an insecure registry Signed-off-by: Djordje Lukic --- daemon/containerd/resolver.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/daemon/containerd/resolver.go b/daemon/containerd/resolver.go index 086bb2edcd..07c9ed9f0c 100644 --- a/daemon/containerd/resolver.go +++ b/daemon/containerd/resolver.go @@ -1,8 +1,9 @@ package containerd import ( + "crypto/tls" + "errors" "net/http" - "strings" "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" @@ -72,12 +73,16 @@ type httpFallback struct { func (f httpFallback) RoundTrip(r *http.Request) (*http.Response, error) { resp, err := f.super.RoundTrip(r) - if err != nil { - if strings.Contains(err.Error(), "http: server gave HTTP response to HTTPS client") { - plain := r.Clone(r.Context()) - plain.URL.Scheme = "http" - return http.DefaultTransport.RoundTrip(plain) - } + var tlsErr tls.RecordHeaderError + if errors.As(err, &tlsErr) && string(tlsErr.RecordHeader[:]) == "HTTP/" { + // server gave HTTP response to HTTPS client + plainHttpUrl := *r.URL + plainHttpUrl.Scheme = "http" + + plainHttpRequest := *r + plainHttpRequest.URL = &plainHttpUrl + + return http.DefaultTransport.RoundTrip(&plainHttpRequest) } return resp, err