Add user agent header to all requests

Currently the user agent is only being used on the initial
resolve request, then switching to the default user agent.
This ensures the correct user agent is always used. There is
a larger fix in progress which does this is a cleaner way, but
the scope of this change is fixing the user agent issue.

Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
Derek McGowan 2019-06-11 22:57:36 +08:00
parent 02ed02eca5
commit bb00872800
No known key found for this signature in database
GPG Key ID: F58C5D0A4405ACDB
2 changed files with 29 additions and 7 deletions

View File

@ -31,6 +31,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/version"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context/ctxhttp"
@ -40,6 +41,7 @@ type dockerAuthorizer struct {
credentials func(string) (string, string, error)
client *http.Client
ua string
mu sync.Mutex
auth map[string]string
@ -54,6 +56,7 @@ func NewAuthorizer(client *http.Client, f func(string) (string, string, error))
return &dockerAuthorizer{
credentials: f,
client: client,
ua: "containerd/" + version.Version,
auth: map[string]string{},
}
}
@ -194,11 +197,16 @@ func (a *dockerAuthorizer) fetchTokenWithOAuth(ctx context.Context, to tokenOpti
form.Set("password", to.secret)
}
resp, err := ctxhttp.Post(
ctx, a.client, to.realm,
"application/x-www-form-urlencoded; charset=utf-8",
strings.NewReader(form.Encode()),
)
req, err := http.NewRequest("POST", to.realm, strings.NewReader(form.Encode()))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
if a.ua != "" {
req.Header.Set("User-Agent", a.ua)
}
resp, err := ctxhttp.Do(ctx, a.client, req)
if err != nil {
return "", err
}
@ -244,6 +252,10 @@ func (a *dockerAuthorizer) fetchToken(ctx context.Context, to tokenOptions) (str
return "", err
}
if a.ua != "" {
req.Header.Set("User-Agent", a.ua)
}
reqParams := req.URL.Query()
if to.service != "" {

View File

@ -111,6 +111,7 @@ type dockerResolver struct {
auth Authorizer
host func(string) (string, error)
headers http.Header
uagent string
plainHTTP bool
client *http.Client
tracker StatusTracker
@ -135,16 +136,22 @@ func NewResolver(options ResolverOptions) remotes.Resolver {
ocispec.MediaTypeImageManifest,
ocispec.MediaTypeImageIndex, "*"}, ", "))
}
if _, ok := options.Headers["User-Agent"]; !ok {
options.Headers.Set("User-Agent", "containerd/"+version.Version)
ua := options.Headers.Get("User-Agent")
if ua != "" {
options.Headers.Del("User-Agent")
} else {
ua = "containerd/" + version.Version
}
if options.Authorizer == nil {
options.Authorizer = NewAuthorizer(options.Client, options.Credentials)
options.Authorizer.(*dockerAuthorizer).ua = ua
}
return &dockerResolver{
auth: options.Authorizer,
host: options.Host,
headers: options.Headers,
uagent: ua,
plainHTTP: options.PlainHTTP,
client: options.Client,
tracker: options.Tracker,
@ -351,6 +358,7 @@ func (r *dockerResolver) Pusher(ctx context.Context, ref string) (remotes.Pusher
type dockerBase struct {
refspec reference.Spec
base url.URL
uagent string
client *http.Client
auth Authorizer
@ -382,6 +390,7 @@ func (r *dockerResolver) base(refspec reference.Spec) (*dockerBase, error) {
return &dockerBase{
refspec: refspec,
base: base,
uagent: r.uagent,
client: r.client,
auth: r.auth,
}, nil
@ -407,6 +416,7 @@ func (r *dockerBase) authorize(ctx context.Context, req *http.Request) error {
func (r *dockerBase) doRequest(ctx context.Context, req *http.Request) (*http.Response, error) {
ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", req.URL.String()))
log.G(ctx).WithField("request.headers", req.Header).WithField("request.method", req.Method).Debug("do request")
req.Header.Set("User-Agent", r.uagent)
if err := r.authorize(ctx, req); err != nil {
return nil, errors.Wrap(err, "failed to authorize")
}