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