docker_cli_registry_user_agent_test.go 3.1 KB

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