improve configuration feature for ghttp.Server/gview/glog

This commit is contained in:
John 2019-11-28 23:19:37 +08:00
parent bb45d8d578
commit 0cce858641
19 changed files with 311 additions and 143 deletions

View File

@ -140,7 +140,9 @@ func (node *ConfigNode) String() string {
if node.LinkInfo != "" {
return node.LinkInfo
}
return fmt.Sprintf(`%s@%s:%s,%s,%s,%s,%s,%v,%d-%d-%d`, node.User, node.Host, node.Port,
return fmt.Sprintf(
`%s@%s:%s,%s,%s,%s,%s,%v,%d-%d-%d`,
node.User, node.Host, node.Port,
node.Name, node.Type, node.Role, node.Charset, node.Debug,
node.MaxIdleConnCount, node.MaxOpenConnCount, node.MaxConnLifetime,
)

View File

@ -4,7 +4,7 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
// Package gins provides instances management and core components management.
// Package gins provides instances and core components management.
package gins
import (
@ -35,8 +35,10 @@ const (
gFRAME_CORE_COMPONENT_NAME_DATABASE = "gf.core.component.database"
)
// instances is the instance map for common used components.
var instances = gmap.NewStrAnyMap(true)
var (
// instances is the instance map for common used components.
instances = gmap.NewStrAnyMap(true)
)
// Get returns the instance by given name.
func Get(name string) interface{} {
@ -88,8 +90,15 @@ func View(name ...string) *gview.View {
return instances.GetOrSetFuncLock(instanceKey, func() interface{} {
view := gview.Instance(instanceName)
// To avoid file no found error while it's not necessary.
if Config().FilePath() != "" {
if m := Config().GetMap("view"); m != nil {
if Config().Available() {
var m map[string]interface{}
// It firstly searches the configuration of the instance name.
if m = Config().GetMap(fmt.Sprintf(`view.%s`, instanceName)); m == nil {
// If the configuration for the instance does not exist,
// it uses the default view configuration.
m = Config().GetMap("view")
}
if m != nil {
if err := view.SetConfigWithMap(m); err != nil {
glog.Panic(err)
}
@ -128,8 +137,15 @@ func Log(name ...string) *glog.Logger {
return instances.GetOrSetFuncLock(instanceKey, func() interface{} {
logger := glog.Instance(instanceName)
// To avoid file no found error while it's not necessary.
if Config().FilePath() != "" {
if m := Config().GetMap("logging"); m != nil {
if Config().Available() {
var m map[string]interface{}
// It firstly searches the configuration of the instance name.
if m = Config().GetMap(fmt.Sprintf(`logging.%s`, instanceName)); m == nil {
// If the configuration for the instance does not exist,
// it uses the default logging configuration.
m = Config().GetMap("logging")
}
if m != nil {
if err := logger.SetConfigWithMap(m); err != nil {
glog.Panic(err)
}
@ -276,8 +292,15 @@ func Server(name ...interface{}) *ghttp.Server {
return instances.GetOrSetFuncLock(instanceKey, func() interface{} {
s := ghttp.GetServer(name...)
// To avoid file no found error while it's not necessary.
if Config().FilePath() != "" {
if m := Config().GetMap("server"); m != nil {
if Config().Available() {
var m map[string]interface{}
// It firstly searches the configuration of the instance name.
if m = Config().GetMap(fmt.Sprintf(`server.%s`, s.GetName())); m == nil {
// If the configuration for the instance does not exist,
// it uses the default server configuration.
m = Config().GetMap("server")
}
if m != nil {
if err := s.SetConfigWithMap(m); err != nil {
panic(err)
}

View File

@ -4,41 +4,40 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gins_test
package gins
import (
"testing"
"github.com/gogf/gf/frame/gins"
"github.com/gogf/gf/test/gtest"
)
func Test_SetGet(t *testing.T) {
gtest.Case(t, func() {
gins.Set("test-user", 1)
gtest.Assert(gins.Get("test-user"), 1)
gtest.Assert(gins.Get("none-exists"), nil)
Set("test-user", 1)
gtest.Assert(Get("test-user"), 1)
gtest.Assert(Get("none-exists"), nil)
})
gtest.Case(t, func() {
gtest.Assert(gins.GetOrSet("test-1", 1), 1)
gtest.Assert(gins.Get("test-1"), 1)
gtest.Assert(GetOrSet("test-1", 1), 1)
gtest.Assert(Get("test-1"), 1)
})
gtest.Case(t, func() {
gtest.Assert(gins.GetOrSetFunc("test-2", func() interface{} {
gtest.Assert(GetOrSetFunc("test-2", func() interface{} {
return 2
}), 2)
gtest.Assert(gins.Get("test-2"), 2)
gtest.Assert(Get("test-2"), 2)
})
gtest.Case(t, func() {
gtest.Assert(gins.GetOrSetFuncLock("test-3", func() interface{} {
gtest.Assert(GetOrSetFuncLock("test-3", func() interface{} {
return 3
}), 3)
gtest.Assert(gins.Get("test-3"), 3)
gtest.Assert(Get("test-3"), 3)
})
gtest.Case(t, func() {
gtest.Assert(gins.SetIfNotExist("test-4", 4), true)
gtest.Assert(gins.Get("test-4"), 4)
gtest.Assert(gins.SetIfNotExist("test-4", 5), false)
gtest.Assert(gins.Get("test-4"), 4)
gtest.Assert(SetIfNotExist("test-4", 4), true)
gtest.Assert(Get("test-4"), 4)
gtest.Assert(SetIfNotExist("test-4", 5), false)
gtest.Assert(Get("test-4"), 4)
})
}

View File

@ -4,7 +4,7 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gins_test
package gins
import (
"fmt"
@ -13,7 +13,6 @@ import (
"github.com/gogf/gf/os/gcfg"
"github.com/gogf/gf/frame/gins"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/test/gtest"
@ -52,7 +51,7 @@ test = "v=1"
cache = "127.0.0.1:6379,1"
`
gtest.Case(t, func() {
gtest.AssertNE(gins.Config(), nil)
gtest.AssertNE(Config(), nil)
})
// relative path
@ -61,10 +60,10 @@ test = "v=1"
err := gfile.PutContents(path, config)
gtest.Assert(err, nil)
defer gfile.Remove(path)
defer gins.Config().Clear()
gtest.Assert(gins.Config().Get("test"), "v=1")
gtest.Assert(gins.Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config().Get("redis.disk"), "127.0.0.1:6379,0")
defer Config().Clear()
gtest.Assert(Config().Get("test"), "v=1")
gtest.Assert(Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config().Get("redis.disk"), "127.0.0.1:6379,0")
})
// for gfsnotify callbacks to refresh cache of config file
time.Sleep(500 * time.Millisecond)
@ -75,10 +74,10 @@ test = "v=1"
err := gfile.PutContents(path, config)
gtest.Assert(err, nil)
defer gfile.Remove(path)
defer gins.Config().Clear()
gtest.Assert(gins.Config().Get("test"), "v=1")
gtest.Assert(gins.Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config().Get("redis.disk"), "127.0.0.1:6379,0")
defer Config().Clear()
gtest.Assert(Config().Get("test"), "v=1")
gtest.Assert(Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config().Get("redis.disk"), "127.0.0.1:6379,0")
})
// for gfsnotify callbacks to refresh cache of config file
time.Sleep(500 * time.Millisecond)
@ -88,11 +87,11 @@ test = "v=1"
err := gfile.PutContents(path, config)
gtest.Assert(err, nil)
defer gfile.Remove(path)
defer gins.Config("test").Clear()
gins.Config("test").SetFileName("test.toml")
gtest.Assert(gins.Config("test").Get("test"), "v=1")
gtest.Assert(gins.Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
defer Config("test").Clear()
Config("test").SetFileName("test.toml")
gtest.Assert(Config("test").Get("test"), "v=1")
gtest.Assert(Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
})
// for gfsnotify callbacks to refresh cache of config file
time.Sleep(500 * time.Millisecond)
@ -102,11 +101,11 @@ test = "v=1"
err := gfile.PutContents(path, config)
gtest.Assert(err, nil)
defer gfile.Remove(path)
defer gins.Config("test").Clear()
gins.Config("test").SetFileName("test.toml")
gtest.Assert(gins.Config("test").Get("test"), "v=1")
gtest.Assert(gins.Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
defer Config("test").Clear()
Config("test").SetFileName("test.toml")
gtest.Assert(Config("test").Get("test"), "v=1")
gtest.Assert(Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
})
// for gfsnotify callbacks to refresh cache of config file
time.Sleep(500 * time.Millisecond)
@ -118,11 +117,11 @@ test = "v=1"
err := gfile.PutContents(file, config)
gtest.Assert(err, nil)
defer gfile.Remove(file)
defer gins.Config().Clear()
gtest.Assert(gins.Config().AddPath(path), nil)
gtest.Assert(gins.Config().Get("test"), "v=1")
gtest.Assert(gins.Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config().Get("redis.disk"), "127.0.0.1:6379,0")
defer Config().Clear()
gtest.Assert(Config().AddPath(path), nil)
gtest.Assert(Config().Get("test"), "v=1")
gtest.Assert(Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config().Get("redis.disk"), "127.0.0.1:6379,0")
})
time.Sleep(500 * time.Millisecond)
@ -132,11 +131,11 @@ test = "v=1"
err := gfile.PutContents(file, config)
gtest.Assert(err, nil)
defer gfile.Remove(file)
defer gins.Config().Clear()
gtest.Assert(gins.Config().AddPath(path), nil)
gtest.Assert(gins.Config().Get("test"), "v=1")
gtest.Assert(gins.Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config().Get("redis.disk"), "127.0.0.1:6379,0")
defer Config().Clear()
gtest.Assert(Config().AddPath(path), nil)
gtest.Assert(Config().Get("test"), "v=1")
gtest.Assert(Config().Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config().Get("redis.disk"), "127.0.0.1:6379,0")
})
time.Sleep(500 * time.Millisecond)
@ -146,12 +145,12 @@ test = "v=1"
err := gfile.PutContents(file, config)
gtest.Assert(err, nil)
defer gfile.Remove(file)
defer gins.Config("test").Clear()
gins.Config("test").SetFileName("test.toml")
gtest.Assert(gins.Config("test").AddPath(path), nil)
gtest.Assert(gins.Config("test").Get("test"), "v=1")
gtest.Assert(gins.Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
defer Config("test").Clear()
Config("test").SetFileName("test.toml")
gtest.Assert(Config("test").AddPath(path), nil)
gtest.Assert(Config("test").Get("test"), "v=1")
gtest.Assert(Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
})
time.Sleep(500 * time.Millisecond)
@ -161,12 +160,12 @@ test = "v=1"
err := gfile.PutContents(file, config)
gtest.Assert(err, nil)
defer gfile.Remove(file)
defer gins.Config().Clear()
gins.Config("test").SetFileName("test.toml")
gtest.Assert(gins.Config("test").AddPath(path), nil)
gtest.Assert(gins.Config("test").Get("test"), "v=1")
gtest.Assert(gins.Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(gins.Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
defer Config().Clear()
Config("test").SetFileName("test.toml")
gtest.Assert(Config("test").AddPath(path), nil)
gtest.Assert(Config("test").Get("test"), "v=1")
gtest.Assert(Config("test").Get("database.default.1.host"), "127.0.0.1")
gtest.Assert(Config("test").Get("redis.disk"), "127.0.0.1:6379,0")
})
}
@ -180,6 +179,6 @@ func Test_Basic2(t *testing.T) {
_ = gfile.Remove(path)
}()
gtest.Assert(gins.Config().Get("log-path"), "logs")
gtest.Assert(Config().Get("log-path"), "logs")
})
}

View File

@ -4,13 +4,12 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gins_test
package gins
import (
"testing"
"time"
"github.com/gogf/gf/frame/gins"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/test/gtest"
)
@ -51,16 +50,16 @@ test = "v=2"
err := gfile.PutContents(path, config)
gtest.Assert(err, nil)
defer gfile.Remove(path)
defer gins.Config().Clear()
defer Config().Clear()
// for gfsnotify callbacks to refresh cache of config file
time.Sleep(500 * time.Millisecond)
gtest.Case(t, func() {
//fmt.Println("gins Test_Database", gins.Config().Get("test"))
//fmt.Println("gins Test_Database", Config().Get("test"))
dbDefault := gins.Database()
dbTest := gins.Database("test")
dbDefault := Database()
dbTest := Database("test")
gtest.AssertNE(dbDefault, nil)
gtest.AssertNE(dbTest, nil)

View File

@ -4,13 +4,12 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gins_test
package gins
import (
"testing"
"time"
"github.com/gogf/gf/frame/gins"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/test/gtest"
)
@ -54,17 +53,17 @@ test = "v=3"
err := gfile.PutContents(path, config)
gtest.Assert(err, nil)
defer gfile.Remove(path)
defer gins.Config().Clear()
defer Config().Clear()
// for gfsnotify callbacks to refresh cache of config file
time.Sleep(500 * time.Millisecond)
gtest.Case(t, func() {
//fmt.Println("gins Test_Redis", gins.Config().Get("test"))
//fmt.Println("gins Test_Redis", Config().Get("test"))
redisDefault := gins.Redis()
redisCache := gins.Redis("cache")
redisDisk := gins.Redis("disk")
redisDefault := Redis()
redisCache := Redis("cache")
redisDisk := Redis("disk")
gtest.AssertNE(redisDefault, nil)
gtest.AssertNE(redisCache, nil)
gtest.AssertNE(redisDisk, nil)

View File

@ -4,13 +4,14 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gins_test
package gins
import (
"fmt"
"github.com/gogf/gf/debug/gdebug"
"github.com/gogf/gf/os/gcfg"
"testing"
"github.com/gogf/gf/frame/gins"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/test/gtest"
@ -18,8 +19,8 @@ import (
func Test_View(t *testing.T) {
gtest.Case(t, func() {
gtest.AssertNE(gins.View(), nil)
b, e := gins.View().ParseContent(`{{"我是中国人" | substr 2 -1}}`, nil)
gtest.AssertNE(View(), nil)
b, e := View().ParseContent(`{{"我是中国人" | substr 2 -1}}`, nil)
gtest.Assert(e, nil)
gtest.Assert(b, "中国人")
})
@ -29,7 +30,7 @@ func Test_View(t *testing.T) {
gtest.Assert(err, nil)
defer gfile.Remove(tpl)
b, e := gins.View().Parse("t.tpl", nil)
b, e := View().Parse("t.tpl", nil)
gtest.Assert(e, nil)
gtest.Assert(b, "中国人")
})
@ -39,11 +40,102 @@ func Test_View(t *testing.T) {
err := gfile.PutContents(tpl, `{{"我是中国人" | substr 2 -1}}`)
gtest.Assert(err, nil)
defer gfile.Remove(tpl)
err = gins.View().AddPath(path)
err = View().AddPath(path)
gtest.Assert(err, nil)
b, e := gins.View().Parse("t.tpl", nil)
b, e := View().Parse("t.tpl", nil)
gtest.Assert(e, nil)
gtest.Assert(b, "中国人")
})
}
func Test_View_Config(t *testing.T) {
// view1 test1
gtest.Case(t, func() {
dirPath := gfile.Join(gdebug.CallerDirectory(), "testdata", "view1")
gcfg.SetContent(gfile.GetContents(gfile.Join(dirPath, "config.toml")))
defer gcfg.ClearContent()
defer instances.Clear()
view := View("test1")
gtest.AssertNE(view, nil)
err := view.AddPath(dirPath)
gtest.Assert(err, nil)
str := `hello ${.name},version:${.version}`
view.Assigns(map[string]interface{}{"version": "1.9.0"})
result, err := view.ParseContent(str, nil)
gtest.Assert(err, nil)
gtest.Assert(result, "hello test1,version:1.9.0")
result, err = view.ParseDefault()
gtest.Assert(err, nil)
gtest.Assert(result, "test1:test1")
})
// view1 test2
gtest.Case(t, func() {
dirPath := gfile.Join(gdebug.CallerDirectory(), "testdata", "view1")
gcfg.SetContent(gfile.GetContents(gfile.Join(dirPath, "config.toml")))
defer gcfg.ClearContent()
defer instances.Clear()
view := View("test2")
gtest.AssertNE(view, nil)
err := view.AddPath(dirPath)
gtest.Assert(err, nil)
str := `hello #{.name},version:#{.version}`
view.Assigns(map[string]interface{}{"version": "1.9.0"})
result, err := view.ParseContent(str, nil)
gtest.Assert(err, nil)
gtest.Assert(result, "hello test2,version:1.9.0")
result, err = view.ParseDefault()
gtest.Assert(err, nil)
gtest.Assert(result, "test2:test2")
})
// view2
gtest.Case(t, func() {
dirPath := gfile.Join(gdebug.CallerDirectory(), "testdata", "view2")
gcfg.SetContent(gfile.GetContents(gfile.Join(dirPath, "config.toml")))
defer gcfg.ClearContent()
defer instances.Clear()
view := View()
gtest.AssertNE(view, nil)
err := view.AddPath(dirPath)
gtest.Assert(err, nil)
str := `hello {.name},version:{.version}`
view.Assigns(map[string]interface{}{"version": "1.9.0"})
result, err := view.ParseContent(str, nil)
gtest.Assert(err, nil)
gtest.Assert(result, "hello test,version:1.9.0")
result, err = view.ParseDefault()
gtest.Assert(err, nil)
gtest.Assert(result, "test:test")
})
// view2
gtest.Case(t, func() {
dirPath := gfile.Join(gdebug.CallerDirectory(), "testdata", "view2")
gcfg.SetContent(gfile.GetContents(gfile.Join(dirPath, "config.toml")))
defer gcfg.ClearContent()
defer instances.Clear()
view := View("test100")
gtest.AssertNE(view, nil)
err := view.AddPath(dirPath)
gtest.Assert(err, nil)
str := `hello {.name},version:{.version}`
view.Assigns(map[string]interface{}{"version": "1.9.0"})
result, err := view.ParseContent(str, nil)
gtest.Assert(err, nil)
gtest.Assert(result, "hello test,version:1.9.0")
result, err = view.ParseDefault()
gtest.Assert(err, nil)
gtest.Assert(result, "test:test")
})
}

14
frame/gins/testdata/view1/config.toml vendored Normal file
View File

@ -0,0 +1,14 @@
[view]
[view.test1]
defaultFile = "test1.html"
delimiters = ["${", "}"]
[view.test1.data]
name = "test1"
[view.test2]
defaultFile = "test2.html"
delimiters = ["#{", "}"]
[view.test2.data]
name = "test2"

1
frame/gins/testdata/view1/test1.html vendored Normal file
View File

@ -0,0 +1 @@
test1:${.name}

1
frame/gins/testdata/view1/test2.html vendored Normal file
View File

@ -0,0 +1 @@
test2:#{.name}

8
frame/gins/testdata/view2/config.toml vendored Normal file
View File

@ -0,0 +1,8 @@
[view]
defaultFile = "test.html"
delimiters = ["{", "}"]
[view.data]
name = "test"

1
frame/gins/testdata/view2/test.html vendored Normal file
View File

@ -0,0 +1 @@
test:{.name}

View File

@ -88,7 +88,7 @@ func (r *Response) buildInVars(params ...map[string]interface{}) map[string]inte
}
// Note that it should assign no Config variable to template
// if there's no configuration file.
if c := gcfg.Instance(); c.FilePath() != "" {
if c := gcfg.Instance(); c.Available() {
vars["Config"] = c.GetMap(".")
}
vars["Get"] = r.Request.GetQueryMap()

View File

@ -63,7 +63,9 @@ func (w *ResponseWriter) OutputBuffer() {
w.buffer.WriteString(http.StatusText(w.Status))
}
if w.buffer.Len() > 0 {
w.writer.Write(w.buffer.Bytes())
if _, err := w.writer.Write(w.buffer.Bytes()); err != nil {
panic(err)
}
w.buffer.Reset()
}
}

View File

@ -215,7 +215,7 @@ func GetServer(name ...interface{}) *Server {
s := &Server{
name: serverName,
servers: make([]*gracefulServer, 0),
closeChan: make(chan struct{}, 100),
closeChan: make(chan struct{}, 10000),
serverCount: gtype.NewInt(),
statusHandlerMap: make(map[string]HandlerFunc),
serveTree: make(map[string]interface{}),
@ -282,7 +282,7 @@ func (s *Server) Start() error {
// Default HTTP handler.
if s.config.Handler == nil {
s.config.Handler = http.HandlerFunc(s.defaultHttpHandle)
s.config.Handler = http.HandlerFunc(s.defaultHandler)
}
// Start the HTTP server.

View File

@ -24,30 +24,30 @@ import (
)
const (
gDEFAULT_HTTP_ADDR = ":80" // 默认HTTP监听地址
gDEFAULT_HTTPS_ADDR = ":443" // 默认HTTPS监听地址
URI_TYPE_DEFAULT = 0 // 服务注册时对象和方法名称转换为URI时全部转为小写单词以'-'连接符号连接
URI_TYPE_FULLNAME = 1 // 不处理名称以原有名称构建成URI
URI_TYPE_ALLLOWER = 2 // 仅转为小写,单词间不使用连接符号
URI_TYPE_CAMEL = 3 // 采用驼峰命名方式
gDEFAULT_HTTP_ADDR = ":80" // Default listening port for HTTP.
gDEFAULT_HTTPS_ADDR = ":443" // Default listening port for HTTPS.
URI_TYPE_DEFAULT = 0 // Type for method name to URI converting, which converts name to its lower case and joins the words using char '-'.
URI_TYPE_FULLNAME = 1 // Type for method name to URI converting, which does no converting to the method name.
URI_TYPE_ALLLOWER = 2 // Type for method name to URI converting, which converts name to its lower case.
URI_TYPE_CAMEL = 3 // Type for method name to URI converting, which converts name to its camel case.
)
// HTTP Server configuration.
type ServerConfig struct {
Address string // Server listening address like ":port", multiple addresses separated using ','
HTTPSAddr string // HTTPS服务监听地址(支持多个地址,使用","号分隔)
HTTPSCertPath string // HTTPS证书文件路径
HTTPSKeyPath string // HTTPS签名文件路径
Handler http.Handler // 默认的处理函数
ReadTimeout time.Duration // 读取超时
WriteTimeout time.Duration // 写入超时
IdleTimeout time.Duration // 等待超时
MaxHeaderBytes int // 最大的header长度
TLSConfig *tls.Config // HTTPS证书配置
KeepAlive bool // 是否开启长连接
ServerAgent string // Server Agent
View *gview.View // 模板引擎对象
Rewrites map[string]string // URI Rewrite重写配置
Address string // Server listening address like ":port", multiple addresses joining using ','
HTTPSAddr string // HTTPS addresses, multiple addresses joining using char ','.
HTTPSCertPath string // HTTPS certification file path.
HTTPSKeyPath string // HTTPS key file path.
Handler http.Handler // Default request handler function.
ReadTimeout time.Duration // Maximum duration for reading the entire request, including the body.
WriteTimeout time.Duration // Maximum duration before timing out writes of the response.
IdleTimeout time.Duration // Maximum amount of time to wait for the next request when keep-alives are enabled.
MaxHeaderBytes int // Maximum number of bytes the server will read parsing the request header's keys and values, including the request line.
TLSConfig *tls.Config // TLS configuration for use by ServeTLS and ListenAndServeTLS.
KeepAlive bool // HTTP keep-alive are enabled or not.
ServerAgent string // Server Agent.
View *gview.View // View engine for the server.
Rewrites map[string]string // URI rewrite rules.
IndexFiles []string // Static: 默认访问的文件列表
IndexFolder bool // Static: 如果访问目录是否显示目录列表
ServerRoot string // Static: 服务器服务的本地目录根路径(检索优先级比StaticPaths低)
@ -116,12 +116,12 @@ var defaultServerConfig = ServerConfig{
Rewrites: make(map[string]string),
}
// 获取默认的http server设置
// Config returns the default ServerConfig object.
func Config() ServerConfig {
return defaultServerConfig
}
// 通过Map创建Config配置对象Map没有传递的属性将会使用模块的默认值
// ConfigFromMap creates and returns a ServerConfig object with given map.
func ConfigFromMap(m map[string]interface{}) (ServerConfig, error) {
config := defaultServerConfig
if err := gconv.Struct(m, &config); err != nil {
@ -130,12 +130,13 @@ func ConfigFromMap(m map[string]interface{}) (ServerConfig, error) {
return config, nil
}
// http server setting设置。
// 注意使用该方法进行http server配置时需要配置所有的配置项否则没有配置的属性将会默认变量为空
// Handler returns the request handler of the server.
func (s *Server) Handler() http.Handler {
return s.config.Handler
}
// SetConfig sets the configuration for the server.
func (s *Server) SetConfig(c ServerConfig) error {
if c.Handler == nil {
c.Handler = http.HandlerFunc(s.defaultHttpHandle)
}
s.config = c
// Static.
if c.ServerRoot != "" {
@ -148,8 +149,7 @@ func (s *Server) SetConfig(c ServerConfig) error {
return nil
}
// 通过map设置http server setting。
// 注意使用该方法进行http server配置时需要配置所有的配置项否则没有配置的属性将会默认变量为空
// SetConfigWithMap sets the configuration for the server using map.
func (s *Server) SetConfigWithMap(m map[string]interface{}) error {
config, err := ConfigFromMap(m)
if err != nil {
@ -158,12 +158,14 @@ func (s *Server) SetConfigWithMap(m map[string]interface{}) error {
return s.SetConfig(config)
}
// 设置http server参数 - Addr
// SetAddr sets the listening address for the server.
// The address is like ':80', '0.0.0.0:80', '127.0.0.1:80', '180.18.99.10:80', etc.
func (s *Server) SetAddr(address string) {
s.config.Address = address
}
// 设置http server参数 - Port
// SetPort sets the listening ports for the server.
// The listening ports can be multiple.
func (s *Server) SetPort(port ...int) {
if len(port) > 0 {
s.config.Address = ""
@ -176,12 +178,13 @@ func (s *Server) SetPort(port ...int) {
}
}
// 设置http server参数 - HTTPS Addr
// SetHTTPSAddr sets the HTTPS listening ports for the server.
func (s *Server) SetHTTPSAddr(address string) {
s.config.HTTPSAddr = address
}
// 设置http server参数 - HTTPS Port
// SetHTTPSPort sets the HTTPS listening ports for the server.
// The listening ports can be multiple.
func (s *Server) SetHTTPSPort(port ...int) {
if len(port) > 0 {
s.config.HTTPSAddr = ""
@ -194,7 +197,8 @@ func (s *Server) SetHTTPSPort(port ...int) {
}
}
// 开启HTTPS支持但是必须提供Cert和Key文件tlsConfig为可选项
// EnableHTTPS enables HTTPS with given certification and key files for the server.
// The optional parameter <tlsConfig> specifies custom TLS configuration.
func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...*tls.Config) {
certFileRealPath := gfile.RealPath(certFile)
if certFileRealPath == "" {
@ -223,47 +227,47 @@ func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...*tls.Config)
}
}
// 设置TLS配置对象
// SetTLSConfig sets custom TLS configuration and enables HTTPS feature for the server.
func (s *Server) SetTLSConfig(tlsConfig *tls.Config) {
s.config.TLSConfig = tlsConfig
}
// 设置http server参数 - ReadTimeout
// SetReadTimeout sets the ReadTimeout for the server.
func (s *Server) SetReadTimeout(t time.Duration) {
s.config.ReadTimeout = t
}
// 设置http server参数 - WriteTimeout
// SetWriteTimeout sets the WriteTimeout for the server.
func (s *Server) SetWriteTimeout(t time.Duration) {
s.config.WriteTimeout = t
}
// 设置http server参数 - IdleTimeout
// SetIdleTimeout sets the IdleTimeout for the server.
func (s *Server) SetIdleTimeout(t time.Duration) {
s.config.IdleTimeout = t
}
// 设置http server参数 - MaxHeaderBytes
// SetMaxHeaderBytes sets the MaxHeaderBytes for the server.
func (s *Server) SetMaxHeaderBytes(b int) {
s.config.MaxHeaderBytes = b
}
// 设置http server参数 - ServerAgent
// SetServerAgent sets the ServerAgent for the server.
func (s *Server) SetServerAgent(agent string) {
s.config.ServerAgent = agent
}
// 设置KeepAlive
// SetKeepAlive sets the KeepAlive for the server.
func (s *Server) SetKeepAlive(enabled bool) {
s.config.KeepAlive = enabled
}
// 设置模板引擎对象
// SetView sets the View for the server.
func (s *Server) SetView(view *gview.View) {
s.config.View = view
}
// 获取WebServer名称
// GetName returns the name of the server.
func (s *Server) GetName() string {
return s.name
}

View File

@ -32,7 +32,7 @@ type staticServeFile struct {
}
// 默认HTTP Server处理入口http包底层默认使用了gorutine异步处理请求所以这里不再异步执行
func (s *Server) defaultHttpHandle(w http.ResponseWriter, r *http.Request) {
func (s *Server) defaultHandler(w http.ResponseWriter, r *http.Request) {
s.handleRequest(w, r)
}

View File

@ -296,13 +296,31 @@ func (c *Config) GetFileName() string {
return c.name.Val()
}
// getJson returns a *gjson.Json object for the specified <file> content.
// It would print error if file reading fails.
// If any error occurs, it return nil.
func (c *Config) getJson(file ...string) *gjson.Json {
name := c.name.Val()
if len(file) > 0 {
// Available checks and returns whether configuration of given <file> is available.
func (c *Config) Available(file ...string) bool {
var name string
if len(file) > 0 && file[0] != "" {
name = file[0]
} else {
name = c.name.Val()
}
if c.FilePath(name) != "" {
return true
}
if GetContent(name) != "" {
return true
}
return false
}
// getJson returns a *gjson.Json object for the specified <file> content.
// It would print error if file reading fails. It return nil if any error occurs.
func (c *Config) getJson(file ...string) *gjson.Json {
var name string
if len(file) > 0 && file[0] != "" {
name = file[0]
} else {
name = c.name.Val()
}
r := c.jsons.GetOrSetFuncLock(name, func() interface{} {
content := ""

View File

@ -114,6 +114,12 @@ func Pwd() string {
return path
}
// Chdir changes the current working directory to the named directory.
// If there is an error, it will be of type *PathError.
func Chdir(dir string) error {
return os.Chdir(dir)
}
// IsFile checks whether given <path> a file, which means it's not a directory.
func IsFile(path string) bool {
s, err := os.Stat(path)