浏览代码

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 <djordje.lukic@docker.com>
Djordje Lukic 2 年之前
父节点
当前提交
f696a1b3b3
共有 1 个文件被更改,包括 12 次插入7 次删除
  1. 12 7
      daemon/containerd/resolver.go

+ 12 - 7
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