gf/net/ghttp/ghttp_server_router_hook.go
2020-04-06 22:31:45 +08:00

90 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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设定参数不区分大小写
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) {
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 {
s.BindHookHandler(pattern, k, v)
}
}
// 事件回调处理,内部使用了缓存处理.
// 并按照指定hook回调函数的优先级及注册顺序进行调用
func (s *Server) callHookHandler(hook string, r *Request) {
hookItems := r.getHookHandlers(hook)
if len(hookItems) > 0 {
// 备份原有的router变量
oldRouterMap := r.routerMap
for _, item := range hookItems {
r.routerMap = item.values
// 不使用hook的router对象保留路由注册服务的router对象不能覆盖
// r.Router = item.handler.router
if err := s.niceCallHookHandler(item.handler.itemFunc, r); err != nil {
switch err {
case gEXCEPTION_EXIT:
break
case gEXCEPTION_EXIT_ALL:
fallthrough
case gEXCEPTION_EXIT_HOOK:
return
default:
r.Response.WriteStatus(http.StatusInternalServerError, err)
panic(err)
}
}
}
// 恢复原有的router变量
r.routerMap = oldRouterMap
}
}
// 获得当前请求,指定类型的的钩子函数列表
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{}) {
defer func() {
err = recover()
}()
f(r)
return
}