@@ -29,6 +29,7 @@ import (
2929 "github.com/containerd/containerd/log"
3030 "github.com/containerd/containerd/reference"
3131 "github.com/containerd/containerd/remotes"
32+ "github.com/containerd/containerd/version"
3233 digest "github.com/opencontainers/go-digest"
3334 ocispec "github.com/opencontainers/image-spec/specs-go/v1"
3435 "github.com/pkg/errors"
@@ -82,6 +83,9 @@ type ResolverOptions struct {
8283 // Host provides the hostname given a namespace.
8384 Host func (string ) (string , error )
8485
86+ // Headers are the HTTP request header fields sent by the resolver
87+ Headers http.Header
88+
8589 // PlainHTTP specifies to use plain http and not https
8690 PlainHTTP bool
8791
@@ -105,6 +109,7 @@ func DefaultHost(ns string) (string, error) {
105109type dockerResolver struct {
106110 auth Authorizer
107111 host func (string ) (string , error )
112+ headers http.Header
108113 plainHTTP bool
109114 client * http.Client
110115 tracker StatusTracker
@@ -118,12 +123,27 @@ func NewResolver(options ResolverOptions) remotes.Resolver {
118123 if options .Host == nil {
119124 options .Host = DefaultHost
120125 }
126+ if options .Headers == nil {
127+ options .Headers = make (http.Header )
128+ }
129+ if _ , ok := options .Headers ["Accept" ]; ! ok {
130+ // set headers for all the types we support for resolution.
131+ options .Headers .Set ("Accept" , strings .Join ([]string {
132+ images .MediaTypeDockerSchema2Manifest ,
133+ images .MediaTypeDockerSchema2ManifestList ,
134+ ocispec .MediaTypeImageManifest ,
135+ ocispec .MediaTypeImageIndex , "*" }, ", " ))
136+ }
137+ if _ , ok := options .Headers ["User-Agent" ]; ! ok {
138+ options .Headers .Set ("User-Agent" , "containerd/" + version .Version )
139+ }
121140 if options .Authorizer == nil {
122141 options .Authorizer = NewAuthorizer (options .Client , options .Credentials )
123142 }
124143 return & dockerResolver {
125144 auth : options .Authorizer ,
126145 host : options .Host ,
146+ headers : options .Headers ,
127147 plainHTTP : options .PlainHTTP ,
128148 client : options .Client ,
129149 tracker : options .Tracker ,
@@ -182,12 +202,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
182202 return "" , ocispec.Descriptor {}, err
183203 }
184204
185- // set headers for all the types we support for resolution.
186- req .Header .Set ("Accept" , strings .Join ([]string {
187- images .MediaTypeDockerSchema2Manifest ,
188- images .MediaTypeDockerSchema2ManifestList ,
189- ocispec .MediaTypeImageManifest ,
190- ocispec .MediaTypeImageIndex , "*" }, ", " ))
205+ req .Header = r .headers
191206
192207 log .G (ctx ).Debug ("resolving" )
193208 resp , err := fetcher .doRequestWithRetries (ctx , req , nil )
0 commit comments