remove error returns from router registry functions of WebServer; add more unit test cases for WebServer

This commit is contained in:
John
2019-03-06 15:21:00 +08:00
parent c8251ed82f
commit 83be1de04c
19 changed files with 1220 additions and 170 deletions

View File

@ -16,10 +16,10 @@ services:
- mysql
before_install:
- pwd
- echo "127.0.0.1 local" >> /etc/hosts
install:
- pwd
- cat /etc/hosts
script:
- cd g

3
g/g.go
View File

@ -39,7 +39,8 @@ type ListIntAny = []map[int]interface{}
type ListIntStr = []map[int]string
type ListIntInt = []map[int]int
// Frequently-used slice type alias.
//
// 常用slice数据结构(使用别名)
type Slice = []interface{}
type SliceAny = []interface{}

View File

@ -9,7 +9,6 @@ package ghttp
import (
"strings"
"github.com/gogf/gf/g/container/gmap"
)
// 域名管理器对象
@ -18,121 +17,80 @@ type Domain struct {
m map[string]bool // 多域名
}
// 域名对象表,用以存储和检索域名(支持多域名)与域名对象之间的关联关系
var domainMap = gmap.NewStringInterfaceMap()
// 生成一个域名对象
// 生成一个域名对象, 参数 domains 支持给定多个域名。
func (s *Server) Domain(domains string) *Domain {
if r := domainMap.Get(domains); r != nil {
return r.(*Domain)
}
d := &Domain{
s : s,
m : make(map[string]bool),
}
result := strings.Split(domains, ",")
for _, v := range result {
for _, v := range strings.Split(domains, ",") {
d.m[strings.TrimSpace(v)] = true
}
domainMap.Set(domains, d)
return d
}
// 注意该方法是直接绑定方法的内存地址,执行的时候直接执行该方法,不会存在初始化新的控制器逻辑
func (d *Domain) BindHandler(pattern string, handler HandlerFunc) error {
func (d *Domain) BindHandler(pattern string, handler HandlerFunc) {
for domain, _ := range d.m {
if err := d.s.BindHandler(pattern + "@" + domain, handler); err != nil {
return err
}
d.s.BindHandler(pattern + "@" + domain, handler)
}
return nil
}
// 执行对象方法
func (d *Domain) BindObject(pattern string, obj interface{}, methods...string) error {
if len(methods) > 0 {
return d.BindObjectMethod(pattern, obj, strings.Join(methods, ","))
}
func (d *Domain) BindObject(pattern string, obj interface{}, methods...string) {
for domain, _ := range d.m {
if err := d.s.BindObject(pattern + "@" + domain, obj); err != nil {
return err
}
d.s.BindObject(pattern + "@" + domain, obj, methods...)
}
return nil
}
// 执行对象方法注册methods参数不区分大小写
func (d *Domain) BindObjectMethod(pattern string, obj interface{}, method string) error {
func (d *Domain) BindObjectMethod(pattern string, obj interface{}, method string) {
for domain, _ := range d.m {
if err := d.s.BindObjectMethod(pattern + "@" + domain, obj, method); err != nil {
return err
}
d.s.BindObjectMethod(pattern + "@" + domain, obj, method)
}
return nil
}
// RESTful执行对象注册
func (d *Domain) BindObjectRest(pattern string, obj interface{}) error {
func (d *Domain) BindObjectRest(pattern string, obj interface{}) {
for domain, _ := range d.m {
if err := d.s.BindObjectRest(pattern + "@" + domain, obj); err != nil {
return err
}
d.s.BindObjectRest(pattern + "@" + domain, obj)
}
return nil
}
// 控制器注册
func (d *Domain) BindController(pattern string, c Controller, methods...string) error {
if len(methods) > 0 {
return d.BindControllerMethod(pattern, c, strings.Join(methods, ","))
}
func (d *Domain) BindController(pattern string, c Controller, methods...string) {
for domain, _ := range d.m {
if err := d.s.BindController(pattern + "@" + domain, c); err != nil {
return err
}
d.s.BindController(pattern + "@" + domain, c, methods...)
}
return nil
}
// 控制器方法注册methods参数区分大小写
func (d *Domain) BindControllerMethod(pattern string, c Controller, method string) error {
func (d *Domain) BindControllerMethod(pattern string, c Controller, method string) {
for domain, _ := range d.m {
if err := d.s.BindControllerMethod(pattern + "@" + domain, c, method); err != nil {
return err
}
d.s.BindControllerMethod(pattern + "@" + domain, c, method)
}
return nil
}
// RESTful控制器注册
func (d *Domain) BindControllerRest(pattern string, c Controller) error {
func (d *Domain) BindControllerRest(pattern string, c Controller) {
for domain, _ := range d.m {
if err := d.s.BindControllerRest(pattern + "@" + domain, c); err != nil {
return err
}
d.s.BindControllerRest(pattern + "@" + domain, c)
}
return nil
}
// 绑定指定的hook回调函数, hook参数的值由ghttp server设定参数不区分大小写
// 目前hook支持Init/Shut
func (d *Domain)BindHookHandler(pattern string, hook string, handler HandlerFunc) error {
func (d *Domain)BindHookHandler(pattern string, hook string, handler HandlerFunc) {
for domain, _ := range d.m {
if err := d.s.BindHookHandler(pattern + "@" + domain, hook, handler); err != nil {
return err
}
d.s.BindHookHandler(pattern + "@" + domain, hook, handler)
}
return nil
}
// 通过map批量绑定回调函数
func (d *Domain)BindHookHandlerByMap(pattern string, hookmap map[string]HandlerFunc) error {
func (d *Domain)BindHookHandlerByMap(pattern string, hookmap map[string]HandlerFunc) {
for domain, _ := range d.m {
if err := d.s.BindHookHandlerByMap(pattern + "@" + domain, hookmap); err != nil {
return err
}
d.s.BindHookHandlerByMap(pattern + "@" + domain, hookmap)
}
return nil
}
// 绑定指定的状态码回调函数

View File

@ -60,10 +60,11 @@ func (s *Server) getHandlerRegisterCallerLine(handler *handlerItem) string {
// 路由注册处理方法。
// 如果带有hook参数表示是回调注册方法; 否则为普通路由执行方法。
func (s *Server) setHandler(pattern string, handler *handlerItem, hook ... string) (resultErr error) {
func (s *Server) setHandler(pattern string, handler *handlerItem, hook ... string) {
// Web Server正常运行时无法动态注册路由方法
if s.Status() == SERVER_STATUS_RUNNING {
return errors.New("cannot bind handler while server running")
glog.Error("cannot bind handler while server running")
return
}
var hookName string
if len(hook) > 0 {
@ -71,29 +72,18 @@ func (s *Server) setHandler(pattern string, handler *handlerItem, hook ... strin
}
domain, method, uri, err := s.parsePattern(pattern)
if err != nil {
return errors.New("invalid pattern")
glog.Error("invalid pattern:", pattern)
return
}
// 注册地址记录及重复注册判断
regkey := s.handlerKey(hookName, method, uri, domain)
caller := s.getHandlerRegisterCallerLine(handler)
if len(hook) == 0 {
if item, ok := s.routesMap[regkey]; ok {
s := fmt.Sprintf(`duplicated route registry "%s", already registered in %s`, pattern, item[0].file)
glog.Errorfln(s)
return errors.New(s)
glog.Errorfln(`duplicated route registry "%s", already registered in %s`, pattern, item[0].file)
return
}
}
defer func() {
if resultErr == nil {
if _, ok := s.routesMap[regkey]; !ok {
s.routesMap[regkey] = make([]registeredRouteItem, 0)
}
s.routesMap[regkey] = append(s.routesMap[regkey], registeredRouteItem {
file : caller,
handler : handler,
})
}
}()
// 路由对象
handler.router = &Router {
@ -193,9 +183,15 @@ func (s *Server) setHandler(pattern string, handler *handlerItem, hook ... strin
l.PushBack(handler)
}
}
//gutil.Dump(s.serveTree)
//gutil.Dump(s.hooksTree)
return nil
// gutil.Dump(s.serveTree)
// gutil.Dump(s.hooksTree)
if _, ok := s.routesMap[regkey]; !ok {
s.routesMap[regkey] = make([]registeredRouteItem, 0)
}
s.routesMap[regkey] = append(s.routesMap[regkey], registeredRouteItem {
file : caller,
handler : handler,
})
}
// 对比两个handlerItem的优先级需要非常注意的是注意新老对比项的参数先后顺序。

View File

@ -18,8 +18,8 @@ import (
)
// 绑定指定的hook回调函数, pattern参数同BindHandler支持命名路由hook参数的值由ghttp server设定参数不区分大小写
func (s *Server)BindHookHandler(pattern string, hook string, handler HandlerFunc) error {
return s.setHandler(pattern, &handlerItem {
func (s *Server)BindHookHandler(pattern string, hook string, handler HandlerFunc) {
s.setHandler(pattern, &handlerItem {
name : runtime.FuncForPC(reflect.ValueOf(handler).Pointer()).Name(),
ctype : nil,
fname : "",
@ -28,13 +28,10 @@ func (s *Server)BindHookHandler(pattern string, hook string, handler HandlerFunc
}
// 通过map批量绑定回调函数
func (s *Server)BindHookHandlerByMap(pattern string, hookmap map[string]HandlerFunc) error {
func (s *Server)BindHookHandlerByMap(pattern string, hookmap map[string]HandlerFunc) {
for k, v := range hookmap {
if err := s.BindHookHandler(pattern, k, v); err != nil {
return err
}
s.BindHookHandler(pattern, k, v)
}
return nil
}
// 事件回调处理,内部使用了缓存处理.

View File

@ -8,20 +8,19 @@
package ghttp
import (
"errors"
"github.com/gogf/gf/g/os/glog"
"github.com/gogf/gf/g/text/gregex"
"strings"
"reflect"
"fmt"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/os/glog"
"github.com/gogf/gf/g/text/gregex"
"github.com/gogf/gf/g/text/gstr"
"reflect"
"strings"
)
// 绑定控制器控制器需要实现gmvc.Controller接口
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
// 第三个参数methods用以指定需要注册的方法支持多个方法名称多个方法以英文“,”号分隔,区分大小写
func (s *Server)BindController(pattern string, c Controller, methods...string) error {
// 绑定控制器,控制器需要实现 gmvc.Controller 接口,
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话,
// 第三个参数methods用以指定需要注册的方法支持多个方法名称多个方法以英文“,”号分隔,区分大小写.
func (s *Server)BindController(pattern string, c Controller, methods...string) {
methodMap := (map[string]bool)(nil)
if len(methods) > 0 {
methodMap = make(map[string]bool)
@ -45,11 +44,7 @@ func (s *Server)BindController(pattern string, c Controller, methods...string) e
continue
}
if _, ok := v.Method(i).Interface().(func()); !ok {
if methodMap != nil {
s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, v.Method(i).Type().String())
glog.Error(s)
return errors.New(s)
}
glog.Errorfln(`invalid method definition "%s", while "func()" is required`, v.Method(i).Type().String())
continue
}
ctlName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "")
@ -71,8 +66,8 @@ func (s *Server)BindController(pattern string, c Controller, methods...string) e
if strings.EqualFold(mname, "Index") && !gregex.IsMatchString(`\{\.\w+\}`, pattern) {
p := gstr.PosR(key, "/index")
k := key[0 : p] + key[p + 6 : ]
if len(k) == 0 {
k = "/"
if len(k) == 0 || k[0] == '@' {
k = "/" + k
}
m[k] = &handlerItem {
name : fmt.Sprintf(`%s.%s.%s`, pkgPath, ctlName, mname),
@ -83,11 +78,11 @@ func (s *Server)BindController(pattern string, c Controller, methods...string) e
}
}
}
return s.bindHandlerByMap(m)
s.bindHandlerByMap(m)
}
// 绑定路由到指定的方法执行
func (s *Server)BindControllerMethod(pattern string, c Controller, method string) error {
// 绑定路由到指定的方法执行, 第三个参数method仅支持一个方法注册不支持多个并且区分大小写。
func (s *Server)BindControllerMethod(pattern string, c Controller, method string) {
m := make(handlerMap)
v := reflect.ValueOf(c)
t := v.Type()
@ -95,12 +90,12 @@ func (s *Server)BindControllerMethod(pattern string, c Controller, method string
mname := strings.TrimSpace(method)
fval := v.MethodByName(mname)
if !fval.IsValid() {
return errors.New("invalid method name:" + mname)
glog.Error("invalid method name:" + mname)
return
}
if _, ok := fval.Interface().(func()); !ok {
s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, fval.Type().String())
glog.Error(s)
return errors.New(s)
glog.Errorfln(`invalid method definition "%s", while "func()" is required`, fval.Type().String())
return
}
pkgPath := t.Elem().PkgPath()
pkgName := gfile.Basename(pkgPath)
@ -116,14 +111,14 @@ func (s *Server)BindControllerMethod(pattern string, c Controller, method string
fname : mname,
faddr : nil,
}
return s.bindHandlerByMap(m)
s.bindHandlerByMap(m)
}
// 绑定控制器(RESTFul)控制器需要实现gmvc.Controller接口
// 方法会识别HTTP方法并做REST绑定处理例如Post方法会绑定到HTTP POST的方法请求处理Delete方法会绑定到HTTP DELETE的方法请求处理
// 因此只会绑定HTTP Method对应的方法其他方法不会自动注册绑定
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
func (s *Server)BindControllerRest(pattern string, c Controller) error {
func (s *Server)BindControllerRest(pattern string, c Controller) {
// 遍历控制器获取方法列表并构造成uri
m := make(handlerMap)
v := reflect.ValueOf(c)
@ -138,9 +133,8 @@ func (s *Server)BindControllerRest(pattern string, c Controller) error {
continue
}
if _, ok := v.Method(i).Interface().(func()); !ok {
s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, v.Method(i).Type().String())
glog.Error(s)
return errors.New(s)
glog.Errorfln(`invalid method definition "%s", while "func()" is required`, v.Method(i).Type().String())
return
}
pkgName := gfile.Basename(pkgPath)
ctlName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "")
@ -156,5 +150,5 @@ func (s *Server)BindControllerRest(pattern string, c Controller) error {
faddr : nil,
}
}
return s.bindHandlerByMap(m)
s.bindHandlerByMap(m)
}

View File

@ -8,17 +8,17 @@
package ghttp
import (
"errors"
"strings"
"github.com/gogf/gf/g/text/gstr"
"bytes"
"runtime"
"github.com/gogf/gf/g/os/glog"
"github.com/gogf/gf/g/text/gstr"
"reflect"
"runtime"
"strings"
)
// 注意该方法是直接绑定函数的内存地址,执行的时候直接执行该方法,不会存在初始化新的控制器逻辑
func (s *Server) BindHandler(pattern string, handler HandlerFunc) error {
return s.bindHandlerItem(pattern, &handlerItem {
func (s *Server) BindHandler(pattern string, handler HandlerFunc) {
s.bindHandlerItem(pattern, &handlerItem {
name : runtime.FuncForPC(reflect.ValueOf(handler).Pointer()).Name(),
rtype : gROUTE_REGISTER_HANDLER,
ctype : nil,
@ -30,21 +30,19 @@ func (s *Server) BindHandler(pattern string, handler HandlerFunc) error {
// 绑定URI到操作函数/方法
// pattern的格式形如/user/list, put:/user, delete:/user, post:/user@johng.cn
// 支持RESTful的请求格式具体业务逻辑由绑定的处理方法来执行
func (s *Server) bindHandlerItem(pattern string, item *handlerItem) error {
func (s *Server) bindHandlerItem(pattern string, item *handlerItem) {
if s.Status() == SERVER_STATUS_RUNNING {
return errors.New("server handlers cannot be changed while running")
glog.Error("server handlers cannot be changed while running")
return
}
return s.setHandler(pattern, item)
s.setHandler(pattern, item)
}
// 通过映射数组绑定URI到操作函数/方法
func (s *Server) bindHandlerByMap(m handlerMap) error {
func (s *Server) bindHandlerByMap(m handlerMap) {
for p, h := range m {
if err := s.bindHandlerItem(p, h); err != nil {
return err
}
s.bindHandlerItem(p, h)
}
return nil
}
// 将内置的名称按照设定的规则合并到pattern中内置名称按照{.xxx}规则命名。

View File

@ -8,19 +8,18 @@
package ghttp
import (
"errors"
"fmt"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/os/glog"
"github.com/gogf/gf/g/text/gregex"
"strings"
"reflect"
"fmt"
"github.com/gogf/gf/g/text/gstr"
"github.com/gogf/gf/g/os/gfile"
"reflect"
"strings"
)
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 第三个参数methods用以指定需要注册的方法支持多个方法名称多个方法以英文“,”号分隔,区分大小写
func (s *Server)BindObject(pattern string, obj interface{}, methods...string) error {
func (s *Server)BindObject(pattern string, obj interface{}, methods...string) {
methodMap := (map[string]bool)(nil)
if len(methods) > 0 {
methodMap = make(map[string]bool)
@ -52,11 +51,7 @@ func (s *Server)BindObject(pattern string, obj interface{}, methods...string) er
}
faddr, ok := v.Method(i).Interface().(func(*Request))
if !ok {
if methodMap != nil {
s := fmt.Sprintf(`invalid medthod definition "%s", while "func(*Request))" is required`, v.Method(i).Type().String())
glog.Error(s)
return errors.New(s)
}
glog.Errorfln(`invalid method definition "%s", while "func(*Request))" is required`, v.Method(i).Type().String())
continue
}
objName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "")
@ -78,8 +73,8 @@ func (s *Server)BindObject(pattern string, obj interface{}, methods...string) er
if strings.EqualFold(mname, "Index") && !gregex.IsMatchString(`\{\.\w+\}`, pattern) {
p := gstr.PosR(key, "/index")
k := key[0 : p] + key[p + 6 : ]
if len(k) == 0 {
k = "/"
if len(k) == 0 || k[0] == '@' {
k = "/" + k
}
m[k] = &handlerItem {
name : fmt.Sprintf(`%s.%s.%s`, pkgPath, objName, mname),
@ -92,12 +87,12 @@ func (s *Server)BindObject(pattern string, obj interface{}, methods...string) er
}
}
}
return s.bindHandlerByMap(m)
s.bindHandlerByMap(m)
}
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 第三个参数methods支持个方法注册,多个方法以英文“,”号分隔,区分大小写
func (s *Server)BindObjectMethod(pattern string, obj interface{}, method string) error {
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 第三个参数method支持个方法注册,不支持多个,并且区分大小写
func (s *Server)BindObjectMethod(pattern string, obj interface{}, method string) {
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
@ -105,13 +100,13 @@ func (s *Server)BindObjectMethod(pattern string, obj interface{}, method string)
mname := strings.TrimSpace(method)
fval := v.MethodByName(mname)
if !fval.IsValid() {
return errors.New("invalid method name:" + mname)
glog.Error("invalid method name:" + mname)
return
}
faddr, ok := fval.Interface().(func(*Request))
if !ok {
s := fmt.Sprintf(`invalid medthod definition "%s", while "func(*Request)" is required`, fval.Type().String())
glog.Error(s)
return errors.New(s)
glog.Errorfln(`invalid method definition "%s", while "func(*Request)" is required`, fval.Type().String())
return
}
finit := (func(*Request))(nil)
fshut := (func(*Request))(nil)
@ -138,12 +133,12 @@ func (s *Server)BindObjectMethod(pattern string, obj interface{}, method string)
fshut : fshut,
}
return s.bindHandlerByMap(m)
s.bindHandlerByMap(m)
}
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 需要注意对象方法的定义必须按照ghttp.HandlerFunc来定义
func (s *Server)BindObjectRest(pattern string, obj interface{}) error {
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面,
// 需要注意对象方法的定义必须按照 ghttp.HandlerFunc 来定义
func (s *Server)BindObjectRest(pattern string, obj interface{}) {
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
@ -165,9 +160,8 @@ func (s *Server)BindObjectRest(pattern string, obj interface{}) error {
}
faddr, ok := v.Method(i).Interface().(func(*Request))
if !ok {
s := fmt.Sprintf(`invalid medthod definition "%s", while "func()" is required`, v.Method(i).Type().String())
glog.Error(s)
return errors.New(s)
glog.Errorfln(`invalid method definition "%s", while "func(*Request)" is required`, v.Method(i).Type().String())
continue
}
pkgName := gfile.Basename(pkgPath)
objName := gstr.Replace(t.String(), fmt.Sprintf(`%s.`, pkgName), "")
@ -185,5 +179,5 @@ func (s *Server)BindObjectRest(pattern string, obj interface{}) error {
fshut : fshut,
}
}
return s.bindHandlerByMap(m)
s.bindHandlerByMap(m)
}

View File

@ -38,9 +38,11 @@ func (c *Controller) Show() {
c.Response.Write("Controller Show")
}
func (c *Controller) Info() {
c.Response.Write("Controller Info")
}
// 控制器注册测试
func Test_Router_Controller(t *testing.T) {
func Test_Router_Controller1(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindController("/", new(Controller))
@ -71,3 +73,58 @@ func Test_Router_Controller(t *testing.T) {
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_Controller2(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindController("/controller", new(Controller), "Show, Info")
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("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "1Controller Show2")
gtest.Assert(client.GetContent("/controller/info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_ControllerMethod(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindControllerMethod("/controller-info", new(Controller), "Info")
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("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "Not Found")
gtest.Assert(client.GetContent("/controller/info"), "Not Found")
gtest.Assert(client.GetContent("/controller-info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}

View File

@ -0,0 +1,338 @@
// 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_DomainBasic(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
d := s.Domain("localhost, local")
d.BindHandler("/:name", func(r *ghttp.Request){
r.Response.Write("/:name")
})
d.BindHandler("/:name/update", func(r *ghttp.Request){
r.Response.Write(r.Get("name"))
})
d.BindHandler("/:name/:action", func(r *ghttp.Request){
r.Response.Write(r.Get("action"))
})
d.BindHandler("/:name/*any", func(r *ghttp.Request){
r.Response.Write(r.Get("any"))
})
d.BindHandler("/user/list/{field}.html", func(r *ghttp.Request){
r.Response.Write(r.Get("field"))
})
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("/john"), "Not Found")
gtest.Assert(client.GetContent("/john/update"), "Not Found")
gtest.Assert(client.GetContent("/john/edit"), "Not Found")
gtest.Assert(client.GetContent("/user/list/100.html"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/john"), "")
gtest.Assert(client.GetContent("/john/update"), "john")
gtest.Assert(client.GetContent("/john/edit"), "edit")
gtest.Assert(client.GetContent("/user/list/100.html"), "100")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/john"), "")
gtest.Assert(client.GetContent("/john/update"), "john")
gtest.Assert(client.GetContent("/john/edit"), "edit")
gtest.Assert(client.GetContent("/user/list/100.html"), "100")
})
}
// 测试HTTP Method注册.
func Test_Router_DomainMethod(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
d := s.Domain("localhost, local")
d.BindHandler("GET:/get", func(r *ghttp.Request){
})
d.BindHandler("POST:/post", func(r *ghttp.Request){
})
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))
resp1, err := client.Get("/get")
defer resp1.Close()
gtest.Assert(err, nil)
gtest.Assert(resp1.StatusCode, 404)
resp2, err := client.Post("/get")
defer resp2.Close()
gtest.Assert(err, nil)
gtest.Assert(resp2.StatusCode, 404)
resp3, err := client.Get("/post")
defer resp3.Close()
gtest.Assert(err, nil)
gtest.Assert(resp3.StatusCode, 404)
resp4, err := client.Post("/post")
defer resp4.Close()
gtest.Assert(err, nil)
gtest.Assert(resp4.StatusCode, 404)
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
resp1, err := client.Get("/get")
defer resp1.Close()
gtest.Assert(err, nil)
gtest.Assert(resp1.StatusCode, 200)
resp2, err := client.Post("/get")
defer resp2.Close()
gtest.Assert(err, nil)
gtest.Assert(resp2.StatusCode, 404)
resp3, err := client.Get("/post")
defer resp3.Close()
gtest.Assert(err, nil)
gtest.Assert(resp3.StatusCode, 404)
resp4, err := client.Post("/post")
defer resp4.Close()
gtest.Assert(err, nil)
gtest.Assert(resp4.StatusCode, 200)
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
resp1, err := client.Get("/get")
defer resp1.Close()
gtest.Assert(err, nil)
gtest.Assert(resp1.StatusCode, 200)
resp2, err := client.Post("/get")
defer resp2.Close()
gtest.Assert(err, nil)
gtest.Assert(resp2.StatusCode, 404)
resp3, err := client.Get("/post")
defer resp3.Close()
gtest.Assert(err, nil)
gtest.Assert(resp3.StatusCode, 404)
resp4, err := client.Post("/post")
defer resp4.Close()
gtest.Assert(err, nil)
gtest.Assert(resp4.StatusCode, 200)
})
}
// 测试状态返回.
func Test_Router_DomainStatus(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
d := s.Domain("localhost, local")
d.BindHandler("/200", func(r *ghttp.Request){
r.Response.WriteStatus(200)
})
d.BindHandler("/300", func(r *ghttp.Request){
r.Response.WriteStatus(300)
})
d.BindHandler("/400", func(r *ghttp.Request){
r.Response.WriteStatus(400)
})
d.BindHandler("/500", func(r *ghttp.Request){
r.Response.WriteStatus(500)
})
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))
resp1, err := client.Get("/200")
defer resp1.Close()
gtest.Assert(err, nil)
gtest.Assert(resp1.StatusCode, 404)
resp2, err := client.Get("/300")
defer resp2.Close()
gtest.Assert(err, nil)
gtest.Assert(resp2.StatusCode, 404)
resp3, err := client.Get("/400")
defer resp3.Close()
gtest.Assert(err, nil)
gtest.Assert(resp3.StatusCode, 404)
resp4, err := client.Get("/500")
defer resp4.Close()
gtest.Assert(err, nil)
gtest.Assert(resp4.StatusCode, 404)
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
resp1, err := client.Get("/200")
defer resp1.Close()
gtest.Assert(err, nil)
gtest.Assert(resp1.StatusCode, 200)
resp2, err := client.Get("/300")
defer resp2.Close()
gtest.Assert(err, nil)
gtest.Assert(resp2.StatusCode, 300)
resp3, err := client.Get("/400")
defer resp3.Close()
gtest.Assert(err, nil)
gtest.Assert(resp3.StatusCode, 400)
resp4, err := client.Get("/500")
defer resp4.Close()
gtest.Assert(err, nil)
gtest.Assert(resp4.StatusCode, 500)
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
resp1, err := client.Get("/200")
defer resp1.Close()
gtest.Assert(err, nil)
gtest.Assert(resp1.StatusCode, 200)
resp2, err := client.Get("/300")
defer resp2.Close()
gtest.Assert(err, nil)
gtest.Assert(resp2.StatusCode, 300)
resp3, err := client.Get("/400")
defer resp3.Close()
gtest.Assert(err, nil)
gtest.Assert(resp3.StatusCode, 400)
resp4, err := client.Get("/500")
defer resp4.Close()
gtest.Assert(err, nil)
gtest.Assert(resp4.StatusCode, 500)
})
}
// 自定义状态码处理.
func Test_Router_DomainCustomStatusHandler(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
d := s.Domain("localhost, local")
d.BindHandler("/", func(r *ghttp.Request){
r.Response.Write("hello")
})
d.BindStatusHandler(404, func(r *ghttp.Request){
r.Response.Write("404 page")
})
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("/ThisDoesNotExist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "hello")
gtest.Assert(client.GetContent("/ThisDoesNotExist"), "404 page")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "hello")
gtest.Assert(client.GetContent("/ThisDoesNotExist"), "404 page")
})
}
// 测试不存在的路由.
func Test_Router_Domain404(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
d := s.Domain("localhost, local")
d.BindHandler("/", func(r *ghttp.Request){
r.Response.Write("hello")
})
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.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "hello")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "hello")
})
}

View File

@ -0,0 +1,127 @@
// 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/frame/gmvc"
"github.com/gogf/gf/g/net/ghttp"
"github.com/gogf/gf/g/test/gtest"
"testing"
"time"
)
type DomainControllerRest struct {
gmvc.Controller
}
func (c *DomainControllerRest) Init(r *ghttp.Request) {
c.Controller.Init(r)
c.Response.Write("1")
}
func (c *DomainControllerRest) Shut() {
c.Response.Write("2")
}
func (c *DomainControllerRest) Get() {
c.Response.Write("Controller Get")
}
func (c *DomainControllerRest) Put() {
c.Response.Write("Controller Put")
}
func (c *DomainControllerRest) Post() {
c.Response.Write("Controller Post")
}
func (c *DomainControllerRest) Delete() {
c.Response.Write("Controller Delete")
}
func (c *DomainControllerRest) Patch() {
c.Response.Write("Controller Patch")
}
func (c *DomainControllerRest) Options() {
c.Response.Write("Controller Options")
}
func (c *DomainControllerRest) Head() {
c.Response.Header().Set("head-ok", "1")
}
// 控制器注册测试
func Test_Router_DomainControllerRest(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
d := s.Domain("localhost, local")
d.BindControllerRest("/", new(DomainControllerRest))
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.PutContent("/"), "Not Found")
gtest.Assert(client.PostContent("/"), "Not Found")
gtest.Assert(client.DeleteContent("/"), "Not Found")
gtest.Assert(client.PatchContent("/"), "Not Found")
gtest.Assert(client.OptionsContent("/"), "Not Found")
resp1, err := client.Head("/")
if err == nil {
defer resp1.Close()
}
gtest.Assert(err, nil)
gtest.Assert(resp1.Header.Get("head-ok"), "")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "1Controller Get2")
gtest.Assert(client.PutContent("/"), "1Controller Put2")
gtest.Assert(client.PostContent("/"), "1Controller Post2")
gtest.Assert(client.DeleteContent("/"), "1Controller Delete2")
gtest.Assert(client.PatchContent("/"), "1Controller Patch2")
gtest.Assert(client.OptionsContent("/"), "1Controller Options2")
resp1, err := client.Head("/")
if err == nil {
defer resp1.Close()
}
gtest.Assert(err, nil)
gtest.Assert(resp1.Header.Get("head-ok"), "1")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "1Controller Get2")
gtest.Assert(client.PutContent("/"), "1Controller Put2")
gtest.Assert(client.PostContent("/"), "1Controller Post2")
gtest.Assert(client.DeleteContent("/"), "1Controller Delete2")
gtest.Assert(client.PatchContent("/"), "1Controller Patch2")
gtest.Assert(client.OptionsContent("/"), "1Controller Options2")
resp1, err := client.Head("/")
if err == nil {
defer resp1.Close()
}
gtest.Assert(err, nil)
gtest.Assert(resp1.Header.Get("head-ok"), "1")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}

View File

@ -0,0 +1,202 @@
// 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/frame/gmvc"
"github.com/gogf/gf/g/net/ghttp"
"github.com/gogf/gf/g/test/gtest"
"testing"
"time"
)
type DomainController struct {
gmvc.Controller
}
func (c *DomainController) Init(r *ghttp.Request) {
c.Controller.Init(r)
c.Response.Write("1")
}
func (c *DomainController) Shut() {
c.Response.Write("2")
}
func (c *DomainController) Index() {
c.Response.Write("Controller Index")
}
func (c *DomainController) Show() {
c.Response.Write("Controller Show")
}
func (c *DomainController) Info() {
c.Response.Write("Controller Info")
}
func Test_Router_DomainController1(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.Domain("localhost, local").BindController("/", new(DomainController))
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("/init"), "Not Found")
gtest.Assert(client.GetContent("/shut"), "Not Found")
gtest.Assert(client.GetContent("/index"), "Not Found")
gtest.Assert(client.GetContent("/show"), "Not Found")
gtest.Assert(client.GetContent("/info"), "Not Found")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "1Controller Index2")
gtest.Assert(client.GetContent("/init"), "Not Found")
gtest.Assert(client.GetContent("/shut"), "Not Found")
gtest.Assert(client.GetContent("/index"), "1Controller Index2")
gtest.Assert(client.GetContent("/show"), "1Controller Show2")
gtest.Assert(client.GetContent("/info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "1Controller Index2")
gtest.Assert(client.GetContent("/init"), "Not Found")
gtest.Assert(client.GetContent("/shut"), "Not Found")
gtest.Assert(client.GetContent("/index"), "1Controller Index2")
gtest.Assert(client.GetContent("/show"), "1Controller Show2")
gtest.Assert(client.GetContent("/info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_DomainController2(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.Domain("localhost, local").BindController("/controller", new(DomainController), "Show, Info")
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("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "Not Found")
gtest.Assert(client.GetContent("/controller/info"), "Not Found")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "1Controller Show2")
gtest.Assert(client.GetContent("/controller/info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "1Controller Show2")
gtest.Assert(client.GetContent("/controller/info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_DomainControllerMethod(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.Domain("localhost, local").BindControllerMethod("/controller-info", new(DomainController), "Info")
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("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "Not Found")
gtest.Assert(client.GetContent("/controller/info"), "Not Found")
gtest.Assert(client.GetContent("/controller-info"), "Not Found")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "Not Found")
gtest.Assert(client.GetContent("/controller/info"), "Not Found")
gtest.Assert(client.GetContent("/controller-info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/controller"), "Not Found")
gtest.Assert(client.GetContent("/controller/init"), "Not Found")
gtest.Assert(client.GetContent("/controller/shut"), "Not Found")
gtest.Assert(client.GetContent("/controller/index"), "Not Found")
gtest.Assert(client.GetContent("/controller/show"), "Not Found")
gtest.Assert(client.GetContent("/controller/info"), "Not Found")
gtest.Assert(client.GetContent("/controller-info"), "1Controller Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}

View File

@ -0,0 +1,122 @@
// 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"
)
type DomainObjectRest struct {}
func (o *DomainObjectRest) Init(r *ghttp.Request) {
r.Response.Write("1")
}
func (o *DomainObjectRest) Shut(r *ghttp.Request) {
r.Response.Write("2")
}
func (o *DomainObjectRest) Get(r *ghttp.Request) {
r.Response.Write("Object Get")
}
func (o *DomainObjectRest) Put(r *ghttp.Request) {
r.Response.Write("Object Put")
}
func (o *DomainObjectRest) Post(r *ghttp.Request) {
r.Response.Write("Object Post")
}
func (o *DomainObjectRest) Delete(r *ghttp.Request) {
r.Response.Write("Object Delete")
}
func (o *DomainObjectRest) Patch(r *ghttp.Request) {
r.Response.Write("Object Patch")
}
func (o *DomainObjectRest) Options(r *ghttp.Request) {
r.Response.Write("Object Options")
}
func (o *DomainObjectRest) Head(r *ghttp.Request) {
r.Response.Header().Set("head-ok", "1")
}
func Test_Router_DomainObjectRest(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
d := s.Domain("localhost, local")
d.BindObjectRest("/", new(DomainObjectRest))
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.PutContent("/"), "Not Found")
gtest.Assert(client.PostContent("/"), "Not Found")
gtest.Assert(client.DeleteContent("/"), "Not Found")
gtest.Assert(client.PatchContent("/"), "Not Found")
gtest.Assert(client.OptionsContent("/"), "Not Found")
resp1, err := client.Head("/")
if err == nil {
defer resp1.Close()
}
gtest.Assert(err, nil)
gtest.Assert(resp1.Header.Get("head-ok"), "")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "1Object Get2")
gtest.Assert(client.PutContent("/"), "1Object Put2")
gtest.Assert(client.PostContent("/"), "1Object Post2")
gtest.Assert(client.DeleteContent("/"), "1Object Delete2")
gtest.Assert(client.PatchContent("/"), "1Object Patch2")
gtest.Assert(client.OptionsContent("/"), "1Object Options2")
resp1, err := client.Head("/")
if err == nil {
defer resp1.Close()
}
gtest.Assert(err, nil)
gtest.Assert(resp1.Header.Get("head-ok"), "1")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "1Object Get2")
gtest.Assert(client.PutContent("/"), "1Object Put2")
gtest.Assert(client.PostContent("/"), "1Object Post2")
gtest.Assert(client.DeleteContent("/"), "1Object Delete2")
gtest.Assert(client.PatchContent("/"), "1Object Patch2")
gtest.Assert(client.OptionsContent("/"), "1Object Options2")
resp1, err := client.Head("/")
if err == nil {
defer resp1.Close()
}
gtest.Assert(err, nil)
gtest.Assert(resp1.Header.Get("head-ok"), "1")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}

View File

@ -0,0 +1,196 @@
// 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"
)
type DomainObject struct {}
func (o *DomainObject) Init(r *ghttp.Request) {
r.Response.Write("1")
}
func (o *DomainObject) Shut(r *ghttp.Request) {
r.Response.Write("2")
}
func (o *DomainObject) Index(r *ghttp.Request) {
r.Response.Write("Object Index")
}
func (o *DomainObject) Show(r *ghttp.Request) {
r.Response.Write("Object Show")
}
func (o *DomainObject) Info(r *ghttp.Request) {
r.Response.Write("Object Info")
}
func Test_Router_DomainObject1(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.Domain("localhost, local").BindObject("/", new(DomainObject))
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("/init"), "Not Found")
gtest.Assert(client.GetContent("/shut"), "Not Found")
gtest.Assert(client.GetContent("/index"), "Not Found")
gtest.Assert(client.GetContent("/show"), "Not Found")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "1Object Index2")
gtest.Assert(client.GetContent("/init"), "Not Found")
gtest.Assert(client.GetContent("/shut"), "Not Found")
gtest.Assert(client.GetContent("/index"), "1Object Index2")
gtest.Assert(client.GetContent("/show"), "1Object Show2")
gtest.Assert(client.GetContent("/info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "1Object Index2")
gtest.Assert(client.GetContent("/init"), "Not Found")
gtest.Assert(client.GetContent("/shut"), "Not Found")
gtest.Assert(client.GetContent("/index"), "1Object Index2")
gtest.Assert(client.GetContent("/show"), "1Object Show2")
gtest.Assert(client.GetContent("/info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_DomainObject2(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.Domain("localhost, local").BindObject("/object", new(DomainObject), "Show, Info")
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("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "Not Found")
gtest.Assert(client.GetContent("/object/info"), "Not Found")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "1Object Show2")
gtest.Assert(client.GetContent("/object/info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "1Object Show2")
gtest.Assert(client.GetContent("/object/info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_DomainObjectMethod(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.Domain("localhost, local").BindObjectMethod("/object-info", new(DomainObject), "Info")
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("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "Not Found")
gtest.Assert(client.GetContent("/object/info"), "Not Found")
gtest.Assert(client.GetContent("/object-info"), "Not Found")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://localhost:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "Not Found")
gtest.Assert(client.GetContent("/object/info"), "Not Found")
gtest.Assert(client.GetContent("/object-info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
gtest.Case(t, func() {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://local:%d", p))
gtest.Assert(client.GetContent("/"), "Not Found")
gtest.Assert(client.GetContent("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "Not Found")
gtest.Assert(client.GetContent("/object/info"), "Not Found")
gtest.Assert(client.GetContent("/object-info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}

View File

@ -0,0 +1,8 @@
// 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

View File

@ -33,8 +33,11 @@ func (o *Object) Show(r *ghttp.Request) {
r.Response.Write("Object Show")
}
// 执行对象注册
func Test_Router_Object(t *testing.T) {
func (o *Object) Info(r *ghttp.Request) {
r.Response.Write("Object Info")
}
func Test_Router_Object1(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindObject("/", new(Object))
@ -65,3 +68,59 @@ func Test_Router_Object(t *testing.T) {
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_Object2(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindObject("/object", new(Object), "Show, Info")
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("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "1Object Show2")
gtest.Assert(client.GetContent("/object/info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}
func Test_Router_ObjectMethod(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindObjectMethod("/object-info", new(Object), "Info")
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("/object"), "Not Found")
gtest.Assert(client.GetContent("/object/init"), "Not Found")
gtest.Assert(client.GetContent("/object/shut"), "Not Found")
gtest.Assert(client.GetContent("/object/index"), "Not Found")
gtest.Assert(client.GetContent("/object/show"), "Not Found")
gtest.Assert(client.GetContent("/object/info"), "Not Found")
gtest.Assert(client.GetContent("/object-info"), "1Object Info2")
gtest.Assert(client.GetContent("/none-exist"), "Not Found")
})
}

View File

@ -37,6 +37,8 @@ type Config struct {
vc *gtype.Bool // 层级检索是否执行分隔符冲突检测(默认为false检测会比较影响检索效率)
}
// New returns a new configuration management object.
//
// 生成一个配置管理对象
func New(path string, file...string) *Config {
name := DEFAULT_CONFIG_FILE
@ -55,6 +57,8 @@ func New(path string, file...string) *Config {
return c
}
// filePath returns the absolute configuration file path for the given filename by <file>.
//
// 判断从哪个配置文件中获取内容,返回配置文件的绝对路径
func (c *Config) filePath(file...string) (path string) {
name := c.name.Val()

View File

@ -23,7 +23,6 @@ import (
func Case(t *testing.T, f func()) {
defer func() {
if err := recover(); err != nil {
panic(err)
fmt.Fprintf(os.Stderr, "%v\n%s", err, getBacktrace())
t.Fail()
}

View File

@ -13,7 +13,7 @@ func Hello2(r *ghttp.Request) {
func main() {
s := ghttp.GetServer()
s.Domain("127.0.0.1").BindHandler("/", Hello1)
s.Domain("localhost").BindHandler("/", Hello2)
s.Domain("localhost, local").BindHandler("/", Hello2)
s.SetPort(8199)
s.Run()
}