From aee266eea0e2e94234be1e1973914d33657631c0 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 28 Nov 2018 20:19:28 +0800 Subject: [PATCH] =?UTF-8?q?WebServer=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/garray/garray.go | 1 + g/container/gchan/gchan.go | 1 + g/container/glist/glist.go | 1 + g/container/gmap/gmap.go | 1 + g/container/gpool/gpool.go | 1 + g/container/gqueue/gqueue.go | 1 + g/container/gring/gring.go | 1 + g/container/gset/gset.go | 1 + g/container/gtype/gtype.go | 1 + g/container/gvar/gvar.go | 1 + g/net/ghttp/ghttp_response.go | 1 + g/net/ghttp/ghttp_server.go | 2 - g/net/ghttp/ghttp_server_config.go | 127 ++++++--------------- g/net/ghttp/ghttp_server_config_cookie.go | 1 - g/net/ghttp/ghttp_server_config_logger.go | 1 - g/net/ghttp/ghttp_server_config_session.go | 1 - g/net/ghttp/ghttp_server_config_static.go | 79 +++++++++++++ g/os/gspath/gspath.go | 10 +- geg/container/gmap/safe_map_delete.go | 2 +- 19 files changed, 130 insertions(+), 104 deletions(-) create mode 100644 g/net/ghttp/ghttp_server_config_static.go diff --git a/g/container/garray/garray.go b/g/container/garray/garray.go index 967363105..dd4065982 100644 --- a/g/container/garray/garray.go +++ b/g/container/garray/garray.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package garray provides kinds of concurrent-safe(alternative) arrays. // 并发安全的数组. package garray diff --git a/g/container/gchan/gchan.go b/g/container/gchan/gchan.go index 67b3ba906..63aba678d 100644 --- a/g/container/gchan/gchan.go +++ b/g/container/gchan/gchan.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gchan provides graceful operations for channel. // 优雅的Channel操作. package gchan diff --git a/g/container/glist/glist.go b/g/container/glist/glist.go index bf63c5651..6361b566b 100644 --- a/g/container/glist/glist.go +++ b/g/container/glist/glist.go @@ -5,6 +5,7 @@ // You can obtain one at https://gitee.com/johng/gf. // +// Package glist provides a concurrent-safe(alternative) doubly linked list. // 并发安全的双向链表. package glist diff --git a/g/container/gmap/gmap.go b/g/container/gmap/gmap.go index 86604bdd1..479ad9b5a 100644 --- a/g/container/gmap/gmap.go +++ b/g/container/gmap/gmap.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gmap provides kinds of concurrent-safe(alternative) maps. // 并发安全的哈希MAP. package gmap diff --git a/g/container/gpool/gpool.go b/g/container/gpool/gpool.go index 5b2e4c73a..cb9b8cb1b 100644 --- a/g/container/gpool/gpool.go +++ b/g/container/gpool/gpool.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gpool provides a object-reusable concurrent-safe pool. // 对象复用池. package gpool diff --git a/g/container/gqueue/gqueue.go b/g/container/gqueue/gqueue.go index 7676685b7..f5d1d7fac 100644 --- a/g/container/gqueue/gqueue.go +++ b/g/container/gqueue/gqueue.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gqueue provides a dynamic/static concurrent-safe(alternative) queue. // 并发安全的动态队列. // 特点: // 1、动态队列初始化速度快; diff --git a/g/container/gring/gring.go b/g/container/gring/gring.go index bb9fe6056..7f126b56d 100644 --- a/g/container/gring/gring.go +++ b/g/container/gring/gring.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gring provides a concurrent-safe(alternative) ring(circular lists). // 并发安全的环. package gring diff --git a/g/container/gset/gset.go b/g/container/gset/gset.go index a0da5c634..f8dcd32e2 100644 --- a/g/container/gset/gset.go +++ b/g/container/gset/gset.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gset provides kinds of concurrent-safe(alternative) sets. // 并发安全的集合SET. package gset diff --git a/g/container/gtype/gtype.go b/g/container/gtype/gtype.go index 8c39cd68b..6519e9f11 100644 --- a/g/container/gtype/gtype.go +++ b/g/container/gtype/gtype.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gtype provides kinds of concurrent-safe basic-types. // 并发安全的基本类型. package gtype diff --git a/g/container/gvar/gvar.go b/g/container/gvar/gvar.go index 1ed19c326..2f65f7a38 100644 --- a/g/container/gvar/gvar.go +++ b/g/container/gvar/gvar.go @@ -4,6 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. +// Package gvar provides a universal variable type. // 通用动态变量. package gvar diff --git a/g/net/ghttp/ghttp_response.go b/g/net/ghttp/ghttp_response.go index 916355e19..2de89e99f 100644 --- a/g/net/ghttp/ghttp_response.go +++ b/g/net/ghttp/ghttp_response.go @@ -195,6 +195,7 @@ func (r *Response) ServeFileDownload(path string, name...string) { func (r *Response) RedirectTo(location string) { r.Header().Set("Location", location) r.WriteHeader(http.StatusFound) + r.request.Exit() } // 返回location标识,引导客户端跳转到来源页面 diff --git a/g/net/ghttp/ghttp_server.go b/g/net/ghttp/ghttp_server.go index ec4a9eb2d..70ee22aae 100644 --- a/g/net/ghttp/ghttp_server.go +++ b/g/net/ghttp/ghttp_server.go @@ -38,7 +38,6 @@ type ( Server struct { // 基本属性变量 name string // 服务名称,方便识别 - paths *gspath.SPath // 静态文件检索对象(类似nginx tryfile功能) config ServerConfig // 配置对象 servers []*gracefulServer // 底层http.Server列表 methodsMap map[string]struct{} // 所有支持的HTTP Method(初始化时自动填充) @@ -179,7 +178,6 @@ func GetServer(name...interface{}) (*Server) { } s := &Server { name : sname, - paths : gspath.New(), servers : make([]*gracefulServer, 0), methodsMap : make(map[string]struct{}), statusHandlerMap : make(map[string]HandlerFunc), diff --git a/g/net/ghttp/ghttp_server_config.go b/g/net/ghttp/ghttp_server_config.go index d6c35e1d2..07b409608 100644 --- a/g/net/ghttp/ghttp_server_config.go +++ b/g/net/ghttp/ghttp_server_config.go @@ -3,17 +3,14 @@ // 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://gitee.com/johng/gf. -// 配置管理数据结构定义. package ghttp import ( - "time" + "gitee.com/johng/gf/g/os/glog" "net/http" "strconv" - "strings" - "gitee.com/johng/gf/g/os/glog" - "gitee.com/johng/gf/g/os/gfile" + "time" ) const ( @@ -36,49 +33,51 @@ type LogHandler func(r *Request, error ... interface{}) // HTTP Server 设置结构体,静态配置 type ServerConfig struct { // 底层http对象配置 - Addr string // 监听IP和端口,监听本地所有IP使用":端口"(支持多个地址,使用","号分隔) - HTTPSAddr string // HTTPS服务监听地址(支持多个地址,使用","号分隔) - HTTPSCertPath string // HTTPS证书文件路径 - HTTPSKeyPath string // HTTPS签名文件路径 - Handler http.Handler // 默认的处理函数 - ReadTimeout time.Duration // 读取超时 - WriteTimeout time.Duration // 写入超时 - IdleTimeout time.Duration // 等待超时 - MaxHeaderBytes int // 最大的header长度 + Addr string // 监听IP和端口,监听本地所有IP使用":端口"(支持多个地址,使用","号分隔) + HTTPSAddr string // HTTPS服务监听地址(支持多个地址,使用","号分隔) + HTTPSCertPath string // HTTPS证书文件路径 + HTTPSKeyPath string // HTTPS签名文件路径 + Handler http.Handler // 默认的处理函数 + ReadTimeout time.Duration // 读取超时 + WriteTimeout time.Duration // 写入超时 + IdleTimeout time.Duration // 等待超时 + MaxHeaderBytes int // 最大的header长度 // 静态文件配置 - IndexFiles []string // 默认访问的文件列表 - IndexFolder bool // 如果访问目录是否显示目录列表 - ServerAgent string // server agent - ServerRoot string // 服务器服务的本地目录根路径 - FileServerEnabled bool // 是否允许静态文件服务(默认开启) + IndexFiles []string // 默认访问的文件列表 + IndexFolder bool // 如果访问目录是否显示目录列表 + ServerAgent string // Server Agent + ServerRoot string // 服务器服务的本地目录根路径(检索优先级比StaticPaths低) + SearchPaths []string // 静态文件搜索目录(包含ServerRoot,按照优先级进行排序) + StaticPaths []map[string]string // 静态文件目录映射(按照优先级进行排序) + FileServerEnabled bool // 是否允许静态文件服务(总开关,默认开启) // COOKIE - CookieMaxAge int // Cookie有效期 - CookiePath string // Cookie有效Path(注意同时也会影响SessionID) - CookieDomain string // Cookie有效Domain(注意同时也会影响SessionID) + CookieMaxAge int // Cookie有效期 + CookiePath string // Cookie有效Path(注意同时也会影响SessionID) + CookieDomain string // Cookie有效Domain(注意同时也会影响SessionID) // SESSION - SessionMaxAge int // Session有效期 - SessionIdName string // SessionId名称 + SessionMaxAge int // Session有效期 + SessionIdName string // SessionId名称 // ip访问控制 - DenyIps []string // 不允许访问的ip列表,支持ip前缀过滤,如: 10 将不允许10开头的ip访问 - AllowIps []string // 仅允许访问的ip列表,支持ip前缀过滤,如: 10 将仅允许10开头的ip访问 + DenyIps []string // 不允许访问的ip列表,支持ip前缀过滤,如: 10 将不允许10开头的ip访问 + AllowIps []string // 仅允许访问的ip列表,支持ip前缀过滤,如: 10 将仅允许10开头的ip访问 // 路由访问控制 - DenyRoutes []string // 不允许访问的路由规则列表 + DenyRoutes []string // 不允许访问的路由规则列表 // 日志配置 - LogPath string // 存放日志的目录路径 - LogHandler LogHandler // 自定义日志处理回调方法 - ErrorLogEnabled bool // 是否开启error log - AccessLogEnabled bool // 是否开启access log + LogPath string // 存放日志的目录路径 + LogHandler LogHandler // 自定义日志处理回调方法 + ErrorLogEnabled bool // 是否开启error log + AccessLogEnabled bool // 是否开启access log // 其他设置 - NameToUriType int // 服务注册时对象和方法名称转换为URI时的规则 - GzipContentTypes []string // 允许进行gzip压缩的文件类型 - DumpRouteMap bool // 是否在程序启动时默认打印路由表信息 - RouterCacheExpire int // 路由检索缓存过期时间(秒) + NameToUriType int // 服务注册时对象和方法名称转换为URI时的规则 + GzipContentTypes []string // 允许进行gzip压缩的文件类型 + DumpRouteMap bool // 是否在程序启动时默认打印路由表信息 + RouterCacheExpire int // 路由检索缓存过期时间(秒) } // 默认HTTP Server配置 @@ -90,10 +89,12 @@ var defaultServerConfig = ServerConfig { WriteTimeout : 60 * time.Second, IdleTimeout : 60 * time.Second, MaxHeaderBytes : 1024, + IndexFiles : []string{"index.html", "index.htm"}, IndexFolder : false, ServerAgent : "gf", ServerRoot : "", + StaticPaths : make([]map[string]string, 0), FileServerEnabled : true, CookieMaxAge : gDEFAULT_COOKIE_MAX_AGE, @@ -232,25 +233,6 @@ func (s *Server)SetMaxHeaderBytes(b int) { } -// 设置http server参数 - IndexFiles,默认展示文件,如:index.html, index.htm -func (s *Server)SetIndexFiles(index []string) { - if s.Status() == SERVER_STATUS_RUNNING { - glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) - return - } - s.config.IndexFiles = index -} - -// 允许展示访问目录的文件列表 -func (s *Server)SetIndexFolder(index bool) { - if s.Status() == SERVER_STATUS_RUNNING { - glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) - return - } - s.config.IndexFolder = index - -} - // 设置http server参数 - ServerAgent func (s *Server)SetServerAgent(agent string) { if s.Status() == SERVER_STATUS_RUNNING { @@ -258,30 +240,6 @@ func (s *Server)SetServerAgent(agent string) { return } s.config.ServerAgent = agent - -} - -// 设置http server参数 - ServerRoot -func (s *Server)SetServerRoot(root string) { - if s.Status() == SERVER_STATUS_RUNNING { - glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) - return - } - // RealPath的作用除了校验地址正确性以外,还转换分隔符号为当前系统正确的文件分隔符号 - path := gfile.RealPath(root) - if path == "" { - glog.Error("invalid root path \"" + root + "\"") - } - s.config.ServerRoot = strings.TrimRight(path, gfile.Separator) -} - -// 是否开启/关闭静态文件服务,当关闭时仅提供动态接口服务,路由性能会得到一定提升 -func (s *Server) SetFileServerEnabled(enabled bool) { - if s.Status() == SERVER_STATUS_RUNNING { - glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) - return - } - s.config.FileServerEnabled = enabled } func (s *Server) SetDenyIps(ips []string) { @@ -343,18 +301,7 @@ func (s *Server) SetRouterCacheExpire(expire int) { s.config.RouterCacheExpire = expire } -// 添加静态文件搜索目录,必须给定目录的绝对路径 -func (s *Server) AddSearchPath(path string) error { - if rp, err := s.paths.Add(path); err != nil { - glog.Error("ghttp.AddSearchPath failed:", err.Error()) - return err - } else { - glog.Debug("ghttp.AddSearchPath:", rp) - } - return nil -} - -// 获取 +// 获取WebServer名称 func (s *Server) GetName() string { return s.name } \ No newline at end of file diff --git a/g/net/ghttp/ghttp_server_config_cookie.go b/g/net/ghttp/ghttp_server_config_cookie.go index b15fc5e0a..bad52b0bf 100644 --- a/g/net/ghttp/ghttp_server_config_cookie.go +++ b/g/net/ghttp/ghttp_server_config_cookie.go @@ -3,7 +3,6 @@ // 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://gitee.com/johng/gf. -// 配置管理数据结构定义. package ghttp diff --git a/g/net/ghttp/ghttp_server_config_logger.go b/g/net/ghttp/ghttp_server_config_logger.go index 97252e9b6..e7a949cf7 100644 --- a/g/net/ghttp/ghttp_server_config_logger.go +++ b/g/net/ghttp/ghttp_server_config_logger.go @@ -3,7 +3,6 @@ // 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://gitee.com/johng/gf. -// 配置管理数据结构定义. package ghttp diff --git a/g/net/ghttp/ghttp_server_config_session.go b/g/net/ghttp/ghttp_server_config_session.go index 015d666b4..7b9fa801b 100644 --- a/g/net/ghttp/ghttp_server_config_session.go +++ b/g/net/ghttp/ghttp_server_config_session.go @@ -3,7 +3,6 @@ // 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://gitee.com/johng/gf. -// 配置管理数据结构定义. package ghttp diff --git a/g/net/ghttp/ghttp_server_config_static.go b/g/net/ghttp/ghttp_server_config_static.go new file mode 100644 index 000000000..3e0055fd0 --- /dev/null +++ b/g/net/ghttp/ghttp_server_config_static.go @@ -0,0 +1,79 @@ +// Copyright 2017 gf Author(https://gitee.com/johng/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://gitee.com/johng/gf. + +// 静态文件搜索优先级: ServerPaths > ServerRoot > SearchPath + +package ghttp + +import ( + "gitee.com/johng/gf/g/os/gfile" + "gitee.com/johng/gf/g/os/glog" + "strings" +) + +// 设置http server参数 - IndexFiles,默认展示文件,如:index.html, index.htm +func (s *Server)SetIndexFiles(index []string) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + s.config.IndexFiles = index +} + +// 允许展示访问目录的文件列表 +func (s *Server)SetIndexFolder(enabled bool) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + s.config.IndexFolder = enabled +} + +// 是否开启/关闭静态文件服务,当关闭时仅提供动态接口服务,路由性能会得到一定提升 +func (s *Server) SetFileServerEnabled(enabled bool) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + s.config.FileServerEnabled = enabled +} + +// 设置http server参数 - ServerRoot +func (s *Server)SetServerRoot(root string) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + // RealPath的作用除了校验地址正确性以外,还转换分隔符号为当前系统正确的文件分隔符号 + path := gfile.RealPath(root) + if path == "" { + glog.Error("invalid root path \"" + root + "\"") + } + s.config.ServerRoot = strings.TrimRight(path, gfile.Separator) +} + +// 添加静态文件搜索目录,必须给定目录的绝对路径 +func (s *Server) AddSearchPath(path string) error { + if rp, err := s.paths.Add(path); err != nil { + glog.Error("[ghttp] AddSearchPath failed:", err.Error()) + return err + } else { + glog.Debug("[ghttp] AddSearchPath:", rp) + } + return nil +} + +// 添加URI与静态目录的映射 +func (s *Server) AddStaticPath(prefix string, path string) error { + if rp, err := s.paths.Add(path); err != nil { + glog.Error("[ghttp] AddSearchPath failed:", err.Error()) + return err + } else { + glog.Debug("[ghttp] AddSearchPath:", rp) + } + return nil +} + diff --git a/g/os/gspath/gspath.go b/g/os/gspath/gspath.go index f32bd52b5..ee0f6f12c 100644 --- a/g/os/gspath/gspath.go +++ b/g/os/gspath/gspath.go @@ -29,8 +29,8 @@ type SPath struct { // 文件搜索缓存项 type SPathCacheItem struct { - path string // 文件/目录绝对路径 - isDir bool // 是否目录 + path string // 文件/目录绝对路径 + isDir bool // 是否目录 } // 创建一个搜索对象 @@ -53,9 +53,6 @@ func (sp *SPath) Set(path string) (realPath string, err error) { if realPath == "" { return realPath, errors.New(fmt.Sprintf(`path "%s" does not exist`, path)) } - if realPath == "" { - return realPath, errors.New("invalid path:" + path) - } // 设置的搜索路径必须为目录 if gfile.IsDir(realPath) { realPath = strings.TrimRight(realPath, gfile.Separator) @@ -87,9 +84,6 @@ func (sp *SPath) Add(path string) (realPath string, err error) { if realPath == "" { return realPath, errors.New(fmt.Sprintf(`path "%s" does not exist`, path)) } - if realPath == "" { - return realPath, errors.New("invalid path:" + path) - } // 添加的搜索路径必须为目录 if gfile.IsDir(realPath) { // 如果已经添加则不再添加 diff --git a/geg/container/gmap/safe_map_delete.go b/geg/container/gmap/safe_map_delete.go index a248c53e4..7d3b999c9 100644 --- a/geg/container/gmap/safe_map_delete.go +++ b/geg/container/gmap/safe_map_delete.go @@ -1,4 +1,3 @@ -// 验证 map 的delete方法是否并发安全 package main import ( @@ -7,6 +6,7 @@ import ( "fmt" ) +// 验证 map 的delete方法是否并发安全 func main() { // 创建一个初始化的map m := make(map[int]int)