route_register.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package routing
  2. import (
  3. "net/http"
  4. "strings"
  5. "gopkg.in/macaron.v1"
  6. )
  7. type Router interface {
  8. Handle(method, pattern string, handlers []macaron.Handler) *macaron.Route
  9. Get(pattern string, handlers ...macaron.Handler) *macaron.Route
  10. }
  11. // RouteRegister allows you to add routes and macaron.Handlers
  12. // that the web server should serve.
  13. type RouteRegister interface {
  14. // Get adds a list of handlers to a given route with a GET HTTP verb
  15. Get(string, ...macaron.Handler)
  16. // Post adds a list of handlers to a given route with a POST HTTP verb
  17. Post(string, ...macaron.Handler)
  18. // Delete adds a list of handlers to a given route with a DELETE HTTP verb
  19. Delete(string, ...macaron.Handler)
  20. // Put adds a list of handlers to a given route with a PUT HTTP verb
  21. Put(string, ...macaron.Handler)
  22. // Patch adds a list of handlers to a given route with a PATCH HTTP verb
  23. Patch(string, ...macaron.Handler)
  24. // Any adds a list of handlers to a given route with any HTTP verb
  25. Any(string, ...macaron.Handler)
  26. // Group allows you to pass a function that can add multiple routes
  27. // with a shared prefix route.
  28. Group(string, func(RouteRegister), ...macaron.Handler)
  29. // Insert adds more routes to an existing Group.
  30. Insert(string, func(RouteRegister), ...macaron.Handler)
  31. // Register iterates over all routes added to the RouteRegister
  32. // and add them to the `Router` pass as an parameter.
  33. Register(Router)
  34. }
  35. type RegisterNamedMiddleware func(name string) macaron.Handler
  36. // NewRouteRegister creates a new RouteRegister with all middlewares sent as params
  37. func NewRouteRegister(namedMiddleware ...RegisterNamedMiddleware) RouteRegister {
  38. return &routeRegister{
  39. prefix: "",
  40. routes: []route{},
  41. subfixHandlers: []macaron.Handler{},
  42. namedMiddleware: namedMiddleware,
  43. }
  44. }
  45. type route struct {
  46. method string
  47. pattern string
  48. handlers []macaron.Handler
  49. }
  50. type routeRegister struct {
  51. prefix string
  52. subfixHandlers []macaron.Handler
  53. namedMiddleware []RegisterNamedMiddleware
  54. routes []route
  55. groups []*routeRegister
  56. }
  57. func (rr *routeRegister) Insert(pattern string, fn func(RouteRegister), handlers ...macaron.Handler) {
  58. //loop over all groups at current level
  59. for _, g := range rr.groups {
  60. // apply routes if the prefix matches the pattern
  61. if g.prefix == pattern {
  62. g.Group("", fn)
  63. break
  64. }
  65. // go down one level if the prefix can be find in the pattern
  66. if strings.HasPrefix(pattern, g.prefix) {
  67. g.Insert(pattern, fn)
  68. }
  69. }
  70. }
  71. func (rr *routeRegister) Group(pattern string, fn func(rr RouteRegister), handlers ...macaron.Handler) {
  72. group := &routeRegister{
  73. prefix: rr.prefix + pattern,
  74. subfixHandlers: append(rr.subfixHandlers, handlers...),
  75. routes: []route{},
  76. namedMiddleware: rr.namedMiddleware,
  77. }
  78. fn(group)
  79. rr.groups = append(rr.groups, group)
  80. }
  81. func (rr *routeRegister) Register(router Router) {
  82. for _, r := range rr.routes {
  83. // GET requests have to be added to macaron routing using Get()
  84. // Otherwise HEAD requests will not be allowed.
  85. // https://github.com/go-macaron/macaron/blob/a325110f8b392bce3e5cdeb8c44bf98078ada3be/router.go#L198
  86. if r.method == http.MethodGet {
  87. router.Get(r.pattern, r.handlers...)
  88. } else {
  89. router.Handle(r.method, r.pattern, r.handlers)
  90. }
  91. }
  92. for _, g := range rr.groups {
  93. g.Register(router)
  94. }
  95. }
  96. func (rr *routeRegister) route(pattern, method string, handlers ...macaron.Handler) {
  97. h := make([]macaron.Handler, 0)
  98. for _, fn := range rr.namedMiddleware {
  99. h = append(h, fn(pattern))
  100. }
  101. h = append(h, rr.subfixHandlers...)
  102. h = append(h, handlers...)
  103. for _, r := range rr.routes {
  104. if r.pattern == rr.prefix+pattern && r.method == method {
  105. panic("cannot add duplicate route")
  106. }
  107. }
  108. rr.routes = append(rr.routes, route{
  109. method: method,
  110. pattern: rr.prefix + pattern,
  111. handlers: h,
  112. })
  113. }
  114. func (rr *routeRegister) Get(pattern string, handlers ...macaron.Handler) {
  115. rr.route(pattern, http.MethodGet, handlers...)
  116. }
  117. func (rr *routeRegister) Post(pattern string, handlers ...macaron.Handler) {
  118. rr.route(pattern, http.MethodPost, handlers...)
  119. }
  120. func (rr *routeRegister) Delete(pattern string, handlers ...macaron.Handler) {
  121. rr.route(pattern, http.MethodDelete, handlers...)
  122. }
  123. func (rr *routeRegister) Put(pattern string, handlers ...macaron.Handler) {
  124. rr.route(pattern, http.MethodPut, handlers...)
  125. }
  126. func (rr *routeRegister) Patch(pattern string, handlers ...macaron.Handler) {
  127. rr.route(pattern, http.MethodPatch, handlers...)
  128. }
  129. func (rr *routeRegister) Any(pattern string, handlers ...macaron.Handler) {
  130. rr.route(pattern, "*", handlers...)
  131. }