From 51e70be04dfcc67134859649eb627f378a4dfe59 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 10 Dec 2018 20:24:20 +0800 Subject: [PATCH] Add rewrite feature to WebServer; Add Unique for un sorted array of garray; Fix map conversion issue of gjson. --- g/container/garray/garray_int.go | 14 ++++++ g/container/garray/garray_interface.go | 14 ++++++ g/container/garray/garray_sorted_int.go | 2 +- g/container/garray/garray_string.go | 14 ++++++ g/container/garray/garray_test.go | 26 +++++++++++ g/encoding/gjson/gjson.go | 2 +- g/net/ghttp/ghttp_server_config.go | 35 +++++---------- g/net/ghttp/ghttp_server_config_route.go | 54 +++++++++++++++++++++++ g/net/ghttp/ghttp_server_config_static.go | 13 +++++- g/net/ghttp/ghttp_server_handler.go | 6 +++ geg/container/garray/array_unique.go | 17 +++++++ geg/database/orm/mysql/gdb_value.go | 9 ++-- geg/other/test2.go | 17 ++++--- 13 files changed, 186 insertions(+), 37 deletions(-) create mode 100644 g/container/garray/garray_test.go create mode 100644 g/net/ghttp/ghttp_server_config_route.go create mode 100644 geg/container/garray/array_unique.go diff --git a/g/container/garray/garray_int.go b/g/container/garray/garray_int.go index 295fa1198..e2c64c3d3 100644 --- a/g/container/garray/garray_int.go +++ b/g/container/garray/garray_int.go @@ -136,6 +136,20 @@ func (a *IntArray) Search(value int) int { return result } +// 清理数组中重复的元素项 +func (a *IntArray) Unique() *IntArray { + a.mu.Lock() + for i := 0; i < len(a.array) - 1; i++ { + for j := i + 1; j < len(a.array); j++ { + if a.array[i] == a.array[j] { + a.array = append(a.array[ : j], a.array[j + 1 : ]...) + } + } + } + a.mu.Unlock() + return a +} + // 使用自定义方法执行加锁修改操作 func (a *IntArray) LockFunc(f func(array []int)) { a.mu.Lock(true) diff --git a/g/container/garray/garray_interface.go b/g/container/garray/garray_interface.go index 82b187279..d2f7c9e0f 100644 --- a/g/container/garray/garray_interface.go +++ b/g/container/garray/garray_interface.go @@ -163,6 +163,20 @@ func (a *Array) Search(value interface{}) int { return result } +// 清理数组中重复的元素项 +func (a *Array) Unique() *Array { + a.mu.Lock() + for i := 0; i < len(a.array) - 1; i++ { + for j := i + 1; j < len(a.array); j++ { + if a.array[i] == a.array[j] { + a.array = append(a.array[ : j], a.array[j + 1 : ]...) + } + } + } + a.mu.Unlock() + return a +} + // 使用自定义方法执行加锁修改操作 func (a *Array) LockFunc(f func(array []interface{})) { a.mu.Lock(true) diff --git a/g/container/garray/garray_sorted_int.go b/g/container/garray/garray_sorted_int.go index b11a1ee1e..6506004d9 100644 --- a/g/container/garray/garray_sorted_int.go +++ b/g/container/garray/garray_sorted_int.go @@ -16,7 +16,7 @@ type SortedIntArray struct { mu *rwmutex.RWMutex // 互斥锁 cap int // 初始化设置的数组容量 array []int // 底层数组 - unique *gtype.Bool // 是否要求不能重复 + unique *gtype.Bool // 是否要求不能重复(默认false) compareFunc func(v1, v2 int) int // 比较函数,返回值 -1: v1 < v2;0: v1 == v2;1: v1 > v2 } diff --git a/g/container/garray/garray_string.go b/g/container/garray/garray_string.go index 3276f957c..c7384dd32 100644 --- a/g/container/garray/garray_string.go +++ b/g/container/garray/garray_string.go @@ -135,6 +135,20 @@ func (a *StringArray) Search(value string) int { return result } +// 清理数组中重复的元素项 +func (a *StringArray) Unique() *StringArray { + a.mu.Lock() + for i := 0; i < len(a.array) - 1; i++ { + for j := i + 1; j < len(a.array); j++ { + if a.array[i] == a.array[j] { + a.array = append(a.array[ : j], a.array[j + 1 : ]...) + } + } + } + a.mu.Unlock() + return a +} + // 使用自定义方法执行加锁修改操作 func (a *StringArray) LockFunc(f func(array []string)) { a.mu.Lock(true) diff --git a/g/container/garray/garray_test.go b/g/container/garray/garray_test.go new file mode 100644 index 000000000..dcfc0b47e --- /dev/null +++ b/g/container/garray/garray_test.go @@ -0,0 +1,26 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +// go test *.go + +package garray_test + +import ( + "fmt" + "gitee.com/johng/gf/g/container/garray" + "testing" +) + + +func TestArray_Unique(t *testing.T) { + expect := []int{1, 2, 3, 4, 5, 6} + array := garray.NewIntArray(0, 0) + array.Append(1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6) + array.Unique() + if fmt.Sprint(array.Slice()) != fmt.Sprint(expect) { + t.Errorf("get: %v, expect: %v\n", array.Slice(), expect) + } +} diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 11888807d..e5b5b6d2f 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -49,7 +49,7 @@ func New(value interface{}, safe...bool) *Json { } default: v := (interface{})(nil) - if m := gconv.Map(value); len(m) > 0 { + if m := gconv.Map(value); m != nil { v = m j = &Json { p : &v, diff --git a/g/net/ghttp/ghttp_server_config.go b/g/net/ghttp/ghttp_server_config.go index dd91b75cf..3dc441b84 100644 --- a/g/net/ghttp/ghttp_server_config.go +++ b/g/net/ghttp/ghttp_server_config.go @@ -63,11 +63,13 @@ type ServerConfig struct { SessionMaxAge int // Session有效期 SessionIdName string // SessionId名称 - // ip访问控制 + // IP访问控制 DenyIps []string // 不允许访问的ip列表,支持ip前缀过滤,如: 10 将不允许10开头的ip访问 AllowIps []string // 仅允许访问的ip列表,支持ip前缀过滤,如: 10 将仅允许10开头的ip访问 + // 路由访问控制 DenyRoutes []string // 不允许访问的路由规则列表 + Rewrites map[string]string // URI Rewrite重写配置 // 日志配置 LogPath string // 存放日志的目录路径 @@ -113,6 +115,7 @@ var defaultServerConfig = ServerConfig { DumpRouteMap : true, RouterCacheExpire : 60, + Rewrites : make(map[string]string), } // 获取默认的http server设置 @@ -195,10 +198,16 @@ func (s *Server)EnableHTTPS(certFile, keyFile string) { return } certFileRealPath := gfile.RealPath(certFile) + if certFileRealPath == "" { + certFileRealPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + certFileRealPath) + } if certFileRealPath == "" { glog.Fatal(fmt.Sprintf(`[ghttp] EnableHTTPS failed: certFile "%s" does not exist`, certFile)) } keyFileRealPath := gfile.RealPath(keyFile) + if keyFileRealPath == "" { + keyFileRealPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + keyFileRealPath) + } if keyFileRealPath == "" { glog.Fatal(fmt.Sprintf(`[ghttp] EnableHTTPS failed: keyFile "%s" does not exist`, keyFile)) } @@ -252,30 +261,6 @@ func (s *Server)SetServerAgent(agent string) { s.config.ServerAgent = agent } -func (s *Server) SetDenyIps(ips []string) { - if s.Status() == SERVER_STATUS_RUNNING { - glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) - return - } - s.config.DenyIps = ips -} - -func (s *Server) SetAllowIps(ips []string) { - if s.Status() == SERVER_STATUS_RUNNING { - glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) - return - } - s.config.AllowIps = ips -} - -func (s *Server) SetDenyRoutes(routes []string) { - if s.Status() == SERVER_STATUS_RUNNING { - glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) - return - } - s.config.DenyRoutes = routes -} - func (s *Server) SetGzipContentTypes(types []string) { if s.Status() == SERVER_STATUS_RUNNING { glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) diff --git a/g/net/ghttp/ghttp_server_config_route.go b/g/net/ghttp/ghttp_server_config_route.go new file mode 100644 index 000000000..ea60da519 --- /dev/null +++ b/g/net/ghttp/ghttp_server_config_route.go @@ -0,0 +1,54 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + + +package ghttp + +import "gitee.com/johng/gf/g/os/glog" + +func (s *Server) SetDenyIps(ips []string) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + s.config.DenyIps = ips +} + +func (s *Server) SetAllowIps(ips []string) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + s.config.AllowIps = ips +} + +func (s *Server) SetDenyRoutes(routes []string) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + s.config.DenyRoutes = routes +} + +// 设置URI重写规则 +func (s *Server) SetRewrite(uri string, rewrite string) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + s.config.Rewrites[uri] = rewrite +} + +// 设置URI重写规则(批量) +func (s *Server) SetRewriteMap(rewrites map[string]string) { + if s.Status() == SERVER_STATUS_RUNNING { + glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) + return + } + for k, v := range rewrites { + s.config.Rewrites[k] = v + } +} \ No newline at end of file diff --git a/g/net/ghttp/ghttp_server_config_static.go b/g/net/ghttp/ghttp_server_config_static.go index b00720424..f395ccc94 100644 --- a/g/net/ghttp/ghttp_server_config_static.go +++ b/g/net/ghttp/ghttp_server_config_static.go @@ -58,13 +58,16 @@ func (s *Server)SetServerRoot(root string) { } // RealPath的作用除了校验地址正确性以外,还转换分隔符号为当前系统正确的文件分隔符号 path := gfile.RealPath(root) + if path == "" { + path = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + root) + } if path == "" { glog.Fatal(fmt.Sprintf(`[ghttp] SetServerRoot failed: path "%s" does not exist`, root)) } s.config.SearchPaths = []string{strings.TrimRight(path, gfile.Separator)} } -// 添加静态文件搜索目录,必须给定目录的绝对路径 +// 添加静态文件搜索**目录**,必须给定目录的绝对路径 func (s *Server) AddSearchPath(path string) { if s.Status() == SERVER_STATUS_RUNNING { glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) @@ -72,13 +75,16 @@ func (s *Server) AddSearchPath(path string) { } // RealPath的作用除了校验地址正确性以外,还转换分隔符号为当前系统正确的文件分隔符号 realPath := gfile.RealPath(path) + if realPath == "" { + realPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + path) + } if realPath == "" { glog.Fatal(fmt.Sprintf(`[ghttp] AddSearchPath failed: path "%s" does not exist`, path)) } s.config.SearchPaths = append(s.config.SearchPaths, realPath) } -// 添加URI与静态目录的映射 +// 添加URI与静态**目录**的映射 func (s *Server) AddStaticPath(prefix string, path string) { if s.Status() == SERVER_STATUS_RUNNING { glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR) @@ -86,6 +92,9 @@ func (s *Server) AddStaticPath(prefix string, path string) { } // RealPath的作用除了校验地址正确性以外,还转换分隔符号为当前系统正确的文件分隔符号 realPath := gfile.RealPath(path) + if realPath == "" { + realPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + path) + } if realPath == "" { glog.Fatal(fmt.Sprintf(`[ghttp] AddStaticPath failed: path "%s" does not exist`, path)) } diff --git a/g/net/ghttp/ghttp_server_handler.go b/g/net/ghttp/ghttp_server_handler.go index f66c6099e..e42afe621 100644 --- a/g/net/ghttp/ghttp_server_handler.go +++ b/g/net/ghttp/ghttp_server_handler.go @@ -29,6 +29,12 @@ func (s *Server)defaultHttpHandle(w http.ResponseWriter, r *http.Request) { // 其次,如果没有对应的自定义处理接口配置,那么走默认的域名处理接口配置; // 最后,如果以上都没有找到处理接口,那么进行文件处理; func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { + // 重写规则判断 + if len(s.config.Rewrites) > 0 { + if rewrite, ok := s.config.Rewrites[r.URL.Path]; ok { + r.URL.Path = rewrite + } + } // 去掉末尾的"/"号 if r.URL.Path != "/" { for r.URL.Path[len(r.URL.Path) - 1] == '/' { diff --git a/geg/container/garray/array_unique.go b/geg/container/garray/array_unique.go new file mode 100644 index 000000000..dc932f243 --- /dev/null +++ b/geg/container/garray/array_unique.go @@ -0,0 +1,17 @@ +package main + +import "fmt" + +func main() { + array := []uint{1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6} + for i := 0; i < len(array) - 1; i++ { + for j := i + 1; j < len(array); j++ { + if array[i] == array[j] { + array = append(array[ : j], array[j + 1 : ]...) + } + } + } + fmt.Println(array) + + +} \ No newline at end of file diff --git a/geg/database/orm/mysql/gdb_value.go b/geg/database/orm/mysql/gdb_value.go index d3e894fac..ad9a2ba1a 100644 --- a/geg/database/orm/mysql/gdb_value.go +++ b/geg/database/orm/mysql/gdb_value.go @@ -3,6 +3,7 @@ package main import ( "gitee.com/johng/gf/g/database/gdb" "fmt" + "gitee.com/johng/gf/g/encoding/gparser" ) func main() { @@ -23,9 +24,11 @@ func main() { // 开启调试模式,以便于记录所有执行的SQL db.SetDebug(true) - r, _ := db.Table("user").Where("uid=?", 1).One() + r, _ := db.Table("user").All() if r != nil { - fmt.Println(r["uid"].Int()) - fmt.Println(r["name"].String()) + fmt.Println(r.ToList()) + b, e := gparser.VarToJson(r.ToList()) + fmt.Println(e) + fmt.Println(string(b)) } } \ No newline at end of file diff --git a/geg/other/test2.go b/geg/other/test2.go index 7316220fc..f4c6e4826 100644 --- a/geg/other/test2.go +++ b/geg/other/test2.go @@ -2,12 +2,19 @@ package main import ( "fmt" - "gitee.com/johng/gf/g/encoding/gbinary" ) + +func Map() map[int]int { + return nil +} + + func main() { - pid := 41902 - b := gbinary.EncodeByLength(2, pid) - fmt.Println(b) - fmt.Println(gbinary.DecodeToInt(b)) + v := (interface{})(nil) + fmt.Println(v == nil) + if v = Map(); v != nil { + fmt.Println(v == nil) + } + fmt.Println(Map() == nil) } \ No newline at end of file