improve routerMap handling for ghttp.Request

This commit is contained in:
John
2019-12-03 17:16:52 +08:00
parent 6af90cafee
commit 890865251b
7 changed files with 25 additions and 41 deletions

View File

@ -37,7 +37,7 @@ type Request struct {
parsedBody bool // A bool marking whether the request body parsed.
parsedForm bool // A bool marking whether request Form parsed for HTTP method PUT, POST, PATCH.
paramsMap map[string]interface{} // Custom parameters.
routerMap map[string]interface{} // Router parameters map, which might be nil if there're no router parameters.
routerMap map[string]string // Router parameters map, which might be nil if there're no router parameters.
queryMap map[string]interface{} // Query parameters map, which is nil if there's no query string.
formMap map[string]interface{} // Form parameters map, which is nil if there's no form data from client.
bodyMap map[string]interface{} // Body parameters map, which might be nil if there're no body content.
@ -54,7 +54,6 @@ type Request struct {
// newRequest creates and returns a new request object.
func newRequest(s *Server, r *http.Request, w http.ResponseWriter) *Request {
request := &Request{
routerMap: make(map[string]interface{}),
Server: s,
Request: r,
Response: newResponse(s, w),

View File

@ -15,7 +15,7 @@ import (
"github.com/gogf/gf/util/gutil"
)
// Middleware is the plugin for request handling.
// Middleware is the plugin for request workflow management.
type Middleware struct {
served bool // Is the request served, which is used for checking response status 404.
request *Request // The request object pointer.
@ -37,9 +37,8 @@ func (m *Middleware) Next() {
continue
}
// Router values switching.
for k, v := range item.values {
m.request.routerMap[k] = v
}
m.request.routerMap = item.values
// Current router switching.
m.request.Router = item.handler.router
gutil.TryCatch(func() {

View File

@ -8,11 +8,8 @@ package ghttp
import "github.com/gogf/gf/container/gvar"
func (r *Request) SetRouterValue(key string, value interface{}) {
r.routerMap[key] = value
}
// 获得路由解析参数
// GetRouterValue retrieves and returns the router value with given key name <key>.
// It returns <def> if <key> does not exist.
func (r *Request) GetRouterValue(key string, def ...interface{}) interface{} {
if r.routerMap != nil {
return r.routerMap[key]
@ -23,11 +20,14 @@ func (r *Request) GetRouterValue(key string, def ...interface{}) interface{} {
return nil
}
// 获得路由解析参数
// GetRouterVar retrieves and returns the router value as *gvar.var with given key name <key>.
// It returns <def> if <key> does not exist.
func (r *Request) GetRouterVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetRouterValue(key, def...))
}
// GetRouterString retrieves and returns the router value as string with given key name <key>.
// It returns <def> if <key> does not exist.
func (r *Request) GetRouterString(key string, def ...interface{}) string {
return r.GetRouterVar(key, def...).String()
}

View File

@ -102,12 +102,12 @@ type (
)
const (
SERVER_STATUS_STOPPED = 0 // Server状态停止
SERVER_STATUS_RUNNING = 1 // Server状态运行
HOOK_BEFORE_SERVE = "HOOK_BEFORE_SERVE" // 回调事件,在执行服务前
HOOK_AFTER_SERVE = "HOOK_AFTER_SERVE" // 回调事件,在执行服务后
HOOK_BEFORE_OUTPUT = "HOOK_BEFORE_OUTPUT" // 回调事件,在输出结果前
HOOK_AFTER_OUTPUT = "HOOK_AFTER_OUTPUT" // 回调事件,在输出结果后
SERVER_STATUS_STOPPED = 0
SERVER_STATUS_RUNNING = 1
HOOK_BEFORE_SERVE = "HOOK_BEFORE_SERVE"
HOOK_AFTER_SERVE = "HOOK_AFTER_SERVE"
HOOK_BEFORE_OUTPUT = "HOOK_BEFORE_OUTPUT"
HOOK_AFTER_OUTPUT = "HOOK_AFTER_OUTPUT"
HTTP_METHODS = "GET,PUT,POST,DELETE,PATCH,HEAD,CONNECT,OPTIONS,TRACE"
gDEFAULT_SERVER = "default"
gDEFAULT_DOMAIN = "default"

View File

@ -63,11 +63,11 @@ func (s *Server) setHandler(pattern string, handler *handlerItem) {
handler.itemId = handlerIdGenerator.Add(1)
domain, method, uri, err := s.parsePattern(pattern)
if err != nil {
glog.Error("invalid pattern:", pattern, err)
glog.Fatal("invalid pattern:", pattern, err)
return
}
if len(uri) == 0 || uri[0] != '/' {
glog.Error("invalid pattern:", pattern, "URI should lead with '/'")
glog.Fatal("invalid pattern:", pattern, "URI should lead with '/'")
return
}
// 注册地址记录及重复注册判断
@ -75,7 +75,7 @@ func (s *Server) setHandler(pattern string, handler *handlerItem) {
switch handler.itemType {
case gHANDLER_TYPE_HANDLER, gHANDLER_TYPE_OBJECT, gHANDLER_TYPE_CONTROLLER:
if item, ok := s.routesMap[regKey]; ok {
glog.Errorf(`duplicated route registry "%s", already registered at %s`, pattern, item[0].file)
glog.Fatalf(`duplicated route registry "%s", already registered at %s`, pattern, item[0].file)
return
}
}
@ -237,6 +237,8 @@ func (s *Server) compareRouterPriority(newItem *handlerItem, oldItem *handlerIte
}
/** 比较路由规则长度,越长的规则优先级越高,模糊/命名规则不算长度 **/
// 例如:/admin-goods-{page} 比 /admin-{page} 优先级高
var uriNew, uriOld string
uriNew, _ = gregex.ReplaceString(`\{[^/]+\}`, "", newItem.router.Uri)
uriNew, _ = gregex.ReplaceString(`:[^/]+`, "", uriNew)

View File

@ -35,22 +35,9 @@ func (s *Server) callHookHandler(hook string, r *Request) {
hookItems := r.getHookHandlers(hook)
if len(hookItems) > 0 {
// 备份原有的router变量
oldRouterVars := r.routerMap
oldRouterMap := r.routerMap
for _, item := range hookItems {
// hook方法不能更改serve方法的路由参数其匹配的路由参数只能自己使用
// 且在多个hook方法之间不能共享路由参数单可以使用匹配的serve方法路由参数。
// 当前回调函数的路由参数只在当前回调函数下有效。
r.routerMap = make(map[string]interface{})
if len(oldRouterVars) > 0 {
for k, v := range oldRouterVars {
r.routerMap[k] = v
}
}
if len(item.values) > 0 {
for k, v := range item.values {
r.routerMap[k] = v
}
}
r.routerMap = item.values
// 不使用hook的router对象保留路由注册服务的router对象不能覆盖
// r.Router = item.handler.router
if err := s.niceCallHookHandler(item.handler.itemFunc, r); err != nil {
@ -68,7 +55,7 @@ func (s *Server) callHookHandler(hook string, r *Request) {
}
}
// 恢复原有的router变量
r.routerMap = oldRouterVars
r.routerMap = oldRouterMap
}
}

View File

@ -30,7 +30,6 @@ func (s *Server) getHandlersWithCache(r *Request) (parsedItems []*handlerParsedI
if parsedItems != nil {
return &handlerCacheItem{parsedItems, hasHook, hasServe}
}
//intlog.Printf("cannot find HTTP handler for: %s, %s, %s", r.Method, r.URL.Path, r.GetHost())
return nil
}, gROUTE_CACHE_DURATION)
if value != nil {
@ -109,9 +108,7 @@ func (s *Server) searchHandlers(method, path, domain string) (parsedItems []*han
// 服务路由函数只能添加一次,将重复判断放在这里提高检索效率
if hasServe {
switch item.itemType {
case gHANDLER_TYPE_HANDLER,
gHANDLER_TYPE_OBJECT,
gHANDLER_TYPE_CONTROLLER:
case gHANDLER_TYPE_HANDLER, gHANDLER_TYPE_OBJECT, gHANDLER_TYPE_CONTROLLER:
continue
}
}