Skip to content

Commit c629bb2

Browse files
committed
perf: use ast.Value and []string in request input
Signed-off-by: Anthony Regeda <[email protected]>
1 parent bd7cc15 commit c629bb2

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed

envoyauth/ast.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package envoyauth
2+
3+
import (
4+
"github.com/open-policy-agent/opa/v1/ast"
5+
)
6+
7+
func keyValue(k, v string) [2]*ast.Term {
8+
return [2]*ast.Term{{Value: ast.String(k)}, {Value: ast.String(v)}}
9+
}

envoyauth/request.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@ import (
1919
"google.golang.org/protobuf/reflect/protoregistry"
2020
"google.golang.org/protobuf/types/dynamicpb"
2121

22+
"github.com/open-policy-agent/opa/v1/ast"
2223
"github.com/open-policy-agent/opa/v1/logging"
2324
"github.com/open-policy-agent/opa/v1/util"
2425
)
2526

26-
var v2Info = map[string]string{"ext_authz": "v2", "encoding": "encoding/json"}
27-
var v3Info = map[string]string{"ext_authz": "v3", "encoding": "protojson"}
27+
var v2Info = ast.NewObject(
28+
keyValue("ext_authz", "v2"),
29+
keyValue("encoding", "encoding/json"),
30+
)
31+
var v3Info = ast.NewObject(
32+
keyValue("ext_authz", "v3"),
33+
keyValue("encoding", "protojson"),
34+
)
2835

