diff --git a/docs/endpoint.go b/docs/endpoint.go index 258a9c285..ef00431f4 100644 --- a/docs/endpoint.go +++ b/docs/endpoint.go @@ -45,12 +45,12 @@ func scanForAPIVersion(address string) (string, APIVersion) { // NewEndpoint parses the given address to return a registry endpoint. v can be used to // specify a specific endpoint version -func NewEndpoint(index *registrytypes.IndexInfo, metaHeaders http.Header, v APIVersion) (*Endpoint, error) { +func NewEndpoint(index *registrytypes.IndexInfo, userAgent string, metaHeaders http.Header, v APIVersion) (*Endpoint, error) { tlsConfig, err := newTLSConfig(index.Name, index.Secure) if err != nil { return nil, err } - endpoint, err := newEndpoint(GetAuthConfigKey(index), tlsConfig, metaHeaders) + endpoint, err := newEndpoint(GetAuthConfigKey(index), tlsConfig, userAgent, metaHeaders) if err != nil { return nil, err } @@ -91,7 +91,7 @@ func validateEndpoint(endpoint *Endpoint) error { return nil } -func newEndpoint(address string, tlsConfig *tls.Config, metaHeaders http.Header) (*Endpoint, error) { +func newEndpoint(address string, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) (*Endpoint, error) { var ( endpoint = new(Endpoint) trimmedAddress string @@ -112,7 +112,7 @@ func newEndpoint(address string, tlsConfig *tls.Config, metaHeaders http.Header) // TODO(tiborvass): make sure a ConnectTimeout transport is used tr := NewTransport(tlsConfig) - endpoint.client = HTTPClient(transport.NewTransport(tr, DockerHeaders(metaHeaders)...)) + endpoint.client = HTTPClient(transport.NewTransport(tr, DockerHeaders(userAgent, metaHeaders)...)) return endpoint, nil } diff --git a/docs/endpoint_test.go b/docs/endpoint_test.go index ee301dbd8..4677e0c9e 100644 --- a/docs/endpoint_test.go +++ b/docs/endpoint_test.go @@ -19,7 +19,7 @@ func TestEndpointParse(t *testing.T) { {"0.0.0.0:5000", "https://0.0.0.0:5000/v0/"}, } for _, td := range testData { - e, err := newEndpoint(td.str, nil, nil) + e, err := newEndpoint(td.str, nil, "", nil) if err != nil { t.Errorf("%q: %s", td.str, err) } diff --git a/docs/registry.go b/docs/registry.go index 643fa56e6..f4ddc15a0 100644 --- a/docs/registry.go +++ b/docs/registry.go @@ -21,9 +21,6 @@ import ( "github.com/docker/distribution/registry/api/v2" "github.com/docker/distribution/registry/client" "github.com/docker/distribution/registry/client/transport" - "github.com/docker/docker/dockerversion" - "github.com/docker/docker/pkg/parsers/kernel" - "github.com/docker/docker/pkg/useragent" "github.com/docker/go-connections/tlsconfig" ) @@ -34,23 +31,7 @@ var ( errLoginRequired = errors.New("Authentication is required.") ) -// dockerUserAgent is the User-Agent the Docker client uses to identify itself. -// It is populated on init(), comprising version information of different components. -var dockerUserAgent string - func init() { - httpVersion := make([]useragent.VersionInfo, 0, 6) - httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: dockerversion.Version}) - httpVersion = append(httpVersion, useragent.VersionInfo{Name: "go", Version: runtime.Version()}) - httpVersion = append(httpVersion, useragent.VersionInfo{Name: "git-commit", Version: dockerversion.GitCommit}) - if kernelVersion, err := kernel.GetKernelVersion(); err == nil { - httpVersion = append(httpVersion, useragent.VersionInfo{Name: "kernel", Version: kernelVersion.String()}) - } - httpVersion = append(httpVersion, useragent.VersionInfo{Name: "os", Version: runtime.GOOS}) - httpVersion = append(httpVersion, useragent.VersionInfo{Name: "arch", Version: runtime.GOARCH}) - - dockerUserAgent = useragent.AppendVersions("", httpVersion...) - if runtime.GOOS != "linux" { V2Only = true } @@ -130,12 +111,13 @@ func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error { return nil } -// DockerHeaders returns request modifiers that ensure requests have -// the User-Agent header set to dockerUserAgent and that metaHeaders -// are added. -func DockerHeaders(metaHeaders http.Header) []transport.RequestModifier { - modifiers := []transport.RequestModifier{ - transport.NewHeaderRequestModifier(http.Header{"User-Agent": []string{dockerUserAgent}}), +// DockerHeaders returns request modifiers with a User-Agent and metaHeaders +func DockerHeaders(userAgent string, metaHeaders http.Header) []transport.RequestModifier { + modifiers := []transport.RequestModifier{} + if userAgent != "" { + modifiers = append(modifiers, transport.NewHeaderRequestModifier(http.Header{ + "User-Agent": []string{userAgent}, + })) } if metaHeaders != nil { modifiers = append(modifiers, transport.NewHeaderRequestModifier(metaHeaders)) diff --git a/docs/registry_test.go b/docs/registry_test.go index 7630d9a52..98a3aa1c8 100644 --- a/docs/registry_test.go +++ b/docs/registry_test.go @@ -25,12 +25,13 @@ const ( func spawnTestRegistrySession(t *testing.T) *Session { authConfig := &types.AuthConfig{} - endpoint, err := NewEndpoint(makeIndex("/v1/"), nil, APIVersionUnknown) + endpoint, err := NewEndpoint(makeIndex("/v1/"), "", nil, APIVersionUnknown) if err != nil { t.Fatal(err) } + userAgent := "docker test client" var tr http.RoundTripper = debugTransport{NewTransport(nil), t.Log} - tr = transport.NewTransport(AuthTransport(tr, authConfig, false), DockerHeaders(nil)...) + tr = transport.NewTransport(AuthTransport(tr, authConfig, false), DockerHeaders(userAgent, nil)...) client := HTTPClient(tr) r, err := NewSession(client, authConfig, endpoint) if err != nil { @@ -52,7 +53,7 @@ func spawnTestRegistrySession(t *testing.T) *Session { func TestPingRegistryEndpoint(t *testing.T) { testPing := func(index *registrytypes.IndexInfo, expectedStandalone bool, assertMessage string) { - ep, err := NewEndpoint(index, nil, APIVersionUnknown) + ep, err := NewEndpoint(index, "", nil, APIVersionUnknown) if err != nil { t.Fatal(err) } @@ -72,7 +73,7 @@ func TestPingRegistryEndpoint(t *testing.T) { func TestEndpoint(t *testing.T) { // Simple wrapper to fail test if err != nil expandEndpoint := func(index *registrytypes.IndexInfo) *Endpoint { - endpoint, err := NewEndpoint(index, nil, APIVersionUnknown) + endpoint, err := NewEndpoint(index, "", nil, APIVersionUnknown) if err != nil { t.Fatal(err) } @@ -81,7 +82,7 @@ func TestEndpoint(t *testing.T) { assertInsecureIndex := func(index *registrytypes.IndexInfo) { index.Secure = true - _, err := NewEndpoint(index, nil, APIVersionUnknown) + _, err := NewEndpoint(index, "", nil, APIVersionUnknown) assertNotEqual(t, err, nil, index.Name+": Expected error for insecure index") assertEqual(t, strings.Contains(err.Error(), "insecure-registry"), true, index.Name+": Expected insecure-registry error for insecure index") index.Secure = false @@ -89,7 +90,7 @@ func TestEndpoint(t *testing.T) { assertSecureIndex := func(index *registrytypes.IndexInfo) { index.Secure = true - _, err := NewEndpoint(index, nil, APIVersionUnknown) + _, err := NewEndpoint(index, "", nil, APIVersionUnknown) assertNotEqual(t, err, nil, index.Name+": Expected cert error for secure index") assertEqual(t, strings.Contains(err.Error(), "certificate signed by unknown authority"), true, index.Name+": Expected cert error for secure index") index.Secure = false @@ -155,7 +156,7 @@ func TestEndpoint(t *testing.T) { } for _, address := range badEndpoints { index.Name = address - _, err := NewEndpoint(index, nil, APIVersionUnknown) + _, err := NewEndpoint(index, "", nil, APIVersionUnknown) checkNotEqual(t, err, nil, "Expected error while expanding bad endpoint") } } diff --git a/docs/service.go b/docs/service.go index dbdf17311..861cdb464 100644 --- a/docs/service.go +++ b/docs/service.go @@ -28,7 +28,7 @@ func NewService(options *Options) *Service { // Auth contacts the public registry with the provided credentials, // and returns OK if authentication was successful. // It can be used to verify the validity of a client's credentials. -func (s *Service) Auth(authConfig *types.AuthConfig) (string, error) { +func (s *Service) Auth(authConfig *types.AuthConfig, userAgent string) (string, error) { addr := authConfig.ServerAddress if addr == "" { // Use the official registry address if not specified. @@ -45,7 +45,7 @@ func (s *Service) Auth(authConfig *types.AuthConfig) (string, error) { endpointVersion = APIVersion2 } - endpoint, err := NewEndpoint(index, nil, endpointVersion) + endpoint, err := NewEndpoint(index, userAgent, nil, endpointVersion) if err != nil { return "", err } @@ -72,7 +72,7 @@ func splitReposSearchTerm(reposName string) (string, string) { // Search queries the public registry for images matching the specified // search terms, and returns the results. -func (s *Service) Search(term string, authConfig *types.AuthConfig, headers map[string][]string) (*registrytypes.SearchResults, error) { +func (s *Service) Search(term string, authConfig *types.AuthConfig, userAgent string, headers map[string][]string) (*registrytypes.SearchResults, error) { if err := validateNoSchema(term); err != nil { return nil, err } @@ -85,7 +85,7 @@ func (s *Service) Search(term string, authConfig *types.AuthConfig, headers map[ } // *TODO: Search multiple indexes. - endpoint, err := NewEndpoint(index, http.Header(headers), APIVersionUnknown) + endpoint, err := NewEndpoint(index, userAgent, http.Header(headers), APIVersionUnknown) if err != nil { return nil, err } @@ -129,8 +129,8 @@ type APIEndpoint struct { } // ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint -func (e APIEndpoint) ToV1Endpoint(metaHeaders http.Header) (*Endpoint, error) { - return newEndpoint(e.URL, e.TLSConfig, metaHeaders) +func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) (*Endpoint, error) { + return newEndpoint(e.URL, e.TLSConfig, userAgent, metaHeaders) } // TLSConfig constructs a client TLS configuration based on server defaults