Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle non-compliant referrers endpoint response with custom transport #170

Merged
merged 5 commits into from
Jun 18, 2024
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion pkg/webhook/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"net/http"
"strings"

"github.com/google/go-containerregistry/pkg/name"
Expand All @@ -18,6 +19,26 @@ import (
"github.com/sigstore/sigstore-go/pkg/verify"
)

type noncompliantRegistryTransport struct{}

// RoundTrip will check if a request and associated response fulfill the following:
// 1. The response returns a 406 status code
// 2. The request path contains /referrers/
// If both conditions are met, the response's status code will be overwritten to 404
// This is a temporary solution to handle non compliant registries that return
// an unexpected status code 406 when the go-containerregistry library used
// by this code attempts to make a request to the referrers API.
// The go-contqainerregistry library can handle 404 response but not a 406 response.
codysoyland marked this conversation as resolved.
Show resolved Hide resolved
// See the related go-containerregistry issue: https://github.com/google/go-containerregistry/issues/1962
func (a *noncompliantRegistryTransport) RoundTrip(req *http.Request) (*http.Response, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment to explain why this is needed. Also would be good to include a link to a go-containerregistry issue if we are reporting this as a bug there (since this hack can be removed if go-containerregistry can handle the this unexpected header).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have an issue filed yet but can add a link once I file one.

resp, err := http.DefaultTransport.RoundTrip(req)
if resp.StatusCode == http.StatusNotAcceptable && strings.Contains(req.URL.Path, "/referrers/") {
resp.StatusCode = http.StatusNotFound
}

return resp, err
}

type VerifiedBundle struct {
SGBundle *bundle.ProtobufBundle
Result *verify.VerificationResult
Expand Down Expand Up @@ -93,7 +114,9 @@ func getBundles(ref name.Reference, remoteOpts []remote.Option) ([]*bundle.Proto

digest := ref.Context().Digest(desc.Digest.String())

referrers, err := remote.Referrers(digest, remoteOpts...)
transportOpts := []remote.Option{remote.WithTransport(&noncompliantRegistryTransport{})}
transportOpts = append(transportOpts, remoteOpts...)
referrers, err := remote.Referrers(digest, transportOpts...)
if err != nil {
return nil, nil, fmt.Errorf("error getting referrers: %w", err)
}
Expand Down
Loading