diff --git a/pkg/exprhelpers/exprlib.go b/pkg/exprhelpers/exprlib.go index 52de6cf19..5c2cfe3b7 100644 --- a/pkg/exprhelpers/exprlib.go +++ b/pkg/exprhelpers/exprlib.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "net" + "net/url" "os" "path" "regexp" @@ -42,6 +43,7 @@ func GetExprEnv(ctx map[string]interface{}) map[string]interface{} { "Upper": Upper, "IpInRange": IpInRange, "TimeNow": TimeNow, + "ParseUri": ParseUri, } for k, v := range ctx { ExprLib[k] = v @@ -142,6 +144,25 @@ func TimeNow() string { return time.Now().Format(time.RFC3339) } + +func ParseUri(uri string) map[string][]string { + ret := make(map[string][]string) + u, err := url.Parse(uri) + if err != nil { + log.Errorf("Could not parse URI: %s", err) + return ret + } + parsed, err := url.ParseQuery(u.RawQuery) + if err != nil { + log.Errorf("Could not parse query uri : %s", err) + return ret + } + for k, v := range parsed { + ret[k] = v + } + return ret +} + func KeyExists(key string, dict map[string]interface{}) bool { _, ok := dict[key] return ok diff --git a/pkg/exprhelpers/exprlib_test.go b/pkg/exprhelpers/exprlib_test.go index 907d33312..36829732d 100644 --- a/pkg/exprhelpers/exprlib_test.go +++ b/pkg/exprhelpers/exprlib_test.go @@ -385,3 +385,73 @@ func TestTimeNow(t *testing.T) { } log.Printf("test 'TimeNow()' : OK") } + +func TestParseUri(t *testing.T) { + tests := []struct { + name string + env map[string]interface{} + code string + result map[string][]string + err string + }{ + { + name: "ParseUri() test: basic test", + env: map[string]interface{}{ + "uri": "/foo?a=1&b=2", + "ParseUri": ParseUri, + }, + code: "ParseUri(uri)", + result: map[string][]string{"a": []string{"1"}, "b": []string{"2"}}, + err: "", + }, + { + name: "ParseUri() test: no param", + env: map[string]interface{}{ + "uri": "/foo", + "ParseUri": ParseUri, + }, + code: "ParseUri(uri)", + result: map[string][]string{}, + err: "", + }, + { + name: "ParseUri() test: extra question mark", + env: map[string]interface{}{ + "uri": "/foo?a=1&b=2?", + "ParseUri": ParseUri, + }, + code: "ParseUri(uri)", + result: map[string][]string{"a": []string{"1"}, "b": []string{"2?"}}, + err: "", + }, + { + name: "ParseUri() test: weird params", + env: map[string]interface{}{ + "uri": "/foo?&?&&&&?=123", + "ParseUri": ParseUri, + }, + code: "ParseUri(uri)", + result: map[string][]string{"?": []string{"", "123"}}, + err: "", + }, + { + name: "ParseUri() test: bad encoding", + env: map[string]interface{}{ + "uri": "/foo?a=%%F", + "ParseUri": ParseUri, + }, + code: "ParseUri(uri)", + result: map[string][]string{}, + err: "", + }, + } + + for _, test := range tests { + program, err := expr.Compile(test.code, expr.Env(test.env)) + require.NoError(t, err) + output, err := expr.Run(program, test.env) + require.NoError(t, err) + require.Equal(t, test.result, output) + log.Printf("test '%s' : OK", test.name) + } +}