github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/integration-cli/docker_cli_registry_user_agent_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "os" 8 "regexp" 9 "testing" 10 11 "github.com/docker/docker/testutil/registry" 12 "gotest.tools/v3/assert" 13 ) 14 15 // unescapeBackslashSemicolonParens unescapes \;() 16 func unescapeBackslashSemicolonParens(s string) string { 17 re := regexp.MustCompile(`\\;`) 18 ret := re.ReplaceAll([]byte(s), []byte(";")) 19 20 re = regexp.MustCompile(`\\\(`) 21 ret = re.ReplaceAll(ret, []byte("(")) 22 23 re = regexp.MustCompile(`\\\)`) 24 ret = re.ReplaceAll(ret, []byte(")")) 25 26 re = regexp.MustCompile(`\\\\`) 27 ret = re.ReplaceAll(ret, []byte(`\`)) 28 29 return string(ret) 30 } 31 32 func regexpCheckUA(c *testing.T, ua string) { 33 re := regexp.MustCompile("(?P<dockerUA>.+) UpstreamClient(?P<upstreamUA>.+)") 34 substrArr := re.FindStringSubmatch(ua) 35 36 assert.Equal(c, len(substrArr), 3, "Expected 'UpstreamClient()' with upstream client UA") 37 dockerUA := substrArr[1] 38 upstreamUAEscaped := substrArr[2] 39 40 // check dockerUA looks correct 41 reDockerUA := regexp.MustCompile("^docker/[0-9A-Za-z+]") 42 bMatchDockerUA := reDockerUA.MatchString(dockerUA) 43 assert.Assert(c, bMatchDockerUA, "Docker Engine User-Agent malformed") 44 45 // check upstreamUA looks correct 46 // Expecting something like: Docker-Client/1.11.0-dev (linux) 47 upstreamUA := unescapeBackslashSemicolonParens(upstreamUAEscaped) 48 reUpstreamUA := regexp.MustCompile(`^\(Docker-Client/[0-9A-Za-z+]`) 49 bMatchUpstreamUA := reUpstreamUA.MatchString(upstreamUA) 50 assert.Assert(c, bMatchUpstreamUA, "(Upstream) Docker Client User-Agent malformed") 51 } 52 53 // registerUserAgentHandler registers a handler for the `/v2/*` endpoint. 54 // Note that a 404 is returned to prevent the client to proceed. 55 // We are only checking if the client sent a valid User Agent string along 56 // with the request. 57 func registerUserAgentHandler(reg *registry.Mock, result *string) { 58 reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) { 59 w.WriteHeader(404) 60 w.Write([]byte(`{"errors":[{"code": "UNSUPPORTED","message": "this is a mock registry"}]}`)) 61 var ua string 62 for k, v := range r.Header { 63 if k == "User-Agent" { 64 ua = v[0] 65 } 66 } 67 *result = ua 68 }) 69 } 70 71 // TestUserAgentPassThrough verifies that when an image is pulled from 72 // a registry, the registry should see a User-Agent string of the form 73 // [docker engine UA] UpstreamClientSTREAM-CLIENT([client UA]) 74 func (s *DockerRegistrySuite) TestUserAgentPassThrough(c *testing.T) { 75 var ua string 76 77 reg, err := registry.NewMock(c) 78 assert.NilError(c, err) 79 defer reg.Close() 80 81 registerUserAgentHandler(reg, &ua) 82 repoName := fmt.Sprintf("%s/busybox", reg.URL()) 83 84 s.d.StartWithBusybox(c, "--insecure-registry", reg.URL()) 85 86 tmp, err := ioutil.TempDir("", "integration-cli-") 87 assert.NilError(c, err) 88 defer os.RemoveAll(tmp) 89 90 dockerfile, err := makefile(tmp, fmt.Sprintf("FROM %s", repoName)) 91 assert.NilError(c, err, "Unable to create test dockerfile") 92 93 s.d.Cmd("build", "--file", dockerfile, tmp) 94 regexpCheckUA(c, ua) 95 96 s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.URL()) 97 regexpCheckUA(c, ua) 98 99 s.d.Cmd("pull", repoName) 100 regexpCheckUA(c, ua) 101 102 s.d.Cmd("tag", "busybox", repoName) 103 s.d.Cmd("push", repoName) 104 regexpCheckUA(c, ua) 105 }