Bläddra i källkod

add ParseUri() expr helper (#994)

blotus 3 år sedan
förälder
incheckning
2bc9f33e12
2 ändrade filer med 91 tillägg och 0 borttagningar
  1. 21 0
      pkg/exprhelpers/exprlib.go
  2. 70 0
      pkg/exprhelpers/exprlib_test.go

+ 21 - 0
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

+ 70 - 0
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)
+	}
+}