diff --git a/g/net/ghttp/ghttp_response.go b/g/net/ghttp/ghttp_response.go index 705ee2856..b756df942 100644 --- a/g/net/ghttp/ghttp_response.go +++ b/g/net/ghttp/ghttp_response.go @@ -45,13 +45,10 @@ func (r *Response) Write(content ... interface{}) { return } for _, v := range content { - switch v.(type) { - case []byte: - // 如果是二进制数据,那么返回二进制数据 - r.buffer.Write(gconv.Bytes(v)) - + switch value := v.(type) { + case []byte: r.buffer.Write(value) + case string: r.buffer.WriteString(value) default: - // 否则一律按照可显示的字符串进行转换 r.buffer.WriteString(gconv.String(v)) } } diff --git a/g/net/ghttp/ghttp_server_router.go b/g/net/ghttp/ghttp_server_router.go index f56a07563..96d26ecd6 100644 --- a/g/net/ghttp/ghttp_server_router.go +++ b/g/net/ghttp/ghttp_server_router.go @@ -75,6 +75,10 @@ func (s *Server) setHandler(pattern string, handler *handlerItem, hook ... strin glog.Error("invalid pattern:", pattern) return } + if len(uri) == 0 || uri[0] != '/' { + glog.Error("invalid pattern:", pattern) + return + } // 注册地址记录及重复注册判断 regkey := s.handlerKey(hookName, method, uri, domain) caller := s.getHandlerRegisterCallerLine(handler) diff --git a/g/net/ghttp/ghttp_unit_init_test.go b/g/net/ghttp/ghttp_unit_init_test.go index e7bd6c78f..66e853c37 100644 --- a/g/net/ghttp/ghttp_unit_init_test.go +++ b/g/net/ghttp/ghttp_unit_init_test.go @@ -17,7 +17,7 @@ var ( ) func init() { - for i := 8000; i <= 8100; i++ { + for i := 8000; i <= 9000; i++ { ports.Append(i) } } diff --git a/g/net/ghttp/ghttp_unit_router_exit_test.go b/g/net/ghttp/ghttp_unit_router_exit_test.go new file mode 100644 index 000000000..1b2881ee7 --- /dev/null +++ b/g/net/ghttp/ghttp_unit_router_exit_test.go @@ -0,0 +1,126 @@ +// 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_test + +import ( + "fmt" + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/net/ghttp" + "github.com/gogf/gf/g/test/gtest" + "testing" + "time" +) + +func Test_Router_Exit(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.BindHookHandlerByMap("/*", map[string]ghttp.HandlerFunc{ + "BeforeServe" : func(r *ghttp.Request){ r.Response.Write("1") }, + "AfterServe" : func(r *ghttp.Request){ r.Response.Write("2") }, + "BeforeOutput" : func(r *ghttp.Request){ r.Response.Write("3") }, + "AfterOutput" : func(r *ghttp.Request){ r.Response.Write("4") }, + "BeforeClose" : func(r *ghttp.Request){ r.Response.Write("5") }, + "AfterClose" : func(r *ghttp.Request){ r.Response.Write("6") }, + }) + s.BindHandler("/test/test", func(r *ghttp.Request) { + r.Response.Write("test-start") + r.Exit() + r.Response.Write("test-end") + }) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "123") + gtest.Assert(client.GetContent("/test/test"), "1test-start23") + }) +} + +func Test_Router_ExitHook(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.BindHandler("/priority/show", func(r *ghttp.Request) { + r.Response.Write("show") + }) + + s.BindHookHandlerByMap("/priority/:name", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("1") + }, + }) + s.BindHookHandlerByMap("/priority/*any", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("2") + }, + }) + s.BindHookHandlerByMap("/priority/show", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("3") + r.ExitHook() + }, + }) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Not Found") + gtest.Assert(client.GetContent("/priority/show"), "3show") + }) +} + +func Test_Router_ExitAll(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.BindHandler("/priority/show", func(r *ghttp.Request) { + r.Response.Write("show") + }) + + s.BindHookHandlerByMap("/priority/:name", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("1") + }, + }) + s.BindHookHandlerByMap("/priority/*any", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("2") + }, + }) + s.BindHookHandlerByMap("/priority/show", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("3") + r.ExitAll() + }, + }) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Not Found") + gtest.Assert(client.GetContent("/priority/show"), "3") + }) +} \ No newline at end of file diff --git a/g/net/ghttp/ghttp_unit_router_hook_test.go b/g/net/ghttp/ghttp_unit_router_hook_test.go new file mode 100644 index 000000000..3fb7bf3c2 --- /dev/null +++ b/g/net/ghttp/ghttp_unit_router_hook_test.go @@ -0,0 +1,87 @@ +// 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_test + +import ( + "fmt" + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/net/ghttp" + "github.com/gogf/gf/g/test/gtest" + "testing" + "time" +) + +func Test_Router_Hook_Basic(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.BindHookHandlerByMap("/*", map[string]ghttp.HandlerFunc{ + "BeforeServe" : func(r *ghttp.Request){ r.Response.Write("1") }, + "AfterServe" : func(r *ghttp.Request){ r.Response.Write("2") }, + "BeforeOutput" : func(r *ghttp.Request){ r.Response.Write("3") }, + "AfterOutput" : func(r *ghttp.Request){ r.Response.Write("4") }, + "BeforeClose" : func(r *ghttp.Request){ r.Response.Write("5") }, + "AfterClose" : func(r *ghttp.Request){ r.Response.Write("6") }, + }) + s.BindHandler("/test/test", func(r *ghttp.Request) { + r.Response.Write("test") + }) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "123") + gtest.Assert(client.GetContent("/test/test"), "1test23") + }) +} + +func Test_Router_Hook_Priority(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.BindHandler("/priority/show", func(r *ghttp.Request) { + r.Response.Write("show") + }) + + s.BindHookHandlerByMap("/priority/:name", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("1") + }, + }) + s.BindHookHandlerByMap("/priority/*any", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("2") + }, + }) + s.BindHookHandlerByMap("/priority/show", map[string]ghttp.HandlerFunc { + "BeforeServe" : func(r *ghttp.Request) { + r.Response.Write("3") + }, + }) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Not Found") + gtest.Assert(client.GetContent("/priority/show"), "312show") + gtest.Assert(client.GetContent("/priority/any/any"), "2") + gtest.Assert(client.GetContent("/priority/name"), "12") + }) +} + diff --git a/g/net/ghttp/ghttp_unit_router_names_test.go b/g/net/ghttp/ghttp_unit_router_names_test.go index f39a7aa2e..9cd388d37 100644 --- a/g/net/ghttp/ghttp_unit_router_names_test.go +++ b/g/net/ghttp/ghttp_unit_router_names_test.go @@ -6,3 +6,107 @@ package ghttp_test +import ( + "fmt" + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/net/ghttp" + "github.com/gogf/gf/g/test/gtest" + "testing" + "time" +) + +type NamesObject struct {} + +func (o *NamesObject) ShowName(r *ghttp.Request) { + r.Response.Write("Object Show Name") +} + +func Test_NameToUri_FullName(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_FULLNAME) + s.BindObject("/{.struct}/{.method}", new(NamesObject)) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetBrowserMode(true) + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + gtest.Assert(client.GetContent("/"), "Not Found") + gtest.Assert(client.GetContent("/NamesObject"), "Not Found") + gtest.Assert(client.GetContent("/NamesObject/ShowName"), "Object Show Name") + }) +} + + +func Test_NameToUri_AllLower(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_ALLLOWER) + s.BindObject("/{.struct}/{.method}", new(NamesObject)) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetBrowserMode(true) + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + gtest.Assert(client.GetContent("/"), "Not Found") + gtest.Assert(client.GetContent("/NamesObject"), "Not Found") + gtest.Assert(client.GetContent("/namesobject/showname"), "Object Show Name") + }) +} + +func Test_NameToUri_Camel(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_CAMEL) + s.BindObject("/{.struct}/{.method}", new(NamesObject)) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetBrowserMode(true) + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + gtest.Assert(client.GetContent("/"), "Not Found") + gtest.Assert(client.GetContent("/NamesObject"), "Not Found") + gtest.Assert(client.GetContent("/namesObject/showName"), "Object Show Name") + }) +} + +func Test_NameToUri_Default(t *testing.T) { + p := ports.PopRand() + s := g.Server(p) + s.SetNameToUriType(ghttp.NAME_TO_URI_TYPE_DEFAULT) + s.BindObject("/{.struct}/{.method}", new(NamesObject)) + s.SetPort(p) + s.SetDumpRouteMap(false) + s.Start() + defer s.Shutdown() + + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(t, func() { + client := ghttp.NewClient() + client.SetBrowserMode(true) + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + gtest.Assert(client.GetContent("/"), "Not Found") + gtest.Assert(client.GetContent("/NamesObject"), "Not Found") + gtest.Assert(client.GetContent("/names-object/show-name"), "Object Show Name") + }) +} + diff --git a/g/net/ghttp/ghttp_unit_static_test.go b/g/net/ghttp/ghttp_unit_static_test.go new file mode 100644 index 000000000..ac0c6d89d --- /dev/null +++ b/g/net/ghttp/ghttp_unit_static_test.go @@ -0,0 +1,232 @@ +// 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_test + +import ( + "fmt" + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/net/ghttp" + "github.com/gogf/gf/g/os/gfile" + "github.com/gogf/gf/g/test/gtest" + "testing" + "time" +) + +func Test_Static_Folder_Forbidden(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + defer gfile.Remove(path) + gfile.PutContents(path + "/test.html", "test") + s.SetServerRoot(path) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Forbidden") + gtest.Assert(client.GetContent("/index.html"), "Not Found") + gtest.Assert(client.GetContent("/test.html"), "test") + }) +} + +func Test_Static_IndexFolder(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + defer gfile.Remove(path) + gfile.PutContents(path + "/test.html", "test") + s.SetIndexFolder(true) + s.SetServerRoot(path) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.AssertNE(client.GetContent("/"), "Forbidden") + gtest.Assert(client.GetContent("/index.html"), "Not Found") + gtest.Assert(client.GetContent("/test.html"), "test") + }) +} + +func Test_Static_IndexFiles1(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + defer gfile.Remove(path) + gfile.PutContents(path + "/index.html", "index") + gfile.PutContents(path + "/test.html", "test") + s.SetServerRoot(path) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "index") + gtest.Assert(client.GetContent("/index.html"), "index") + gtest.Assert(client.GetContent("/test.html"), "test") + }) +} + +func Test_Static_IndexFiles2(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + defer gfile.Remove(path) + gfile.PutContents(path + "/test.html", "test") + s.SetIndexFiles([]string{"index.html", "test.html"}) + s.SetServerRoot(path) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "test") + gtest.Assert(client.GetContent("/index.html"), "Not Found") + gtest.Assert(client.GetContent("/test.html"), "test") + }) +} + +func Test_Static_AddSearchPath1(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path1 := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + path2 := fmt.Sprintf(`%s/ghttp/static/test/%d/%d`, gfile.TempDir(), p, p) + defer gfile.Remove(path1) + defer gfile.Remove(path2) + gfile.PutContents(path2 + "/test.html", "test") + s.SetServerRoot(path1) + s.AddSearchPath(path2) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Forbidden") + gtest.Assert(client.GetContent("/test.html"), "test") + }) +} + +func Test_Static_AddSearchPath2(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path1 := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + path2 := fmt.Sprintf(`%s/ghttp/static/test/%d/%d`, gfile.TempDir(), p, p) + defer gfile.Remove(path1) + defer gfile.Remove(path2) + gfile.PutContents(path1 + "/test.html", "test1") + gfile.PutContents(path2 + "/test.html", "test2") + s.SetServerRoot(path1) + s.AddSearchPath(path2) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Forbidden") + gtest.Assert(client.GetContent("/test.html"), "test1") + }) +} + +func Test_Static_AddStaticPath(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path1 := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + path2 := fmt.Sprintf(`%s/ghttp/static/test/%d/%d`, gfile.TempDir(), p, p) + defer gfile.Remove(path1) + defer gfile.Remove(path2) + gfile.PutContents(path1 + "/test.html", "test1") + gfile.PutContents(path2 + "/test.html", "test2") + s.SetServerRoot(path1) + s.AddStaticPath("/my-test", path2) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Forbidden") + gtest.Assert(client.GetContent("/test.html"), "test1") + gtest.Assert(client.GetContent("/my-test/test.html"), "test2") + }) +} + +func Test_Static_AddStaticPath_Priority(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path1 := fmt.Sprintf(`%s/ghttp/static/test/%d/test`, gfile.TempDir(), p) + path2 := fmt.Sprintf(`%s/ghttp/static/test/%d/%d/test`, gfile.TempDir(), p, p) + defer gfile.Remove(path1) + defer gfile.Remove(path2) + gfile.PutContents(path1 + "/test.html", "test1") + gfile.PutContents(path2 + "/test.html", "test2") + s.SetServerRoot(path1) + s.AddStaticPath("/test", path2) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Forbidden") + gtest.Assert(client.GetContent("/test.html"), "test1") + gtest.Assert(client.GetContent("/test/test.html"), "test2") + }) +} + +func Test_Static_Rewrite(t *testing.T) { + gtest.Case(t, func() { + p := ports.PopRand() + s := g.Server(p) + path := fmt.Sprintf(`%s/ghttp/static/test/%d`, gfile.TempDir(), p) + defer gfile.Remove(path) + gfile.PutContents(path + "/test1.html", "test1") + gfile.PutContents(path + "/test2.html", "test2") + s.SetServerRoot(path) + s.SetRewrite("/test.html", "/test1.html") + s.SetRewriteMap(g.MapStrStr{ + "/my-test1" : "/test1.html", + "/my-test2" : "/test2.html", + }) + s.SetPort(p) + s.Start() + defer s.Shutdown() + time.Sleep(time.Second) + client := ghttp.NewClient() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) + + gtest.Assert(client.GetContent("/"), "Forbidden") + gtest.Assert(client.GetContent("/test.html"), "test1") + gtest.Assert(client.GetContent("/test1.html"), "test1") + gtest.Assert(client.GetContent("/test2.html"), "test2") + gtest.Assert(client.GetContent("/my-test1"), "test1") + gtest.Assert(client.GetContent("/my-test2"), "test2") + }) +} \ No newline at end of file