From 0cce858641c46a83492a0cb3b652f3181c33f80d Mon Sep 17 00:00:00 2001 From: John Date: Thu, 28 Nov 2019 23:19:37 +0800 Subject: [PATCH] improve configuration feature for ghttp.Server/gview/glog --- database/gdb/gdb_config.go | 4 +- frame/gins/gins.go | 41 +++++++--- frame/gins/gins_basic_test.go | 29 ++++--- frame/gins/gins_config_test.go | 87 +++++++++++---------- frame/gins/gins_database_test.go | 11 ++- frame/gins/gins_redis_test.go | 13 ++-- frame/gins/gins_view_test.go | 106 ++++++++++++++++++++++++-- frame/gins/testdata/view1/config.toml | 14 ++++ frame/gins/testdata/view1/test1.html | 1 + frame/gins/testdata/view1/test2.html | 1 + frame/gins/testdata/view2/config.toml | 8 ++ frame/gins/testdata/view2/test.html | 1 + net/ghttp/ghttp_response_view.go | 2 +- net/ghttp/ghttp_response_writer.go | 4 +- net/ghttp/ghttp_server.go | 4 +- net/ghttp/ghttp_server_config.go | 90 +++++++++++----------- net/ghttp/ghttp_server_handler.go | 2 +- os/gcfg/gcfg.go | 30 ++++++-- os/gfile/gfile.go | 6 ++ 19 files changed, 311 insertions(+), 143 deletions(-) create mode 100644 frame/gins/testdata/view1/config.toml create mode 100644 frame/gins/testdata/view1/test1.html create mode 100644 frame/gins/testdata/view1/test2.html create mode 100644 frame/gins/testdata/view2/config.toml create mode 100644 frame/gins/testdata/view2/test.html diff --git a/database/gdb/gdb_config.go b/database/gdb/gdb_config.go index 56806f353..9d1c17113 100644 --- a/database/gdb/gdb_config.go +++ b/database/gdb/gdb_config.go @@ -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, ) diff --git a/frame/gins/gins.go b/frame/gins/gins.go index 085965162..b0be17db9 100644 --- a/frame/gins/gins.go +++ b/frame/gins/gins.go @@ -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) } diff --git a/frame/gins/gins_basic_test.go b/frame/gins/gins_basic_test.go index 38ab63909..8322dacb7 100644 --- a/frame/gins/gins_basic_test.go +++ b/frame/gins/gins_basic_test.go @@ -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) }) } diff --git a/frame/gins/gins_config_test.go b/frame/gins/gins_config_test.go index 82c727fb8..6d250a36b 100644 --- a/frame/gins/gins_config_test.go +++ b/frame/gins/gins_config_test.go @@ -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") }) } diff --git a/frame/gins/gins_database_test.go b/frame/gins/gins_database_test.go index 1a86f9bd8..9e652c881 100644 --- a/frame/gins/gins_database_test.go +++ b/frame/gins/gins_database_test.go @@ -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) diff --git a/frame/gins/gins_redis_test.go b/frame/gins/gins_redis_test.go index 0eb25eb86..933203b49 100644 --- a/frame/gins/gins_redis_test.go +++ b/frame/gins/gins_redis_test.go @@ -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) diff --git a/frame/gins/gins_view_test.go b/frame/gins/gins_view_test.go index 84fddeef2..51733f5c5 100644 --- a/frame/gins/gins_view_test.go +++ b/frame/gins/gins_view_test.go @@ -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") + }) +} diff --git a/frame/gins/testdata/view1/config.toml b/frame/gins/testdata/view1/config.toml new file mode 100644 index 000000000..b74e6fa83 --- /dev/null +++ b/frame/gins/testdata/view1/config.toml @@ -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" + diff --git a/frame/gins/testdata/view1/test1.html b/frame/gins/testdata/view1/test1.html new file mode 100644 index 000000000..ee7e6d285 --- /dev/null +++ b/frame/gins/testdata/view1/test1.html @@ -0,0 +1 @@ +test1:${.name} \ No newline at end of file diff --git a/frame/gins/testdata/view1/test2.html b/frame/gins/testdata/view1/test2.html new file mode 100644 index 000000000..2fd32690b --- /dev/null +++ b/frame/gins/testdata/view1/test2.html @@ -0,0 +1 @@ +test2:#{.name} \ No newline at end of file diff --git a/frame/gins/testdata/view2/config.toml b/frame/gins/testdata/view2/config.toml new file mode 100644 index 000000000..48f4b42ca --- /dev/null +++ b/frame/gins/testdata/view2/config.toml @@ -0,0 +1,8 @@ + + +[view] + defaultFile = "test.html" + delimiters = ["{", "}"] + [view.data] + name = "test" + diff --git a/frame/gins/testdata/view2/test.html b/frame/gins/testdata/view2/test.html new file mode 100644 index 000000000..926bb9712 --- /dev/null +++ b/frame/gins/testdata/view2/test.html @@ -0,0 +1 @@ +test:{.name} \ No newline at end of file diff --git a/net/ghttp/ghttp_response_view.go b/net/ghttp/ghttp_response_view.go index 983b4d24f..90ecba06b 100644 --- a/net/ghttp/ghttp_response_view.go +++ b/net/ghttp/ghttp_response_view.go @@ -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() diff --git a/net/ghttp/ghttp_response_writer.go b/net/ghttp/ghttp_response_writer.go index 646596e46..e24ecc6e3 100644 --- a/net/ghttp/ghttp_response_writer.go +++ b/net/ghttp/ghttp_response_writer.go @@ -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() } } diff --git a/net/ghttp/ghttp_server.go b/net/ghttp/ghttp_server.go index 2a3f2afe5..22d6bcbca 100644 --- a/net/ghttp/ghttp_server.go +++ b/net/ghttp/ghttp_server.go @@ -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. diff --git a/net/ghttp/ghttp_server_config.go b/net/ghttp/ghttp_server_config.go index 3abde8d6c..637163fea 100644 --- a/net/ghttp/ghttp_server_config.go +++ b/net/ghttp/ghttp_server_config.go @@ -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 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 } diff --git a/net/ghttp/ghttp_server_handler.go b/net/ghttp/ghttp_server_handler.go index f5d1481d4..8d91e1403 100644 --- a/net/ghttp/ghttp_server_handler.go +++ b/net/ghttp/ghttp_server_handler.go @@ -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) } diff --git a/os/gcfg/gcfg.go b/os/gcfg/gcfg.go index 78eee2438..196e9cc1f 100644 --- a/os/gcfg/gcfg.go +++ b/os/gcfg/gcfg.go @@ -296,13 +296,31 @@ func (c *Config) GetFileName() string { return c.name.Val() } -// getJson returns a *gjson.Json object for the specified 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 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 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 := "" diff --git a/os/gfile/gfile.go b/os/gfile/gfile.go index 03de36dbf..52debd0f1 100644 --- a/os/gfile/gfile.go +++ b/os/gfile/gfile.go @@ -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 a file, which means it's not a directory. func IsFile(path string) bool { s, err := os.Stat(path)