From 45275ad3b030aee1e38edb0ea8a27dbf79e5a875 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Thu, 24 Jan 2019 17:30:21 +0000 Subject: [PATCH] Factor out the doing of the registry challenge This mainly just to keep method length a little more managable. --- registry/client_factory.go | 79 +++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/registry/client_factory.go b/registry/client_factory.go index da1e4ece7d..b0964f1e5c 100644 --- a/registry/client_factory.go +++ b/registry/client_factory.go @@ -44,48 +44,16 @@ func (t *logging) RoundTrip(req *http.Request) (*http.Response, error) { return res, err } -func (f *RemoteClientFactory) ClientFor(repo image.CanonicalName, creds Credentials) (Client, error) { - insecure := false - for _, h := range f.InsecureHosts { - if repo.Domain == h { - insecure = true - break - } - } - - tlsConfig := &tls.Config{ - InsecureSkipVerify: insecure, - } - // Since we construct one of these per scan, be fairly ruthless - // about throttling the number, and closing of, idle connections. - baseTx := &http.Transport{ - TLSClientConfig: tlsConfig, - MaxIdleConns: 10, - IdleConnTimeout: 10 * time.Second, - Proxy: http.ProxyFromEnvironment, - } - tx := f.Limiters.RoundTripper(baseTx, repo.Domain) - if f.Trace { - tx = &logging{f.Logger, tx} - } - - f.mu.Lock() - if f.challengeManager == nil { - f.challengeManager = challenge.NewSimpleManager() - } - manager := f.challengeManager - f.mu.Unlock() - +func (f *RemoteClientFactory) doChallenge(manager challenge.Manager, tx http.RoundTripper, domain string, insecureOK bool) (*url.URL, error) { registryURL := url.URL{ Scheme: "https", - Host: repo.Domain, + Host: domain, Path: "/v2/", } // Before we know how to authorise, need to establish which // authorisation challenges the host will send. See if we've been // here before. - attemptInsecureFallback := insecure attemptChallenge: cs, err := manager.GetChallenges(registryURL) if err != nil { @@ -104,9 +72,9 @@ attemptChallenge: Transport: tx, }).Do(req) if err != nil { - if attemptInsecureFallback { + if insecureOK { registryURL.Scheme = "http" - attemptInsecureFallback = false + insecureOK = false goto attemptChallenge } return nil, err @@ -117,6 +85,45 @@ attemptChallenge: } registryURL = *res.Request.URL // <- the URL after any redirection } + return ®istryURL, nil +} + +func (f *RemoteClientFactory) ClientFor(repo image.CanonicalName, creds Credentials) (Client, error) { + insecure := false + for _, h := range f.InsecureHosts { + if repo.Domain == h { + insecure = true + break + } + } + + tlsConfig := &tls.Config{ + InsecureSkipVerify: insecure, + } + // Since we construct one of these per scan, be fairly ruthless + // about throttling the number, and closing of, idle connections. + baseTx := &http.Transport{ + TLSClientConfig: tlsConfig, + MaxIdleConns: 10, + IdleConnTimeout: 10 * time.Second, + Proxy: http.ProxyFromEnvironment, + } + tx := f.Limiters.RoundTripper(baseTx, repo.Domain) + if f.Trace { + tx = &logging{f.Logger, tx} + } + + f.mu.Lock() + if f.challengeManager == nil { + f.challengeManager = challenge.NewSimpleManager() + } + manager := f.challengeManager + f.mu.Unlock() + + registryURL, err := f.doChallenge(manager, tx, repo.Domain, insecure) + if err != nil { + return nil, err + } cred := creds.credsFor(repo.Domain) if f.Trace {