gf/g/net/ghttp/http_server.go

295 lines
8.5 KiB
Go
Raw Normal View History

2017-11-23 10:21:28 +08:00
package ghttp
import (
"net/http"
"strings"
"path/filepath"
"crypto/tls"
"time"
"log"
2017-12-07 14:57:16 +08:00
"sync"
"errors"
2017-12-08 12:03:21 +08:00
"gitee.com/johng/gf/g/container/gmap"
2017-11-23 10:21:28 +08:00
)
const (
gDEFAULT_DOMAIN = "default"
gDEFAULT_METHOD = "all"
)
2017-12-07 14:57:16 +08:00
// http server结构体
type Server struct {
hmu sync.RWMutex // handlerMap互斥锁
2017-12-08 12:03:21 +08:00
name string // 服务名称,方便识别
2017-12-07 14:57:16 +08:00
server http.Server // 底层http server对象
config ServerConfig // 配置对象
handlerMap HandlerMap // 回调函数
2017-12-07 17:34:51 +08:00
status int8 // 当前服务器状态(0未启动1运行中)
2017-12-07 14:57:16 +08:00
}
// 域名、URI与回调函数的绑定记录表
type HandlerMap map[string]HandlerFunc
2017-12-07 14:57:16 +08:00
// http回调函数
type HandlerFunc func(*ClientRequest, *ServerResponse)
2017-12-08 12:03:21 +08:00
// Server表用以存储和检索名称与Server对象之间的关联关系
var serverMapping *gmap.StringInterfaceMap = gmap.NewStringInterfaceMap()
2017-12-07 17:34:51 +08:00
2017-12-07 14:57:16 +08:00
// 创建一个默认配置的HTTP Server(默认监听端口是80)
2017-12-07 17:34:51 +08:00
func GetServer(name string) (*Server) {
2017-12-08 12:03:21 +08:00
if s := serverMapping.Get(name); s != nil {
return s.(*Server)
2017-12-07 17:34:51 +08:00
}
s := &Server{}
s.name = name
s.handlerMap = make(HandlerMap)
2017-12-08 12:03:21 +08:00
s.SetConfig(defaultServerConfig)
serverMapping.Set(name, s)
return s
2017-12-07 14:57:16 +08:00
}
2017-11-23 10:21:28 +08:00
// 执行
2017-12-07 17:34:51 +08:00
func (s *Server) Run() error {
2017-12-08 12:03:21 +08:00
if s.status == 1 {
return errors.New("server is already running")
}
2017-11-23 10:21:28 +08:00
// 底层http server配置
if s.config.Handler == nil {
s.config.Handler = http.HandlerFunc(s.defaultHttpHandle)
}
2017-12-07 14:57:16 +08:00
// 底层http server初始化
2017-11-23 10:21:28 +08:00
s.server = http.Server {
Addr : s.config.Addr,
Handler : s.config.Handler,
ReadTimeout : s.config.ReadTimeout,
WriteTimeout : s.config.WriteTimeout,
IdleTimeout : s.config.IdleTimeout,
MaxHeaderBytes : s.config.MaxHeaderBytes,
}
// 执行端口监听
2017-12-07 14:57:16 +08:00
if err := s.server.ListenAndServe(); err != nil {
return err
2017-11-23 10:21:28 +08:00
}
2017-12-07 17:34:51 +08:00
s.status = 1
2017-12-07 14:57:16 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// http server setting设置
// 注意使用该方法进行http server配置时需要配置所有的配置项否则没有配置的属性将会默认变量为空
2017-12-07 17:34:51 +08:00
func (s *Server)SetConfig(c ServerConfig) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
if c.Handler == nil {
c.Handler = http.HandlerFunc(s.defaultHttpHandle)
}
s.config = c
// 需要处理server root最后的目录分隔符号
if s.config.ServerRoot != "" {
s.SetServerRoot(s.config.ServerRoot)
}
// 必需设置默认值的属性
if len(s.config.IndexFiles) < 1 {
s.SetIndexFiles(defaultServerConfig.IndexFiles)
}
if s.config.ServerAgent == "" {
s.SetServerAgent(defaultServerConfig.ServerAgent)
}
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - Addr
2017-12-07 17:34:51 +08:00
func (s *Server)SetAddr(addr string) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.Addr = addr
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - TLSConfig
2017-12-07 17:34:51 +08:00
func (s *Server)SetTLSConfig(tls *tls.Config) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.TLSConfig = tls
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - ReadTimeout
2017-12-07 17:34:51 +08:00
func (s *Server)SetReadTimeout(t time.Duration) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.ReadTimeout = t
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - WriteTimeout
2017-12-07 17:34:51 +08:00
func (s *Server)SetWriteTimeout(t time.Duration) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.WriteTimeout = t
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - IdleTimeout
2017-12-07 17:34:51 +08:00
func (s *Server)SetIdleTimeout(t time.Duration) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.IdleTimeout = t
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - MaxHeaderBytes
2017-12-07 17:34:51 +08:00
func (s *Server)SetMaxHeaderBytes(b int) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.MaxHeaderBytes = b
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - ErrorLog
2017-12-07 17:34:51 +08:00
func (s *Server)SetErrorLog(logger *log.Logger) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.ErrorLog = logger
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - IndexFiles
2017-12-07 17:34:51 +08:00
func (s *Server)SetIndexFiles(index []string) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.IndexFiles = index
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - IndexFolder
2017-12-07 17:34:51 +08:00
func (s *Server)SetIndexFolder(index bool) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.IndexFolder = index
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - ServerAgent
2017-12-07 17:34:51 +08:00
func (s *Server)SetServerAgent(agent string) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.ServerAgent = agent
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 设置http server参数 - ServerRoot
2017-12-07 17:34:51 +08:00
func (s *Server)SetServerRoot(root string) error {
if s.status == 1 {
return errors.New("server config cannot be changed while running")
}
2017-11-23 10:21:28 +08:00
s.config.ServerRoot = strings.TrimRight(root, string(filepath.Separator))
2017-12-07 17:34:51 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 生成回调方法查询的Key
func (s *Server) handlerKey(domain, method, pattern string) string {
return strings.ToUpper(method) + ":" + pattern + "@" + strings.ToLower(domain)
}
// 设置请求处理方法
func (s *Server) setHandler(domain, method, pattern string, handler HandlerFunc) {
s.hmu.Lock()
defer s.hmu.Unlock()
2017-12-11 18:21:30 +08:00
if method == "all" {
s.handlerMap[s.handlerKey(domain, "GET", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "PUT", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "POST", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "DELETE", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "PATCH", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "HEAD", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "CONNECT", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "OPTIONS", pattern)] = handler
s.handlerMap[s.handlerKey(domain, "TRACE", pattern)] = handler
} else {
s.handlerMap[s.handlerKey(domain, method, pattern)] = handler
}
}
// 查询请求处理方法
func (s *Server) getHandler(domain, method, pattern string) HandlerFunc {
s.hmu.RLock()
defer s.hmu.RUnlock()
key := s.handlerKey(domain, method, pattern)
if f, ok := s.handlerMap[key]; ok {
return f
}
return nil
}
2017-11-23 10:21:28 +08:00
// 绑定URI到操作函数/方法
// pattern的格式形如/user/list, put:/user, delete:/user, post:/user@johng.cn
2017-11-23 10:21:28 +08:00
// 支持RESTful的请求格式具体业务逻辑由绑定的处理方法来执行
func (s *Server)BindHandler(pattern string, handler HandlerFunc) error {
2017-12-07 17:34:51 +08:00
if s.status == 1 {
return errors.New("server handlers cannot be changed while running")
}
2017-12-11 18:21:30 +08:00
s.hmu.Lock()
defer s.hmu.Unlock()
uri := ""
domain := gDEFAULT_DOMAIN
2017-12-11 18:21:30 +08:00
method := "all"
result := strings.Split(pattern, "@")
if len(result) > 1 {
domain = result[1]
2017-11-23 10:21:28 +08:00
}
result = strings.Split(result[0], ":")
2017-11-23 10:21:28 +08:00
if len(result) > 1 {
method = result[0]
uri = result[0]
2017-11-23 10:21:28 +08:00
} else {
uri = result[0]
2017-11-23 10:21:28 +08:00
}
if uri == "" {
return errors.New("invalid pattern")
2017-11-23 10:21:28 +08:00
}
s.setHandler(domain, method, uri, handler)
2017-12-07 14:57:16 +08:00
return nil
2017-11-23 10:21:28 +08:00
}
// 通过映射数组绑定URI到操作函数/方法
func (s *Server)BindHandlerByMap(m HandlerMap) error {
2017-11-23 10:21:28 +08:00
for p, f := range m {
if err := s.BindHandler(p, f); err != nil {
return err
}
2017-11-23 10:21:28 +08:00
}
return nil
2017-11-23 10:21:28 +08:00
}
// 绑定控制器控制器需要继承gmvc.Controller对象并实现需要的REST方法
func (s *Server)BindControllerRest(uri string, c ControllerRest) error {
return s.BindHandlerByMap(HandlerMap{
2017-11-23 10:21:28 +08:00
"GET:" + uri : c.Get,
"PUT:" + uri : c.Put,
"POST:" + uri : c.Post,
"DELETE:" + uri : c.Delete,
"PATCH:" + uri : c.Patch,
"HEAD:" + uri : c.Head,
"CONNECT:" + uri : c.Connect,
"OPTIONS:" + uri : c.Options,
"TRACE:" + uri : c.Trace,
})
}