hooks.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package fiber
  2. import (
  3. "github.com/gofiber/fiber/v2/log"
  4. )
  5. // OnRouteHandler Handlers define a function to create hooks for Fiber.
  6. type (
  7. OnRouteHandler = func(Route) error
  8. OnNameHandler = OnRouteHandler
  9. OnGroupHandler = func(Group) error
  10. OnGroupNameHandler = OnGroupHandler
  11. OnListenHandler = func(ListenData) error
  12. OnShutdownHandler = func() error
  13. OnForkHandler = func(int) error
  14. OnMountHandler = func(*App) error
  15. )
  16. // Hooks is a struct to use it with App.
  17. type Hooks struct {
  18. // Embed app
  19. app *App
  20. // Hooks
  21. onRoute []OnRouteHandler
  22. onName []OnNameHandler
  23. onGroup []OnGroupHandler
  24. onGroupName []OnGroupNameHandler
  25. onListen []OnListenHandler
  26. onShutdown []OnShutdownHandler
  27. onFork []OnForkHandler
  28. onMount []OnMountHandler
  29. }
  30. // ListenData is a struct to use it with OnListenHandler
  31. type ListenData struct {
  32. Host string
  33. Port string
  34. TLS bool
  35. }
  36. func newHooks(app *App) *Hooks {
  37. return &Hooks{
  38. app: app,
  39. onRoute: make([]OnRouteHandler, 0),
  40. onGroup: make([]OnGroupHandler, 0),
  41. onGroupName: make([]OnGroupNameHandler, 0),
  42. onName: make([]OnNameHandler, 0),
  43. onListen: make([]OnListenHandler, 0),
  44. onShutdown: make([]OnShutdownHandler, 0),
  45. onFork: make([]OnForkHandler, 0),
  46. onMount: make([]OnMountHandler, 0),
  47. }
  48. }
  49. // OnRoute is a hook to execute user functions on each route registeration.
  50. // Also you can get route properties by route parameter.
  51. func (h *Hooks) OnRoute(handler ...OnRouteHandler) {
  52. h.app.mutex.Lock()
  53. h.onRoute = append(h.onRoute, handler...)
  54. h.app.mutex.Unlock()
  55. }
  56. // OnName is a hook to execute user functions on each route naming.
  57. // Also you can get route properties by route parameter.
  58. //
  59. // WARN: OnName only works with naming routes, not groups.
  60. func (h *Hooks) OnName(handler ...OnNameHandler) {
  61. h.app.mutex.Lock()
  62. h.onName = append(h.onName, handler...)
  63. h.app.mutex.Unlock()
  64. }
  65. // OnGroup is a hook to execute user functions on each group registeration.
  66. // Also you can get group properties by group parameter.
  67. func (h *Hooks) OnGroup(handler ...OnGroupHandler) {
  68. h.app.mutex.Lock()
  69. h.onGroup = append(h.onGroup, handler...)
  70. h.app.mutex.Unlock()
  71. }
  72. // OnGroupName is a hook to execute user functions on each group naming.
  73. // Also you can get group properties by group parameter.
  74. //
  75. // WARN: OnGroupName only works with naming groups, not routes.
  76. func (h *Hooks) OnGroupName(handler ...OnGroupNameHandler) {
  77. h.app.mutex.Lock()
  78. h.onGroupName = append(h.onGroupName, handler...)
  79. h.app.mutex.Unlock()
  80. }
  81. // OnListen is a hook to execute user functions on Listen, ListenTLS, Listener.
  82. func (h *Hooks) OnListen(handler ...OnListenHandler) {
  83. h.app.mutex.Lock()
  84. h.onListen = append(h.onListen, handler...)
  85. h.app.mutex.Unlock()
  86. }
  87. // OnShutdown is a hook to execute user functions after Shutdown.
  88. func (h *Hooks) OnShutdown(handler ...OnShutdownHandler) {
  89. h.app.mutex.Lock()
  90. h.onShutdown = append(h.onShutdown, handler...)
  91. h.app.mutex.Unlock()
  92. }
  93. // OnFork is a hook to execute user function after fork process.
  94. func (h *Hooks) OnFork(handler ...OnForkHandler) {
  95. h.app.mutex.Lock()
  96. h.onFork = append(h.onFork, handler...)
  97. h.app.mutex.Unlock()
  98. }
  99. // OnMount is a hook to execute user function after mounting process.
  100. // The mount event is fired when sub-app is mounted on a parent app. The parent app is passed as a parameter.
  101. // It works for app and group mounting.
  102. func (h *Hooks) OnMount(handler ...OnMountHandler) {
  103. h.app.mutex.Lock()
  104. h.onMount = append(h.onMount, handler...)
  105. h.app.mutex.Unlock()
  106. }
  107. func (h *Hooks) executeOnRouteHooks(route Route) error {
  108. // Check mounting
  109. if h.app.mountFields.mountPath != "" {
  110. route.path = h.app.mountFields.mountPath + route.path
  111. route.Path = route.path
  112. }
  113. for _, v := range h.onRoute {
  114. if err := v(route); err != nil {
  115. return err
  116. }
  117. }
  118. return nil
  119. }
  120. func (h *Hooks) executeOnNameHooks(route Route) error {
  121. // Check mounting
  122. if h.app.mountFields.mountPath != "" {
  123. route.path = h.app.mountFields.mountPath + route.path
  124. route.Path = route.path
  125. }
  126. for _, v := range h.onName {
  127. if err := v(route); err != nil {
  128. return err
  129. }
  130. }
  131. return nil
  132. }
  133. func (h *Hooks) executeOnGroupHooks(group Group) error {
  134. // Check mounting
  135. if h.app.mountFields.mountPath != "" {
  136. group.Prefix = h.app.mountFields.mountPath + group.Prefix
  137. }
  138. for _, v := range h.onGroup {
  139. if err := v(group); err != nil {
  140. return err
  141. }
  142. }
  143. return nil
  144. }
  145. func (h *Hooks) executeOnGroupNameHooks(group Group) error {
  146. // Check mounting
  147. if h.app.mountFields.mountPath != "" {
  148. group.Prefix = h.app.mountFields.mountPath + group.Prefix
  149. }
  150. for _, v := range h.onGroupName {
  151. if err := v(group); err != nil {
  152. return err
  153. }
  154. }
  155. return nil
  156. }
  157. func (h *Hooks) executeOnListenHooks(listenData ListenData) error {
  158. for _, v := range h.onListen {
  159. if err := v(listenData); err != nil {
  160. return err
  161. }
  162. }
  163. return nil
  164. }
  165. func (h *Hooks) executeOnShutdownHooks() {
  166. for _, v := range h.onShutdown {
  167. if err := v(); err != nil {
  168. log.Errorf("failed to call shutdown hook: %v", err)
  169. }
  170. }
  171. }
  172. func (h *Hooks) executeOnForkHooks(pid int) {
  173. for _, v := range h.onFork {
  174. if err := v(pid); err != nil {
  175. log.Errorf("failed to call fork hook: %v", err)
  176. }
  177. }
  178. }
  179. func (h *Hooks) executeOnMountHooks(app *App) error {
  180. for _, v := range h.onMount {
  181. if err := v(app); err != nil {
  182. return err
  183. }
  184. }
  185. return nil
  186. }