route_register.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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) *macaron.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) *macaron.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. return &macaron.Router{}
  96. }
  97. func (rr *routeRegister) route(pattern, method string, handlers ...macaron.Handler) {
  98. h := make([]macaron.Handler, 0)
  99. for _, fn := range rr.namedMiddleware {
  100. h = append(h, fn(pattern))
  101. }
  102. h = append(h, rr.subfixHandlers...)
  103. h = append(h, handlers...)
  104. for _, r := range rr.routes {
  105. if r.pattern == rr.prefix+pattern && r.method == method {
  106. panic("cannot add duplicate route")
  107. }
  108. }
  109. rr.routes = append(rr.routes, route{
  110. method: method,
  111. pattern: rr.prefix + pattern,
  112. handlers: h,
  113. })
  114. }
  115. func (rr *routeRegister) Get(pattern string, handlers ...macaron.Handler) {
  116. rr.route(pattern, http.MethodGet, handlers...)
  117. }
  118. func (rr *routeRegister) Post(pattern string, handlers ...macaron.Handler) {
  119. rr.route(pattern, http.MethodPost, handlers...)
  120. }
  121. func (rr *routeRegister) Delete(pattern string, handlers ...macaron.Handler) {
  122. rr.route(pattern, http.MethodDelete, handlers...)
  123. }
  124. func (rr *routeRegister) Put(pattern string, handlers ...macaron.Handler) {
  125. rr.route(pattern, http.MethodPut, handlers...)
  126. }
  127. func (rr *routeRegister) Patch(pattern string, handlers ...macaron.Handler) {
  128. rr.route(pattern, http.MethodPatch, handlers...)
  129. }
  130. func (rr *routeRegister) Any(pattern string, handlers ...macaron.Handler) {
  131. rr.route(pattern, "*", handlers...)
  132. }