You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
3.9 KiB

  1. package loop
  2. // Copyright (c) 2013-2017 The btcsuite developers
  3. // Copyright (c) 2015-2016 The Decred developers
  4. // Heavily inspired by https://github.com/btcsuite/btcd/blob/master/version.go
  5. // Copyright (C) 2015-2020 The Lightning Network Developers
  6. import (
  7. "bytes"
  8. "fmt"
  9. "math"
  10. "strings"
  11. )
  12. // Commit stores the current commit hash of this build, this should be set
  13. // using the -ldflags during compilation.
  14. var Commit string
  15. // semanticAlphabet is the allowed characters from the semantic versioning
  16. // guidelines for pre-release version and build metadata strings. In particular
  17. // they MUST only contain characters in semanticAlphabet.
  18. const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
  19. // These constants define the application version and follow the semantic
  20. // versioning 2.0.0 spec (http://semver.org/).
  21. const (
  22. // Note: please update release_notes.md when you change these values.
  23. appMajor uint = 0
  24. appMinor uint = 11
  25. appPatch uint = 2
  26. // appPreRelease MUST only contain characters from semanticAlphabet per
  27. // the semantic versioning spec.
  28. appPreRelease = "beta"
  29. // defaultAgentName is the default name of the software that is added as
  30. // the first part of the user agent string.
  31. defaultAgentName = "loopd"
  32. )
  33. // AgentName stores the name of the software that is added as the first part of
  34. // the user agent string. This defaults to the value "loopd" when being run as
  35. // a standalone component but can be overwritten by LiT for example when loopd
  36. // is integrated into the UI.
  37. var AgentName = defaultAgentName
  38. // Version returns the application version as a properly formed string per the
  39. // semantic versioning 2.0.0 spec (http://semver.org/) and the commit it was
  40. // built on.
  41. func Version() string {
  42. // Append commit hash of current build to version.
  43. return fmt.Sprintf("%s commit=%s", semanticVersion(), Commit)
  44. }
  45. // UserAgent returns the full user agent string that identifies the software
  46. // that is submitting swaps to the loop server.
  47. func UserAgent(initiator string) string {
  48. // We'll only allow "safe" characters in the initiator portion of the
  49. // user agent string and spaces only if surrounded by other characters.
  50. initiatorAlphabet := semanticAlphabet + ". "
  51. cleanInitiator := normalizeVerString(
  52. strings.TrimSpace(initiator), initiatorAlphabet,
  53. )
  54. if len(cleanInitiator) > 0 {
  55. cleanInitiator = fmt.Sprintf(",initiator=%s", cleanInitiator)
  56. }
  57. // The whole user agent string is limited to 255 characters server side
  58. // and also consists of the agent name, version and commit. So we only
  59. // want to take up at most 150 characters for the initiator. Anything
  60. // more will just be dropped.
  61. strLen := len(cleanInitiator)
  62. cleanInitiator = cleanInitiator[:int(math.Min(float64(strLen), 150))]
  63. // Assemble full string, including the commit hash of current build.
  64. return fmt.Sprintf(
  65. "%s/v%s/commit=%s%s", AgentName, semanticVersion(), Commit,
  66. cleanInitiator,
  67. )
  68. }
  69. // semanticVersion returns the SemVer part of the version.
  70. func semanticVersion() string {
  71. // Start with the major, minor, and patch versions.
  72. version := fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)
  73. // Append pre-release version if there is one. The hyphen called for
  74. // by the semantic versioning spec is automatically appended and should
  75. // not be contained in the pre-release string. The pre-release version
  76. // is not appended if it contains invalid characters.
  77. preRelease := normalizeVerString(appPreRelease, semanticAlphabet)
  78. if preRelease != "" {
  79. version = fmt.Sprintf("%s-%s", version, preRelease)
  80. }
  81. return version
  82. }
  83. // normalizeVerString returns the passed string stripped of all characters
  84. // which are not valid according to the given alphabet.
  85. func normalizeVerString(str, alphabet string) string {
  86. var result bytes.Buffer
  87. for _, r := range str {
  88. if strings.ContainsRune(alphabet, r) {
  89. result.WriteRune(r)
  90. }
  91. }
  92. return result.String()
  93. }