/host.go

https://github.com/webx-top/echo · Go · 117 lines · 110 code · 7 blank · 0 comment · 5 complexity · d223bec55b1c1bd6702c68c2c43e6166 MD5 · raw file

  1. package echo
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. type Hoster interface {
  7. Name() string
  8. Alias() string
  9. Format(args ...interface{}) string
  10. FormatMap(params H) string
  11. RegExp() *regexp.Regexp
  12. Match(host string) (r []string, hasExpr bool)
  13. }
  14. type host struct {
  15. name string
  16. alias string
  17. format string
  18. regExp *regexp.Regexp
  19. names []string
  20. }
  21. func (h *host) Name() string {
  22. return h.name
  23. }
  24. func (h *host) Alias() string {
  25. return h.alias
  26. }
  27. func (h *host) Format(args ...interface{}) string {
  28. if len(args) > 0 {
  29. return fmt.Sprintf(h.format, args...)
  30. }
  31. return h.format
  32. }
  33. func (h *host) FormatMap(params H) string {
  34. if len(params) > 0 {
  35. args := make([]interface{}, len(h.names))
  36. for index, name := range h.names {
  37. v, y := params[name]
  38. if y {
  39. args[index] = v
  40. } else {
  41. args[index] = ``
  42. }
  43. }
  44. return fmt.Sprintf(h.format, args...)
  45. }
  46. return h.format
  47. }
  48. func (h *host) RegExp() *regexp.Regexp {
  49. return h.regExp
  50. }
  51. func (h *host) Match(host string) (r []string, hasExpr bool) {
  52. if h.regExp != nil {
  53. match := h.regExp.FindStringSubmatch(host)
  54. if len(match) > 0 {
  55. return match[1:], true
  56. }
  57. return nil, true
  58. }
  59. return nil, false
  60. }
  61. func NewHost(name string) *host {
  62. return &host{name: name}
  63. }
  64. var hostRegExp = regexp.MustCompile(`<([^:]+)(?:\:(.+?))?>`)
  65. func ParseURIRegExp(uriRegexp string, dflRegexp string) (names []string, format string, regExp *regexp.Regexp) {
  66. matches := hostRegExp.FindAllStringSubmatchIndex(uriRegexp, -1)
  67. if len(matches) == 0 {
  68. return
  69. }
  70. if len(dflRegexp) == 0 {
  71. dflRegexp = `[^.]+`
  72. }
  73. var regExpr string
  74. var lastPosition int
  75. for _, matchIndex := range matches {
  76. if matchIndex[0] > 0 {
  77. v := uriRegexp[lastPosition:matchIndex[0]]
  78. format += v
  79. regExpr += regexp.QuoteMeta(v)
  80. }
  81. lastPosition = matchIndex[1]
  82. format += `%v`
  83. name := uriRegexp[matchIndex[2]:matchIndex[3]]
  84. if matchIndex[4] > 0 {
  85. regExpr += `(` + uriRegexp[matchIndex[4]:matchIndex[5]] + `)`
  86. } else {
  87. regExpr += `(` + dflRegexp + `)`
  88. }
  89. names = append(names, name)
  90. }
  91. if lastPosition > 0 {
  92. if lastPosition < len(uriRegexp) {
  93. v := uriRegexp[lastPosition:]
  94. format += v
  95. regExpr += regexp.QuoteMeta(v)
  96. }
  97. }
  98. regExp = regexp.MustCompile(`^` + regExpr + `$`)
  99. return
  100. }
  101. func (h *host) Parse() *host {
  102. h.names, h.format, h.regExp = ParseURIRegExp(h.name, ``)
  103. return h
  104. }