From 2ff5698845bb368f70223d6b8038634e7bc30d7e Mon Sep 17 00:00:00 2001 From: John Date: Tue, 13 Mar 2018 17:57:41 +0800 Subject: [PATCH] =?UTF-8?q?ghttp=E5=A2=9E=E5=8A=A0Init&Shut=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=87=BD=E6=95=B0=E6=B3=A8=E5=86=8C=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8Cgmap=E5=A2=9E=E5=8A=A0SetWithDefault=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gmap/int_bool_map.go | 14 +- g/container/gmap/int_int_map.go | 12 ++ g/container/gmap/int_interface_map.go | 12 ++ g/container/gmap/int_string_map.go | 14 +- g/container/gmap/interface_interface_map.go | 14 +- g/container/gmap/string_bool_map.go | 14 +- g/container/gmap/string_int_map.go | 14 +- g/container/gmap/string_interface_map.go | 12 ++ g/container/gmap/string_string_map.go | 12 ++ g/container/gmap/uint_interface_map.go | 14 +- g/frame/gmvc/controller.go | 2 +- g/net/ghttp/http_controller.go | 2 +- g/net/ghttp/http_server.go | 160 ++++++++++++++++---- g/net/ghttp/http_server_domain.go | 26 +++- g/net/ghttp/http_server_handler.go | 35 ++++- g/net/grouter/grouter.go | 4 +- g/util/gregx/regx.go | 2 +- geg/frame/mvc/controller/demo/hook.go | 21 +++ 18 files changed, 337 insertions(+), 47 deletions(-) create mode 100644 geg/frame/mvc/controller/demo/hook.go diff --git a/g/container/gmap/int_bool_map.go b/g/container/gmap/int_bool_map.go index 1ebdce090..a3d9613d3 100644 --- a/g/container/gmap/int_bool_map.go +++ b/g/container/gmap/int_bool_map.go @@ -59,13 +59,25 @@ func (this *IntBoolMap) BatchSet(m map[int]bool) { } // 获取键值 -func (this *IntBoolMap) Get(key int) (bool) { +func (this *IntBoolMap) Get(key int) bool { this.mu.RLock() val, _ := this.m[key] this.mu.RUnlock() return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *IntBoolMap) GetWithDefault(key int, value bool) bool { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + // 删除键值对 func (this *IntBoolMap) Remove(key int) { this.mu.Lock() diff --git a/g/container/gmap/int_int_map.go b/g/container/gmap/int_int_map.go index 08d297535..1563d5bcc 100644 --- a/g/container/gmap/int_int_map.go +++ b/g/container/gmap/int_int_map.go @@ -66,6 +66,18 @@ func (this *IntIntMap) Get(key int) (int) { return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *IntIntMap) GetWithDefault(key int, value int) int { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + // 删除键值对 func (this *IntIntMap) Remove(key int) { this.mu.Lock() diff --git a/g/container/gmap/int_interface_map.go b/g/container/gmap/int_interface_map.go index 300f47cfd..eb395d80d 100644 --- a/g/container/gmap/int_interface_map.go +++ b/g/container/gmap/int_interface_map.go @@ -67,6 +67,18 @@ func (this *IntInterfaceMap) Get(key int) (interface{}) { return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *IntInterfaceMap) GetWithDefault(key int, value interface{}) interface{} { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + func (this *IntInterfaceMap) GetBool(key int) bool { return gconv.Bool(this.Get(key)) } diff --git a/g/container/gmap/int_string_map.go b/g/container/gmap/int_string_map.go index a66db91d9..bab4251d4 100644 --- a/g/container/gmap/int_string_map.go +++ b/g/container/gmap/int_string_map.go @@ -59,13 +59,25 @@ func (this *IntStringMap) BatchSet(m map[int]string) { } // 获取键值 -func (this *IntStringMap) Get(key int) (string) { +func (this *IntStringMap) Get(key int) string { this.mu.RLock() val, _ := this.m[key] this.mu.RUnlock() return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *IntStringMap) GetWithDefault(key int, value string) string { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + // 删除键值对 func (this *IntStringMap) Remove(key int) { this.mu.Lock() diff --git a/g/container/gmap/interface_interface_map.go b/g/container/gmap/interface_interface_map.go index 5d1993922..5d6f1b2c4 100644 --- a/g/container/gmap/interface_interface_map.go +++ b/g/container/gmap/interface_interface_map.go @@ -60,13 +60,25 @@ func (this *InterfaceInterfaceMap) BatchSet(m map[interface{}]interface{}) { } // 获取键值 -func (this *InterfaceInterfaceMap) Get(key interface{}) (interface{}) { +func (this *InterfaceInterfaceMap) Get(key interface{}) interface{} { this.mu.RLock() val, _ := this.m[key] this.mu.RUnlock() return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *InterfaceInterfaceMap) GetWithDefault(key interface{}, value interface{}) interface{} { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + func (this *InterfaceInterfaceMap) GetBool(key interface{}) bool { return gconv.Bool(this.Get(key)) } diff --git a/g/container/gmap/string_bool_map.go b/g/container/gmap/string_bool_map.go index ffc91881c..4a9051674 100644 --- a/g/container/gmap/string_bool_map.go +++ b/g/container/gmap/string_bool_map.go @@ -59,13 +59,25 @@ func (this *StringBoolMap) BatchSet(m map[string]bool) { } // 获取键值 -func (this *StringBoolMap) Get(key string) (bool) { +func (this *StringBoolMap) Get(key string) bool { this.mu.RLock() val, _ := this.m[key] this.mu.RUnlock() return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *StringBoolMap) GetWithDefault(key string, value bool) bool { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + // 删除键值对 func (this *StringBoolMap) Remove(key string) { this.mu.Lock() diff --git a/g/container/gmap/string_int_map.go b/g/container/gmap/string_int_map.go index a31fe4ca2..8a8ed2165 100644 --- a/g/container/gmap/string_int_map.go +++ b/g/container/gmap/string_int_map.go @@ -59,13 +59,25 @@ func (this *StringIntMap) BatchSet(m map[string]int) { } // 获取键值 -func (this *StringIntMap) Get(key string) (int) { +func (this *StringIntMap) Get(key string) int { this.mu.RLock() val, _ := this.m[key] this.mu.RUnlock() return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *StringIntMap) GetWithDefault(key string, value int) int { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + // 删除键值对 func (this *StringIntMap) Remove(key string) { this.mu.Lock() diff --git a/g/container/gmap/string_interface_map.go b/g/container/gmap/string_interface_map.go index ca182b8b1..90779d42a 100644 --- a/g/container/gmap/string_interface_map.go +++ b/g/container/gmap/string_interface_map.go @@ -67,6 +67,18 @@ func (this *StringInterfaceMap) Get(key string) interface{} { return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *StringInterfaceMap) GetWithDefault(key string, value interface{}) interface{} { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + func (this *StringInterfaceMap) GetBool(key string) bool { return gconv.Bool(this.Get(key)) } diff --git a/g/container/gmap/string_string_map.go b/g/container/gmap/string_string_map.go index d6796e432..6e8a07ee6 100644 --- a/g/container/gmap/string_string_map.go +++ b/g/container/gmap/string_string_map.go @@ -66,6 +66,18 @@ func (this *StringStringMap) Get(key string) string { return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *StringStringMap) GetWithDefault(key string, value string) string { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + // 删除键值对 func (this *StringStringMap) Remove(key string) { this.mu.Lock() diff --git a/g/container/gmap/uint_interface_map.go b/g/container/gmap/uint_interface_map.go index 549ea8683..815498c8d 100644 --- a/g/container/gmap/uint_interface_map.go +++ b/g/container/gmap/uint_interface_map.go @@ -59,13 +59,25 @@ func (this *UintInterfaceMap) BatchSet(m map[uint]interface{}) { } // 获取键值 -func (this *UintInterfaceMap) Get(key uint) (interface{}) { +func (this *UintInterfaceMap) Get(key uint) interface{} { this.mu.RLock() val, _ := this.m[key] this.mu.RUnlock() return val } +// 获取键值,如果键值不存在则写入默认值 +func (this *UintInterfaceMap) GetWithDefault(key uint, value interface{}) interface{} { + this.mu.Lock() + val, ok := this.m[key] + if !ok { + this.m[key] = value + val = value + } + this.mu.Unlock() + return val +} + func (this *UintInterfaceMap) GetBool(key uint) bool { return gconv.Bool(this.Get(key)) } diff --git a/g/frame/gmvc/controller.go b/g/frame/gmvc/controller.go index 70e1e7be3..0f9a7ca13 100644 --- a/g/frame/gmvc/controller.go +++ b/g/frame/gmvc/controller.go @@ -32,7 +32,7 @@ func (c *Controller) Init(r *ghttp.Request) { } // 控制器结束请求接口方法 -func (c *Controller) Shut() { +func (c *Controller) Shut(r *ghttp.Request) { } diff --git a/g/net/ghttp/http_controller.go b/g/net/ghttp/http_controller.go index 164d08fe5..6d4871c0d 100644 --- a/g/net/ghttp/http_controller.go +++ b/g/net/ghttp/http_controller.go @@ -10,5 +10,5 @@ package ghttp // 控制器接口 type Controller interface { Init(*Request) - Shut() + Shut(*Request) } diff --git a/g/net/ghttp/http_server.go b/g/net/ghttp/http_server.go index bb1a35030..491610ffa 100644 --- a/g/net/ghttp/http_server.go +++ b/g/net/ghttp/http_server.go @@ -22,6 +22,7 @@ import ( "gitee.com/johng/gf/g/util/gidgen" "gitee.com/johng/gf/g/container/gmap" "gitee.com/johng/gf/g/container/gqueue" + "gitee.com/johng/gf/g/container/glist" ) const ( @@ -33,16 +34,18 @@ const ( // http server结构体 type Server struct { - hmu sync.RWMutex // handlerMap互斥锁 - name string // 服务名称,方便识别 - server http.Server // 底层http server对象 - config ServerConfig // 配置对象 - status int8 // 当前服务器状态(0:未启动,1:运行中) - handlerMap HandlerMap // 所有注册的回调函数 - methodsMap map[string]bool // 所有支持的HTTP Method - idgen *gidgen.Gen // 请求ID生成器 - closeQueue *gqueue.Queue // 请求结束的关闭队列(存放的是需要异步关闭处理的*Request对象) - Router *grouter.Router // 路由管理对象 + hmu sync.RWMutex // handlerMap互斥锁 + name string // 服务名称,方便识别 + server http.Server // 底层http server对象 + config ServerConfig // 配置对象 + status int8 // 当前服务器状态(0:未启动,1:运行中) + handlerMap HandlerMap // 所有注册的回调函数 + methodsMap map[string]bool // 所有支持的HTTP Method(初始化时自动填充) + idgen *gidgen.Gen // 请求ID生成器 + closeQueue *gqueue.Queue // 请求结束的关闭队列(存放的是需要异步关闭处理的*Request对象) + initHookMap *gmap.StringInterfaceMap // Init钩子注册方法map,键值为按照注册顺序生成的glist,用于hook顺序调用 + shutHookMap *gmap.StringInterfaceMap // Shut钩子注册方法map,键值为按照注册顺序生成的glist,用于hook顺序调用 + Router *grouter.Router // 路由管理对象 } // 域名、URI与回调函数的绑定记录表 @@ -72,12 +75,14 @@ func GetServer(names...string) (*Server) { return s.(*Server) } s := &Server{ - name : name, - handlerMap : make(HandlerMap), - methodsMap : make(map[string]bool), - idgen : gidgen.New(50000), - closeQueue : gqueue.New(), - Router : grouter.New(), + name : name, + handlerMap : make(HandlerMap), + methodsMap : make(map[string]bool), + idgen : gidgen.New(50000), + closeQueue : gqueue.New(), + initHookMap : gmap.NewStringInterfaceMap(), + shutHookMap : gmap.NewStringInterfaceMap(), + Router : grouter.New(), } for _, v := range strings.Split(gHTTP_METHODS, ",") { s.methodsMap[v] = true @@ -259,15 +264,15 @@ func (s *Server) handlerKey(domain, method, pattern string) string { } // 设置请求处理方法 -func (s *Server) setHandler(domain, method, pattern string, hitem HandlerItem) { +func (s *Server) setHandler(domain, method, pattern string, item HandlerItem) { s.hmu.Lock() defer s.hmu.Unlock() if method == gDEFAULT_METHOD { for v, _ := range s.methodsMap { - s.handlerMap[s.handlerKey(domain, v, pattern)] = hitem + s.handlerMap[s.handlerKey(domain, v, pattern)] = item } } else { - s.handlerMap[s.handlerKey(domain, method, pattern)] = hitem + s.handlerMap[s.handlerKey(domain, method, pattern)] = item } } @@ -283,16 +288,11 @@ func (s *Server) getHandler(domain, method, pattern string) *HandlerItem { return nil } -// 绑定URI到操作函数/方法 -// pattern的格式形如:/user/list, put:/user, delete:/user, post:/user@johng.cn -// 支持RESTful的请求格式,具体业务逻辑由绑定的处理方法来执行 -func (s *Server)bindHandlerItem(pattern string, hitem HandlerItem) error { - if s.status == 1 { - return errors.New("server handlers cannot be changed while running") - } - uri := "" - domain := gDEFAULT_DOMAIN - method := "all" +// 解析pattern +func (s *Server)parsePattern(pattern string) (domain, method, uri string, err error) { + uri = "" + domain = gDEFAULT_DOMAIN + method = "all" result := strings.Split(pattern, "@") if len(result) > 1 { domain = result[1] @@ -305,9 +305,23 @@ func (s *Server)bindHandlerItem(pattern string, hitem HandlerItem) error { uri = result[0] } if uri == "" { + err = errors.New("invalid pattern") + } + return +} + +// 绑定URI到操作函数/方法 +// pattern的格式形如:/user/list, put:/user, delete:/user, post:/user@johng.cn +// 支持RESTful的请求格式,具体业务逻辑由绑定的处理方法来执行 +func (s *Server)bindHandlerItem(pattern string, item HandlerItem) error { + if s.status == 1 { + return errors.New("server handlers cannot be changed while running") + } + domain, method, uri, err := s.parsePattern(pattern) + if err != nil { return errors.New("invalid pattern") } - s.setHandler(domain, method, uri, hitem) + s.setHandler(domain, method, uri, item) return nil } @@ -362,7 +376,7 @@ func (s *Server)BindObject(pattern string, obj interface{}) error { } // 绑定对象到URI请求处理中,会自动识别方法名称,并附加到对应的URI地址后面 -// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔 +// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔,不区分大小写 func (s *Server)BindObjectMethod(pattern string, obj interface{}, methods string) error { m := make(HandlerMap) for _, v := range strings.Split(methods, ",") { @@ -440,7 +454,7 @@ func (s *Server)BindControllerRest(pattern string, c Controller) error { } // 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话 -// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔 +// 第三个参数methods支持多个方法注册,多个方法以英文“,”号分隔,不区分大小写 func (s *Server)BindControllerMethod(pattern string, c Controller, methods string) error { m := make(HandlerMap) cval := reflect.ValueOf(c) @@ -455,3 +469,85 @@ func (s *Server)BindControllerMethod(pattern string, c Controller, methods strin } return s.bindHandlerByMap(m) } + +// 绑定URI服务注册的Init回调函数,回调时按照注册顺序执行 +// Init回调调用时机为请求进入控制器之前,初始化Request对象之后 +func (s *Server)BindHookHandlerInit(pattern string, handler HandlerFunc) error { + domain, method, uri, err := s.parsePattern(pattern) + if err != nil { + return errors.New("invalid pattern") + } + var l *glist.List + if method == gDEFAULT_METHOD { + for v, _ := range s.methodsMap { + key := s.handlerKey(domain, v, uri) + if v := s.initHookMap.GetWithDefault(key, glist.New()); v != nil { + l = v.(*glist.List) + } + l.PushBack(handler) + } + } else { + key := s.handlerKey(domain, method, uri) + if v := s.initHookMap.GetWithDefault(key, glist.New()); v == nil { + l = v.(*glist.List) + } + l.PushBack(handler) + } + return nil +} + +// 绑定URI服务注册的Shut回调函数,回调时按照注册顺序执行 +// Shut回调调用时机为请求执行完成之后,所有的请求资源释放之前 +func (s *Server)BindHookHandlerShut(pattern string, handler HandlerFunc) error { + domain, method, uri, err := s.parsePattern(pattern) + if err != nil { + return errors.New("invalid pattern") + } + var l *glist.List + if method == gDEFAULT_METHOD { + for v, _ := range s.methodsMap { + key := s.handlerKey(domain, v, uri) + if v := s.shutHookMap.GetWithDefault(key, glist.New()); v != nil { + l = v.(*glist.List) + } + l.PushBack(handler) + } + } else { + key := s.handlerKey(domain, method, uri) + if v := s.shutHookMap.GetWithDefault(key, glist.New()); v != nil { + l = v.(*glist.List) + } + l.PushBack(handler) + } + return nil +} + +// 获取Init回调函数列表,按照注册顺序排序 +func (s *Server)getInitHookList(domain, method, uri string) []HandlerFunc { + key := s.handlerKey(domain, method, uri) + if v := s.initHookMap.Get(key); v != nil { + items := v.(*glist.List).FrontAll() + funcs := make([]HandlerFunc, len(items)) + for k, v := range items { + funcs[k] = v.(HandlerFunc) + } + return funcs + } + return nil +} + +// 获取Shut回调函数列表,按照注册顺序排序 +func (s *Server)getShutHookList(domain, method, uri string) []HandlerFunc { + key := s.handlerKey(domain, method, uri) + if v := s.shutHookMap.Get(key); v != nil { + items := v.(*glist.List).FrontAll() + funcs := make([]HandlerFunc, len(items)) + for k, v := range items { + funcs[k] = v.(HandlerFunc) + } + return funcs + } + return nil +} + + diff --git a/g/net/ghttp/http_server_domain.go b/g/net/ghttp/http_server_domain.go index 1d80cfdf8..51d24054a 100644 --- a/g/net/ghttp/http_server_domain.go +++ b/g/net/ghttp/http_server_domain.go @@ -58,7 +58,7 @@ func (d *Domain) BindObject(pattern string, obj interface{}) error { return nil } -// 执行对象方法注册 +// 执行对象方法注册,methods参数不区分大小写 func (d *Domain) BindObjectMethod(pattern string, obj interface{}, methods string) error { for domain, _ := range d.m { if err := d.s.BindObjectMethod(pattern + "@" + domain, obj, methods); err != nil { @@ -98,7 +98,7 @@ func (d *Domain) BindControllerRest(pattern string, c Controller) error { return nil } -// 控制器方法注册 +// 控制器方法注册,methods参数不区分大小写 func (d *Domain) BindControllerMethod(pattern string, c Controller, methods string) error { for domain, _ := range d.m { if err := d.s.BindControllerMethod(pattern + "@" + domain, c, methods); err != nil { @@ -107,3 +107,25 @@ func (d *Domain) BindControllerMethod(pattern string, c Controller, methods stri } return nil } + +// 绑定URI服务注册的Init回调函数,回调时按照注册顺序执行 +// Init回调调用时机为请求进入控制器之前,初始化Request对象之后 +func (d *Domain)BindHookHandlerInit(pattern string, handler HandlerFunc) error { + for domain, _ := range d.m { + if err := d.s.BindHookHandlerInit(pattern + "@" + domain, handler); err != nil { + return err + } + } + return nil +} + +// 绑定URI服务注册的Shut回调函数,回调时按照注册顺序执行 +// Shut回调调用时机为请求执行完成之后,所有的请求资源释放之前 +func (d *Domain)BindHookHandlerShut(pattern string, handler HandlerFunc) error { + for domain, _ := range d.m { + if err := d.s.BindHookHandlerShut(pattern + "@" + domain, handler); err != nil { + return err + } + } + return nil +} \ No newline at end of file diff --git a/g/net/ghttp/http_server_handler.go b/g/net/ghttp/http_server_handler.go index 13d6ff5f1..605f227e6 100644 --- a/g/net/ghttp/http_server_handler.go +++ b/g/net/ghttp/http_server_handler.go @@ -68,10 +68,11 @@ func (s *Server)callHandler(h *HandlerItem, r *Request) { c := reflect.New(h.ctype) c.MethodByName("Init").Call([]reflect.Value{reflect.ValueOf(r)}) c.MethodByName(h.fname).Call(nil) - c.MethodByName("Shut").Call(nil) + c.MethodByName("Shut").Call([]reflect.Value{reflect.ValueOf(r)}) } else { - // 直接调用注册的方法处理请求 + s.callHookHandlerInit(r) h.faddr(r) + s.callHookHandlerShut(r) } // 路由规则打包 if buffer, err := s.Router.Patch(r.Response.Buffer()); err == nil { @@ -89,6 +90,36 @@ func (s *Server)callHandler(h *HandlerItem, r *Request) { s.closeQueue.PushBack(r) } +// 按照Init回调函数的注册顺序进行调用 +func (s *Server)callHookHandlerInit(r *Request) { + var l []HandlerFunc + l = s.getInitHookList(gDEFAULT_DOMAIN, r.Method, r.URL.Path) + if l == nil { + l = s.getInitHookList(strings.Split(r.Host, ":")[0], r.Method, r.URL.Path) + } + if l == nil { + return + } + for _, f := range l { + f(r) + } +} + +// 按照Shut回调函数的注册顺序进行调用 +func (s *Server)callHookHandlerShut(r *Request) { + var l []HandlerFunc + l = s.getShutHookList(gDEFAULT_DOMAIN, r.Method, r.URL.Path) + if l == nil { + l = s.getShutHookList(strings.Split(r.Host, ":")[0], r.Method, r.URL.Path) + } + if l == nil { + return + } + for _, f := range l { + f(r) + } +} + // 处理静态文件请求 func (s *Server)serveFile(w http.ResponseWriter, r *http.Request) { uri := r.URL.String() diff --git a/g/net/grouter/grouter.go b/g/net/grouter/grouter.go index df195e54f..aae76d273 100644 --- a/g/net/grouter/grouter.go +++ b/g/net/grouter/grouter.go @@ -86,7 +86,7 @@ func (r *Router) Dispatch(uri string) (string, error) { } for _, rule := range r.dkeys { if replace := r.drules.Get(rule); replace != "" { - result, err := gregx.ReplaceString(rule, uri, replace) + result, err := gregx.ReplaceString(rule, replace, uri) if err != nil { return result, err } @@ -107,7 +107,7 @@ func (r *Router) Patch(content []byte) ([]byte, error) { } for _, rule := range r.pkeys { if replace := r.prules.Get(rule); replace != "" { - result, err := gregx.Replace(rule, content, []byte(replace)) + result, err := gregx.Replace(rule, []byte(replace), content) if err != nil { return result, err } diff --git a/g/util/gregx/regx.go b/g/util/gregx/regx.go index 3fe855ea9..42ad695f7 100644 --- a/g/util/gregx/regx.go +++ b/g/util/gregx/regx.go @@ -54,6 +54,6 @@ func Replace(pattern string, replace, src []byte) ([]byte, error) { // 正则替换(全部替换),字符串 func ReplaceString(pattern, replace, src string) (string, error) { - r, e := Replace(pattern, []byte(src), []byte(replace)) + r, e := Replace(pattern, []byte(replace), []byte(src)) return string(r), e } \ No newline at end of file diff --git a/geg/frame/mvc/controller/demo/hook.go b/geg/frame/mvc/controller/demo/hook.go new file mode 100644 index 000000000..d7886b8ee --- /dev/null +++ b/geg/frame/mvc/controller/demo/hook.go @@ -0,0 +1,21 @@ +package demo + +import "gitee.com/johng/gf/g/net/ghttp" + +func init() { + ghttp.GetServer().BindHandler("/hook", func(r *ghttp.Request){ + r.Response.WriteString("This is hook content!\n") + }) + ghttp.GetServer().BindHookHandlerInit("/hook", func(r *ghttp.Request){ + r.Response.WriteString("Init hook 1!\n") + }) + ghttp.GetServer().BindHookHandlerInit("/hook", func(r *ghttp.Request){ + r.Response.WriteString("Init hook 2!\n") + }) + ghttp.GetServer().BindHookHandlerShut("/hook", func(r *ghttp.Request){ + r.Response.WriteString("Shut hook 1!\n") + }) + ghttp.GetServer().BindHookHandlerShut("/hook", func(r *ghttp.Request){ + r.Response.WriteString("Shut hook 2!\n") + }) +} \ No newline at end of file