77 "errors"
88 "fmt"
99 "io"
10+ "net/http"
1011 "strings"
1112
1213 "github.com/google/go-containerregistry/pkg/name"
@@ -18,6 +19,26 @@ import (
1819 "github.com/sigstore/sigstore-go/pkg/verify"
1920)
2021
22+ type noncompliantRegistryTransport struct {}
23+
24+ // RoundTrip will check if a request and associated response fulfill the following:
25+ // 1. The response returns a 406 status code
26+ // 2. The request path contains /referrers/
27+ // If both conditions are met, the response's status code will be overwritten to 404
28+ // This is a temporary solution to handle non compliant registries that return
29+ // an unexpected status code 406 when the go-containerregistry library used
30+ // by this code attempts to make a request to the referrers API.
31+ // The go-containerregistry library can handle 404 response but not a 406 response.
32+ // See the related go-containerregistry issue: https://github.com/google/go-containerregistry/issues/1962
33+ func (a * noncompliantRegistryTransport ) RoundTrip (req * http.Request ) (* http.Response , error ) {
34+ resp , err := http .DefaultTransport .RoundTrip (req )
35+ if resp .StatusCode == http .StatusNotAcceptable && strings .Contains (req .URL .Path , "/referrers/" ) {
36+ resp .StatusCode = http .StatusNotFound
37+ }
38+
39+ return resp , err
40+ }
41+
2142type VerifiedBundle struct {
2243 SGBundle * bundle.Bundle
2344 Result * verify.VerificationResult
@@ -94,7 +115,9 @@ func getBundles(ref name.Reference, remoteOpts []remote.Option) ([]*bundle.Bundl
94115
95116 digest := ref .Context ().Digest (desc .Digest .String ())
96117
97- referrers , err := remote .Referrers (digest , remoteOpts ... )
118+ transportOpts := []remote.Option {remote .WithTransport (& noncompliantRegistryTransport {})}
119+ transportOpts = append (transportOpts , remoteOpts ... )
120+ referrers , err := remote .Referrers (digest , transportOpts ... )
98121 if err != nil {
99122 return nil , nil , fmt .Errorf ("error getting referrers: %w" , err )
100123 }
0 commit comments