Factor out the doing of the registry challenge
This mainly just to keep method length a little more managable.
@@ -45,48 +45,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 {
@@ -107,9 +75,9 @@ attemptChallenge:
Transport: tx,
}).Do(req.WithContext(ctx))
if err != nil {
- if attemptInsecureFallback {
+ if insecureOK {
registryURL.Scheme = "http"
- attemptInsecureFallback = false
+ insecureOK = false
goto attemptChallenge
}
return nil, err
@@ -120,6 +88,45 @@ attemptChallenge:
}
registryURL = *res.Request.URL // <- the URL after any redirection
}
+ return &registryURL, 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 {
