From f62e96bdff3d5a8957122b444a74f6e3ffc9c272 Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Fri, 16 Jun 2023 11:34:59 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=9D=A1=E4=BB=B6=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=A2=9E=E5=8A=A0=E2=80=9CURL=E9=80=9A=E9=85=8D?= =?UTF-8?q?=E7=AC=A6=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/serverconfigs/shared/http_request_cond.go | 78 ++++++++++++------- .../shared/http_request_cond_test.go | 77 +++++++++++++++++- pkg/serverconfigs/shared/request_operators.go | 35 +++++++-- 3 files changed, 153 insertions(+), 37 deletions(-) diff --git a/pkg/serverconfigs/shared/http_request_cond.go b/pkg/serverconfigs/shared/http_request_cond.go index e4a93f7..d1e3cf3 100644 --- a/pkg/serverconfigs/shared/http_request_cond.go +++ b/pkg/serverconfigs/shared/http_request_cond.go @@ -5,12 +5,10 @@ import ( "encoding/binary" "encoding/json" "errors" - "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/lists" "github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/utils/string" "net" - "os" "path/filepath" "regexp" "strings" @@ -59,6 +57,20 @@ func (this *HTTPRequestCond) Init() error { return err } this.regValue = reg + } else if lists.ContainsString([]string{ + RequestCondOperatorWildcardMatch, + RequestCondOperatorWildcardNotMatch, + }, this.Operator) { + var pieces = strings.Split(this.Value, "*") + for index, piece := range pieces { + pieces[index] = regexp.QuoteMeta(piece) + } + var pattern = strings.Join(pieces, "(.*)") + reg, err := regexp.Compile("(?i)" /** 大小写不敏感 **/ + "^" + pattern + "$") + if err != nil { + return err + } + this.regValue = reg } else if lists.ContainsString([]string{ RequestCondOperatorEqFloat, RequestCondOperatorGtFloat, @@ -162,6 +174,16 @@ func (this *HTTPRequestCond) match(formatter func(source string) string) bool { return false } return !this.regValue.MatchString(paramValue) + case RequestCondOperatorWildcardMatch: + if this.regValue == nil { + return false + } + return this.regValue.MatchString(paramValue) + case RequestCondOperatorWildcardNotMatch: + if this.regValue == nil { + return false + } + return !this.regValue.MatchString(paramValue) case RequestCondOperatorEqInt: return this.isInt && paramValue == this.Value case RequestCondOperatorEqFloat: @@ -373,32 +395,32 @@ func (this *HTTPRequestCond) match(formatter func(source string) string) bool { return this.ipToInt64(net.ParseIP(paramValue))%10 == types.Int64(this.Value) case RequestCondOperatorIPMod100: return this.ipToInt64(net.ParseIP(paramValue))%100 == types.Int64(this.Value) - case RequestCondOperatorFileExist: - index := strings.Index(paramValue, "?") - if index > -1 { - paramValue = paramValue[:index] - } - if len(paramValue) == 0 { - return false - } - if !filepath.IsAbs(paramValue) { - paramValue = Tea.Root + Tea.DS + paramValue - } - stat, err := os.Stat(paramValue) - return err == nil && !stat.IsDir() - case RequestCondOperatorFileNotExist: - index := strings.Index(paramValue, "?") - if index > -1 { - paramValue = paramValue[:index] - } - if len(paramValue) == 0 { - return true - } - if !filepath.IsAbs(paramValue) { - paramValue = Tea.Root + Tea.DS + paramValue - } - stat, err := os.Stat(paramValue) - return err != nil || stat.IsDir() + /**case RequestCondOperatorFileExist: + index := strings.Index(paramValue, "?") + if index > -1 { + paramValue = paramValue[:index] + } + if len(paramValue) == 0 { + return false + } + if !filepath.IsAbs(paramValue) { + paramValue = Tea.Root + Tea.DS + paramValue + } + stat, err := os.Stat(paramValue) + return err == nil && !stat.IsDir() + case RequestCondOperatorFileNotExist: + index := strings.Index(paramValue, "?") + if index > -1 { + paramValue = paramValue[:index] + } + if len(paramValue) == 0 { + return true + } + if !filepath.IsAbs(paramValue) { + paramValue = Tea.Root + Tea.DS + paramValue + } + stat, err := os.Stat(paramValue) + return err != nil || stat.IsDir()**/ } return false diff --git a/pkg/serverconfigs/shared/http_request_cond_test.go b/pkg/serverconfigs/shared/http_request_cond_test.go index ea67883..f7d5e15 100644 --- a/pkg/serverconfigs/shared/http_request_cond_test.go +++ b/pkg/serverconfigs/shared/http_request_cond_test.go @@ -3,7 +3,6 @@ package shared import ( "bytes" "fmt" - "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/assert" "net" "regexp" @@ -85,6 +84,78 @@ func TestRequestCond_Compare1(t *testing.T) { })) } + { + var cond = HTTPRequestCond{ + Param: "/hello", + Operator: RequestCondOperatorWildcardMatch, + Value: "/*", + } + a.IsNil(cond.Init()) + a.IsTrue(cond.Match(func(format string) string { + return format + })) + } + + { + var cond = HTTPRequestCond{ + Param: "/hello/world", + Operator: RequestCondOperatorWildcardMatch, + Value: "/*/world", + } + a.IsNil(cond.Init()) + a.IsTrue(cond.Match(func(format string) string { + return format + })) + } + + { + var cond = HTTPRequestCond{ + Param: "/hello/world", + Operator: RequestCondOperatorWildcardMatch, + Value: "/H*/world", + } + a.IsNil(cond.Init()) + a.IsTrue(cond.Match(func(format string) string { + return format + })) + } + + { + var cond = HTTPRequestCond{ + Param: "/hello", + Operator: RequestCondOperatorWildcardMatch, + Value: "/hello/*", + } + a.IsNil(cond.Init()) + a.IsFalse(cond.Match(func(format string) string { + return format + })) + } + + { + var cond = HTTPRequestCond{ + Param: "/hello/world", + Operator: RequestCondOperatorWildcardNotMatch, + Value: "/hello/*", + } + a.IsNil(cond.Init()) + a.IsFalse(cond.Match(func(format string) string { + return format + })) + } + + { + var cond = HTTPRequestCond{ + Param: "/hello", + Operator: RequestCondOperatorWildcardNotMatch, + Value: "/hello/*", + } + a.IsNil(cond.Init()) + a.IsTrue(cond.Match(func(format string) string { + return format + })) + } + { cond := HTTPRequestCond{ Param: "123.123", @@ -687,7 +758,7 @@ func TestRequestCond_File(t *testing.T) { })) } - { + /**{ cond := HTTPRequestCond{ Param: "a.png", Operator: RequestCondOperatorFileExist, @@ -762,7 +833,7 @@ func TestRequestCond_File(t *testing.T) { a.IsFalse(cond.Match(func(source string) string { return source })) - } + }**/ } func TestRequestCond_MimeType(t *testing.T) { diff --git a/pkg/serverconfigs/shared/request_operators.go b/pkg/serverconfigs/shared/request_operators.go index aa543b2..db90696 100644 --- a/pkg/serverconfigs/shared/request_operators.go +++ b/pkg/serverconfigs/shared/request_operators.go @@ -2,15 +2,23 @@ package shared import "github.com/iwind/TeaGo/maps" -// 运算符定义 +// RequestCondOperator 运算符定义 type RequestCondOperator = string const ( + // 正则 + RequestCondOperatorRegexp RequestCondOperator = "regexp" RequestCondOperatorNotRegexp RequestCondOperator = "not regexp" + // 通配符 + + RequestCondOperatorWildcardMatch RequestCondOperator = "wildcard match" + RequestCondOperatorWildcardNotMatch RequestCondOperator = "wildcard not match" + // 数字相关 + RequestCondOperatorEqInt RequestCondOperator = "eq int" // 整数等于 RequestCondOperatorEqFloat RequestCondOperator = "eq float" // 浮点数等于 RequestCondOperatorGtFloat RequestCondOperator = "gt" @@ -19,11 +27,13 @@ const ( RequestCondOperatorLteFloat RequestCondOperator = "lte" // 取模 + RequestCondOperatorMod10 RequestCondOperator = "mod 10" RequestCondOperatorMod100 RequestCondOperator = "mod 100" RequestCondOperatorMod RequestCondOperator = "mod" // 字符串相关 + RequestCondOperatorEqString RequestCondOperator = "eq" RequestCondOperatorNeqString RequestCondOperator = "not" RequestCondOperatorHasPrefix RequestCondOperator = "prefix" @@ -37,6 +47,7 @@ const ( RequestCondOperatorVersionRange RequestCondOperator = "version range" // IP相关 + RequestCondOperatorEqIP RequestCondOperator = "eq ip" RequestCondOperatorGtIP RequestCondOperator = "gt ip" RequestCondOperatorGteIP RequestCondOperator = "gte ip" @@ -48,11 +59,13 @@ const ( RequestCondOperatorIPMod RequestCondOperator = "ip mod" // 文件相关 - RequestCondOperatorFileExist RequestCondOperator = "file exist" - RequestCondOperatorFileNotExist RequestCondOperator = "file not exist" + // 为了安全暂时不提供 + + //RequestCondOperatorFileExist RequestCondOperator = "file exist" + //RequestCondOperatorFileNotExist RequestCondOperator = "file not exist" ) -// 所有的运算符 +// AllRequestOperators 所有的运算符 func AllRequestOperators() []maps.Map { return []maps.Map{ { @@ -65,6 +78,16 @@ func AllRequestOperators() []maps.Map { "op": RequestCondOperatorNotRegexp, "description": "判断是否正则表达式不匹配", }, + { + "name": "通配符匹配", + "op": RequestCondOperatorWildcardMatch, + "description": "判断是否和指定的通配符匹配", + }, + { + "name": "通配符不匹配", + "op": RequestCondOperatorWildcardNotMatch, + "description": "判断是否和指定的通配符不匹配", + }, { "name": "字符串等于", "op": RequestCondOperatorEqString, @@ -211,7 +234,7 @@ func AllRequestOperators() []maps.Map { "description": "对IP参数值取模,对比值格式为:除数,余数,比如10,1", }, - { + /**{ "name": "文件存在", "op": RequestCondOperatorFileExist, "description": "判断参数值解析后的文件是否存在", @@ -221,6 +244,6 @@ func AllRequestOperators() []maps.Map { "name": "文件不存在", "op": RequestCondOperatorFileNotExist, "description": "判断参数值解析后的文件是否不存在", - }, + },**/ } }