useragent.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Package useragent provides helper functions to pack
  2. // version information into a single User-Agent header.
  3. package useragent
  4. import (
  5. "strings"
  6. )
  7. // VersionInfo is used to model UserAgent versions.
  8. type VersionInfo struct {
  9. Name string
  10. Version string
  11. }
  12. func (vi *VersionInfo) isValid() bool {
  13. const stopChars = " \t\r\n/"
  14. name := vi.Name
  15. vers := vi.Version
  16. if len(name) == 0 || strings.ContainsAny(name, stopChars) {
  17. return false
  18. }
  19. if len(vers) == 0 || strings.ContainsAny(vers, stopChars) {
  20. return false
  21. }
  22. return true
  23. }
  24. // AppendVersions converts versions to a string and appends the string to the string base.
  25. //
  26. // Each VersionInfo will be converted to a string in the format of
  27. // "product/version", where the "product" is get from the name field, while
  28. // version is get from the version field. Several pieces of version information
  29. // will be concatenated and separated by space.
  30. //
  31. // Example:
  32. // AppendVersions("base", VersionInfo{"foo", "1.0"}, VersionInfo{"bar", "2.0"})
  33. // results in "base foo/1.0 bar/2.0".
  34. func AppendVersions(base string, versions ...VersionInfo) string {
  35. if len(versions) == 0 {
  36. return base
  37. }
  38. verstrs := make([]string, 0, 1+len(versions))
  39. if len(base) > 0 {
  40. verstrs = append(verstrs, base)
  41. }
  42. for _, v := range versions {
  43. if !v.isValid() {
  44. continue
  45. }
  46. verstrs = append(verstrs, v.Name+"/"+v.Version)
  47. }
  48. return strings.Join(verstrs, " ")
  49. }