2019-02-02 16:18:25 +08:00
|
|
|
|
// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
2018-07-31 21:05:02 +08:00
|
|
|
|
//
|
|
|
|
|
|
// 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,
|
2019-02-02 16:18:25 +08:00
|
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2018-07-31 21:05:02 +08:00
|
|
|
|
|
|
|
|
|
|
package ghttp
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2019-06-19 09:06:52 +08:00
|
|
|
|
"bytes"
|
2019-12-04 10:03:03 +08:00
|
|
|
|
"github.com/gogf/gf/debug/gdebug"
|
2019-06-19 09:06:52 +08:00
|
|
|
|
"strings"
|
2019-07-29 21:01:19 +08:00
|
|
|
|
|
|
|
|
|
|
"github.com/gogf/gf/text/gstr"
|
2018-07-31 21:05:02 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 注意该方法是直接绑定函数的内存地址,执行的时候直接执行该方法,不会存在初始化新的控制器逻辑
|
2019-03-06 15:21:00 +08:00
|
|
|
|
func (s *Server) BindHandler(pattern string, handler HandlerFunc) {
|
2019-12-04 10:03:03 +08:00
|
|
|
|
s.doBindHandler(pattern, handler, nil)
|
2018-07-31 21:05:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 绑定URI到操作函数/方法
|
|
|
|
|
|
// pattern的格式形如:/user/list, put:/user, delete:/user, post:/user@johng.cn
|
|
|
|
|
|
// 支持RESTful的请求格式,具体业务逻辑由绑定的处理方法来执行
|
2019-12-04 10:03:03 +08:00
|
|
|
|
func (s *Server) doBindHandler(pattern string, handler HandlerFunc, middleware []HandlerFunc) {
|
|
|
|
|
|
s.setHandler(pattern, &handlerItem{
|
|
|
|
|
|
itemName: gdebug.FuncPath(handler),
|
|
|
|
|
|
itemType: gHANDLER_TYPE_HANDLER,
|
|
|
|
|
|
itemFunc: handler,
|
|
|
|
|
|
middleware: middleware,
|
|
|
|
|
|
})
|
2018-07-31 21:05:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-12-04 13:55:08 +08:00
|
|
|
|
// 通过映射map绑定URI到操作函数/方法
|
2020-01-21 17:18:03 +08:00
|
|
|
|
func (s *Server) bindHandlerByMap(m map[string]*handlerItem) {
|
2019-06-19 09:06:52 +08:00
|
|
|
|
for p, h := range m {
|
2019-12-04 10:03:03 +08:00
|
|
|
|
s.setHandler(p, h)
|
2019-06-19 09:06:52 +08:00
|
|
|
|
}
|
2018-07-31 21:05:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 将内置的名称按照设定的规则合并到pattern中,内置名称按照{.xxx}规则命名。
|
|
|
|
|
|
// 规则1:pattern中的URI包含{.struct}关键字,则替换该关键字为结构体名称;
|
2019-03-01 23:45:55 +08:00
|
|
|
|
// 规则2:pattern中的URI包含{.method}关键字,则替换该关键字为方法名称;
|
2018-07-31 21:05:02 +08:00
|
|
|
|
// 规则2:如果不满足规则1,那么直接将防发明附加到pattern中的URI后面;
|
2018-08-16 21:33:47 +08:00
|
|
|
|
func (s *Server) mergeBuildInNameToPattern(pattern string, structName, methodName string, allowAppend bool) string {
|
2019-12-04 10:03:03 +08:00
|
|
|
|
structName = s.nameToUri(structName)
|
|
|
|
|
|
methodName = s.nameToUri(methodName)
|
2019-06-19 09:06:52 +08:00
|
|
|
|
pattern = strings.Replace(pattern, "{.struct}", structName, -1)
|
|
|
|
|
|
if strings.Index(pattern, "{.method}") != -1 {
|
|
|
|
|
|
return strings.Replace(pattern, "{.method}", methodName, -1)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 不允许将方法名称append到路由末尾
|
|
|
|
|
|
if !allowAppend {
|
|
|
|
|
|
return pattern
|
|
|
|
|
|
}
|
|
|
|
|
|
// 检测域名后缀
|
|
|
|
|
|
array := strings.Split(pattern, "@")
|
|
|
|
|
|
// 分离URI(其实可能包含HTTP Method)
|
|
|
|
|
|
uri := array[0]
|
|
|
|
|
|
uri = strings.TrimRight(uri, "/") + "/" + methodName
|
|
|
|
|
|
// 加上指定域名后缀
|
|
|
|
|
|
if len(array) > 1 {
|
|
|
|
|
|
return uri + "@" + array[1]
|
|
|
|
|
|
}
|
|
|
|
|
|
return uri
|
2018-07-31 21:05:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 将给定的名称转换为URL规范格式。
|
2018-08-12 12:22:02 +08:00
|
|
|
|
// 规则0: 全部转换为小写,方法名中间存在大写字母,转换为小写URI地址以“-”号链接每个单词;
|
|
|
|
|
|
// 规则1: 不处理名称,以原有名称构建成URI
|
|
|
|
|
|
// 规则2: 仅转为小写,单词间不使用连接符号
|
2018-08-12 12:36:02 +08:00
|
|
|
|
// 规则3: 采用驼峰命名方式
|
2019-12-04 10:03:03 +08:00
|
|
|
|
func (s *Server) nameToUri(name string) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
|
switch s.config.NameToUriType {
|
2019-09-23 19:25:03 +08:00
|
|
|
|
case URI_TYPE_FULLNAME:
|
2019-06-19 09:06:52 +08:00
|
|
|
|
return name
|
2018-08-12 12:36:02 +08:00
|
|
|
|
|
2019-09-23 19:25:03 +08:00
|
|
|
|
case URI_TYPE_ALLLOWER:
|
2019-06-19 09:06:52 +08:00
|
|
|
|
return strings.ToLower(name)
|
2018-08-12 12:36:02 +08:00
|
|
|
|
|
2019-09-23 19:25:03 +08:00
|
|
|
|
case URI_TYPE_CAMEL:
|
2019-06-19 09:06:52 +08:00
|
|
|
|
part := bytes.NewBuffer(nil)
|
|
|
|
|
|
if gstr.IsLetterUpper(name[0]) {
|
|
|
|
|
|
part.WriteByte(name[0] + 32)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
part.WriteByte(name[0])
|
|
|
|
|
|
}
|
|
|
|
|
|
part.WriteString(name[1:])
|
|
|
|
|
|
return part.String()
|
2018-08-12 12:36:02 +08:00
|
|
|
|
|
2019-09-23 19:25:03 +08:00
|
|
|
|
case URI_TYPE_DEFAULT:
|
2019-06-19 09:06:52 +08:00
|
|
|
|
fallthrough
|
|
|
|
|
|
default:
|
|
|
|
|
|
part := bytes.NewBuffer(nil)
|
|
|
|
|
|
for i := 0; i < len(name); i++ {
|
|
|
|
|
|
if i > 0 && gstr.IsLetterUpper(name[i]) {
|
|
|
|
|
|
part.WriteByte('-')
|
|
|
|
|
|
}
|
|
|
|
|
|
if gstr.IsLetterUpper(name[i]) {
|
|
|
|
|
|
part.WriteByte(name[i] + 32)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
part.WriteByte(name[i])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return part.String()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|