router.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package vhost
  2. import (
  3. "errors"
  4. "sort"
  5. "strings"
  6. "sync"
  7. )
  8. var (
  9. ErrRouterConfigConflict = errors.New("router config conflict")
  10. )
  11. type Routers struct {
  12. RouterByDomain map[string][]*Router
  13. mutex sync.RWMutex
  14. }
  15. type Router struct {
  16. domain string
  17. location string
  18. payload interface{}
  19. }
  20. func NewRouters() *Routers {
  21. return &Routers{
  22. RouterByDomain: make(map[string][]*Router),
  23. }
  24. }
  25. func (r *Routers) Add(domain, location string, payload interface{}) error {
  26. r.mutex.Lock()
  27. defer r.mutex.Unlock()
  28. if _, exist := r.exist(domain, location); exist {
  29. return ErrRouterConfigConflict
  30. }
  31. vrs, found := r.RouterByDomain[domain]
  32. if !found {
  33. vrs = make([]*Router, 0, 1)
  34. }
  35. vr := &Router{
  36. domain: domain,
  37. location: location,
  38. payload: payload,
  39. }
  40. vrs = append(vrs, vr)
  41. sort.Sort(sort.Reverse(ByLocation(vrs)))
  42. r.RouterByDomain[domain] = vrs
  43. return nil
  44. }
  45. func (r *Routers) Del(domain, location string) {
  46. r.mutex.Lock()
  47. defer r.mutex.Unlock()
  48. vrs, found := r.RouterByDomain[domain]
  49. if !found {
  50. return
  51. }
  52. newVrs := make([]*Router, 0)
  53. for _, vr := range vrs {
  54. if vr.location != location {
  55. newVrs = append(newVrs, vr)
  56. }
  57. }
  58. r.RouterByDomain[domain] = newVrs
  59. }
  60. func (r *Routers) Get(host, path string) (vr *Router, exist bool) {
  61. r.mutex.RLock()
  62. defer r.mutex.RUnlock()
  63. vrs, found := r.RouterByDomain[host]
  64. if !found {
  65. return
  66. }
  67. // can't support load balance, will to do
  68. for _, vr = range vrs {
  69. if strings.HasPrefix(path, vr.location) {
  70. return vr, true
  71. }
  72. }
  73. return
  74. }
  75. func (r *Routers) exist(host, path string) (vr *Router, exist bool) {
  76. vrs, found := r.RouterByDomain[host]
  77. if !found {
  78. return
  79. }
  80. for _, vr = range vrs {
  81. if path == vr.location {
  82. return vr, true
  83. }
  84. }
  85. return
  86. }
  87. // sort by location
  88. type ByLocation []*Router
  89. func (a ByLocation) Len() int {
  90. return len(a)
  91. }
  92. func (a ByLocation) Swap(i, j int) {
  93. a[i], a[j] = a[j], a[i]
  94. }
  95. func (a ByLocation) Less(i, j int) bool {
  96. return strings.Compare(a[i].location, a[j].location) < 0
  97. }