user_agent.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package middleware
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/Sirupsen/logrus"
  6. "github.com/docker/docker/api/server/httputils"
  7. "github.com/docker/engine-api/types/versions"
  8. "golang.org/x/net/context"
  9. )
  10. // UserAgentMiddleware is a middleware that
  11. // validates the client user-agent.
  12. type UserAgentMiddleware struct {
  13. serverVersion string
  14. }
  15. // NewUserAgentMiddleware creates a new UserAgentMiddleware
  16. // with the server version.
  17. func NewUserAgentMiddleware(s string) UserAgentMiddleware {
  18. return UserAgentMiddleware{
  19. serverVersion: s,
  20. }
  21. }
  22. // WrapHandler returns a new handler function wrapping the previous one in the request chain.
  23. func (u UserAgentMiddleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  24. return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  25. ctx = context.WithValue(ctx, httputils.UAStringKey, r.Header.Get("User-Agent"))
  26. if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") {
  27. userAgent := strings.Split(r.Header.Get("User-Agent"), "/")
  28. // v1.20 onwards includes the GOOS of the client after the version
  29. // such as Docker/1.7.0 (linux)
  30. if len(userAgent) == 2 && strings.Contains(userAgent[1], " ") {
  31. userAgent[1] = strings.Split(userAgent[1], " ")[0]
  32. }
  33. if len(userAgent) == 2 && !versions.Equal(u.serverVersion, userAgent[1]) {
  34. logrus.Debugf("Client and server don't have the same version (client: %s, server: %s)", userAgent[1], u.serverVersion)
  35. }
  36. }
  37. return handler(ctx, w, r, vars)
  38. }
  39. }