gf/net/ghttp/ghttp_server_service_handler.go

113 lines
3.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 (
"bytes"
"reflect"
"runtime"
"strings"
"github.com/gogf/gf/os/glog"
"github.com/gogf/gf/text/gstr"
)
// 注意该方法是直接绑定函数的内存地址,执行的时候直接执行该方法,不会存在初始化新的控制器逻辑
func (s *Server) BindHandler(pattern string, handler HandlerFunc) {
s.bindHandlerItem(pattern, &handlerItem{
itemName: runtime.FuncForPC(reflect.ValueOf(handler).Pointer()).Name(),
itemType: gHANDLER_TYPE_HANDLER,
itemFunc: handler,
})
}
// 绑定URI到操作函数/方法
// pattern的格式形如/user/list, put:/user, delete:/user, post:/user@johng.cn
// 支持RESTful的请求格式具体业务逻辑由绑定的处理方法来执行
func (s *Server) bindHandlerItem(pattern string, item *handlerItem) {
if s.Status() == SERVER_STATUS_RUNNING {
glog.Error("server handlers cannot be changed while running")
return
}
s.setHandler(pattern, item)
}
// 通过映射数组绑定URI到操作函数/方法
func (s *Server) bindHandlerByMap(m handlerMap) {
for p, h := range m {
s.bindHandlerItem(p, h)
}
}
// 将内置的名称按照设定的规则合并到pattern中内置名称按照{.xxx}规则命名。
// 规则1pattern中的URI包含{.struct}关键字,则替换该关键字为结构体名称;
// 规则2pattern中的URI包含{.method}关键字,则替换该关键字为方法名称;
// 规则2如果不满足规则1那么直接将防发明附加到pattern中的URI后面
func (s *Server) mergeBuildInNameToPattern(pattern string, structName, methodName string, allowAppend bool) string {
structName = s.nameToUrlPart(structName)
methodName = s.nameToUrlPart(methodName)
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
}
// 将给定的名称转换为URL规范格式。
// 规则0: 全部转换为小写方法名中间存在大写字母转换为小写URI地址以“-”号链接每个单词;
// 规则1: 不处理名称以原有名称构建成URI
// 规则2: 仅转为小写,单词间不使用连接符号
// 规则3: 采用驼峰命名方式
func (s *Server) nameToUrlPart(name string) string {
switch s.config.NameToUriType {
case NAME_TO_URI_TYPE_FULLNAME:
return name
case NAME_TO_URI_TYPE_ALLLOWER:
return strings.ToLower(name)
case NAME_TO_URI_TYPE_CAMEL:
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()
case NAME_TO_URI_TYPE_DEFAULT:
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()
}
}