gf/net/ghttp/ghttp_server_router_hook.go

90 lines
2.5 KiB
Go
Raw Normal View History

// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package ghttp
import (
"github.com/gogf/gf/debug/gdebug"
"net/http"
)
// 绑定指定的hook回调函数, pattern参数同BindHandler支持命名路由hook参数的值由ghttp server设定参数不区分大小写
2019-06-19 09:06:52 +08:00
func (s *Server) BindHookHandler(pattern string, hook string, handler HandlerFunc) {
s.doBindHookHandler(pattern, hook, handler, "")
}
func (s *Server) doBindHookHandler(pattern string, hook string, handler HandlerFunc, source string) {
2019-06-19 09:06:52 +08:00
s.setHandler(pattern, &handlerItem{
itemType: gHANDLER_TYPE_HOOK,
itemName: gdebug.FuncPath(handler),
itemFunc: handler,
hookName: hook,
source: source,
})
}
// 通过map批量绑定回调函数
func (s *Server) BindHookHandlerByMap(pattern string, hookMap map[string]HandlerFunc) {
for k, v := range hookMap {
2019-06-19 09:06:52 +08:00
s.BindHookHandler(pattern, k, v)
}
}
// 事件回调处理,内部使用了缓存处理.
// 并按照指定hook回调函数的优先级及注册顺序进行调用
func (s *Server) callHookHandler(hook string, r *Request) {
hookItems := r.getHookHandlers(hook)
2019-06-19 09:06:52 +08:00
if len(hookItems) > 0 {
// 备份原有的router变量
oldRouterMap := r.routerMap
2019-06-19 09:06:52 +08:00
for _, item := range hookItems {
r.routerMap = item.values
2019-06-19 09:06:52 +08:00
// 不使用hook的router对象保留路由注册服务的router对象不能覆盖
// r.Router = item.handler.router
if err := s.niceCallHookHandler(item.handler.itemFunc, r); err != nil {
2019-06-19 09:06:52 +08:00
switch err {
case gEXCEPTION_EXIT:
break
case gEXCEPTION_EXIT_ALL:
fallthrough
case gEXCEPTION_EXIT_HOOK:
return
default:
r.Response.WriteStatus(http.StatusInternalServerError, err)
2019-06-19 09:06:52 +08:00
panic(err)
}
}
}
// 恢复原有的router变量
r.routerMap = oldRouterMap
2019-06-19 09:06:52 +08:00
}
}
2020-04-06 22:31:45 +08:00
// 获得当前请求,指定类型的的钩子函数列表
func (r *Request) getHookHandlers(hook string) []*handlerParsedItem {
if !r.hasHookHandler {
return nil
}
parsedItems := make([]*handlerParsedItem, 0, 4)
for _, v := range r.handlers {
if v.handler.hookName != hook {
continue
}
item := v
parsedItems = append(parsedItems, item)
}
return parsedItems
}
// 友好地调用方法
func (s *Server) niceCallHookHandler(f HandlerFunc, r *Request) (err interface{}) {
2019-06-19 09:06:52 +08:00
defer func() {
err = recover()
}()
f(r)
return
}