2936
// RequestToInput - Converts a CheckRequest in either protobuf 2 or 3 to an input map
3037
func RequestToInput(req interface{}, logger logging.Logger, protoSet *protoregistry.Files, skipRequestBodyParse bool) (map[string]interface{}, error) {
@@ -33,7 +40,8 @@ func RequestToInput(req interface{}, logger logging.Logger, protoSet *protoregis
3340

3441
var rawBody []byte
3542
var path, body string
36-
var headers, version map[string]string
43+
var headers map[string]string
44+
var version ast.Value
3745

3846
// NOTE: The path/body/headers blocks look silly, but they allow us to retrieve
3947
// the parts of the incoming request we care about, without having to convert
@@ -84,32 +92,24 @@ func RequestToInput(req interface{}, logger logging.Logger, protoSet *protoregis
8492
return input, nil
8593
}
8694

87-
func getParsedPathAndQuery(path string) ([]interface{}, map[string]interface{}, error) {
95+
func getParsedPathAndQuery(path string) ([]string, map[string]any, error) {
8896
parsedURL, err := url.Parse(path)
8997
if err != nil {
9098
return nil, nil, err
9199
}
92100

93101
parsedPath := strings.Split(strings.TrimLeft(parsedURL.Path, "/"), "/")
94-
parsedPathInterface := make([]interface{}, len(parsedPath))
95-
for i, v := range parsedPath {
96-
parsedPathInterface[i] = v
97-
}
98102

99103
query := parsedURL.Query()
100-
parsedQueryInterface := make(map[string]interface{}, len(query))
104+
parsedQueryInterface := make(map[string]any, len(query))
101105
for paramKey, paramValues := range query {
102-
queryValues := make([]interface{}, len(paramValues))
103-
for i, v := range paramValues {
104-
queryValues[i] = v
105-
}
106-
parsedQueryInterface[paramKey] = queryValues
106+
parsedQueryInterface[paramKey] = paramValues
107107
}
108108

109-
return parsedPathInterface, parsedQueryInterface, nil
109+
return parsedPath, parsedQueryInterface, nil
110110
}
111111

112-
func getParsedBody(logger logging.Logger, headers map[string]string, body string, rawBody []byte, parsedPath []interface{}, protoSet *protoregistry.Files) (interface{}, bool, error) {
112+
func getParsedBody(logger logging.Logger, headers map[string]string, body string, rawBody []byte, parsedPath []string, protoSet *protoregistry.Files) (interface{}, bool, error) {
113113
var data interface{}
114114

115115
if val, ok := headers["content-type"]; ok {
@@ -269,7 +269,7 @@ func getParsedBody(logger logging.Logger, headers map[string]string, body string
269269
return data, false, nil
270270
}
271271

272-
func getGRPCBody(logger logging.Logger, in []byte, parsedPath []interface{}, data interface{}, files *protoregistry.Files) (found, truncated bool, _ error) {
272+
func getGRPCBody(logger logging.Logger, in []byte, parsedPath []string, data interface{}, files *protoregistry.Files) (found, truncated bool, _ error) {
273273

274274
// the first 5 bytes are part of gRPC framing. We need to remove them to be able to parse
275275
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
@@ -294,12 +294,12 @@ func getGRPCBody(logger logging.Logger, in []byte, parsedPath []interface{}, dat
294294
in = in[5 : size+5]
295295

296296
// Note: we've already checked that len(path)>=2
297-
svc, err := findService(parsedPath[0].(string), files)
297+
svc, err := findService(parsedPath[0], files)
298298
if err != nil {
299299
logger.WithFields(map[string]interface{}{"err": err}).Debug("could not find service")
300300
return false, false, nil
301301
}
302-
msgDesc, err := findMessageInputDesc(parsedPath[1].(string), svc)
302+
msgDesc, err := findMessageInputDesc(parsedPath[1], svc)
303303
if err != nil {
304304
logger.WithFields(map[string]interface{}{"err": err}).Debug("could not find message")
305305
return false, false, nil

envoyauth/request_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ func TestGetParsedBody(t *testing.T) {
384384

385385
logger := logging.NewNoOpLogger()
386386
req := createCheckRequest(requestContentTypeJSONInvalid)
387-
path := []interface{}{}
387+
path := []string{}
388388
protoSet := (*protoregistry.Files)(nil)
389389
headers, body := req.GetAttributes().GetRequest().GetHttp().GetHeaders(), req.GetAttributes().GetRequest().GetHttp().GetBody()
390390
_, _, err := getParsedBody(logger, headers, body, nil, path, protoSet)
@@ -617,38 +617,38 @@ func TestGetParsedBodygRPC(t *testing.T) {
617617
func TestParsedPathAndQuery(t *testing.T) {
618618
var tests = []struct {
619619
request *ext_authz.CheckRequest
620-
expectedPath []interface{}
620+
expectedPath []string
621621
expectedQuery map[string]interface{}
622622
}{
623623
{
624624
createExtReqWithPath("/my/test/path"),
625-
[]interface{}{"my", "test", "path"},
625+
[]string{"my", "test", "path"},
626626
map[string]interface{}{},
627627
},
628628
{
629629
createExtReqWithPath("/my/test/path?a=1"),
630-
[]interface{}{"my", "test", "path"},
631-
map[string]interface{}{"a": []interface{}{"1"}},
630+
[]string{"my", "test", "path"},
631+
map[string]interface{}{"a": []string{"1"}},
632632
},
633633
{
634634
createExtReqWithPath("/my/test/path?a=1&a=2"),
635-
[]interface{}{"my", "test", "path"},
636-
map[string]interface{}{"a": []interface{}{"1", "2"}},
635+
[]string{"my", "test", "path"},
636+
map[string]interface{}{"a": []string{"1", "2"}},
637637
},
638638
{
639639
createExtReqWithPath("/my/test/path?a=1&b=2"),
640-
[]interface{}{"my", "test", "path"},
641-
map[string]interface{}{"a": []interface{}{"1"}, "b": []interface{}{"2"}},
640+
[]string{"my", "test", "path"},
641+
map[string]interface{}{"a": []string{"1"}, "b": []string{"2"}},
642642
},
643643
{
644644
createExtReqWithPath("/my/test/path?a=1&a=new%0aline"),
645-
[]interface{}{"my", "test", "path"},
646-
map[string]interface{}{"a": []interface{}{"1", "new\nline"}},
645+
[]string{"my", "test", "path"},
646+
map[string]interface{}{"a": []string{"1", "new\nline"}},
647647
},
648648
{
649649
createExtReqWithPath("%2Fmy%2Ftest%2Fpath?a=1&a=new%0aline"),
650-
[]interface{}{"my", "test", "path"},
651-
map[string]interface{}{"a": []interface{}{"1", "new\nline"}},
650+
[]string{"my", "test", "path"},
651+
map[string]interface{}{"a": []string{"1", "new\nline"}},
652652
},
653653
}
654654

0 commit comments

Comments
 (0)