Skip to content

Commit

Permalink
Remove intermediate JSON marshal and unmarshal
Browse files Browse the repository at this point in the history
Signed-off-by: Pushpalanka Jayawardhana <[email protected]>
  • Loading branch information
Pushpalanka committed Jan 2, 2025
1 parent 7dbefee commit 1a1d372
Showing 1 changed file with 42 additions and 29 deletions.
71 changes: 42 additions & 29 deletions envoyauth/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package envoyauth

import (
"encoding/binary"
"encoding/json"
"fmt"
"io"
"mime"
Expand All @@ -29,58 +28,72 @@ var v3Info = map[string]string{"ext_authz": "v3", "encoding": "protojson"}
// RequestToInput - Converts a CheckRequest in either protobuf 2 or 3 to an input map
func RequestToInput(req interface{}, logger logging.Logger, protoSet *protoregistry.Files, skipRequestBodyParse bool) (map[string]interface{}, error) {
var err error
var input map[string]interface{}
var input = make(map[string]interface{})

var bs, rawBody []byte
var path, body string
var headers, version map[string]string
var rawBody []byte
var path, body, method, host string
var headers map[string]string
var version map[string]string

// NOTE: The path/body/headers blocks look silly, but they allow us to retrieve
// the parts of the incoming request we care about, without having to convert
// the entire v2 message into v3. It's nested, each level has a different type,
// etc -- we only care for its JSON representation as fed into evaluation later.
switch req := req.(type) {
case *ext_authz_v3.CheckRequest:
bs, err = protojson.Marshal(req)
if err != nil {
return nil, err
attrs := req.GetAttributes()
if attrs == nil || attrs.GetRequest() == nil || attrs.GetRequest().GetHttp() == nil {
return nil, fmt.Errorf("missing required attributes in v3 CheckRequest")
}
path = req.GetAttributes().GetRequest().GetHttp().GetPath()
body = req.GetAttributes().GetRequest().GetHttp().GetBody()
headers = req.GetAttributes().GetRequest().GetHttp().GetHeaders()
rawBody = req.GetAttributes().GetRequest().GetHttp().GetRawBody()
httpReq := attrs.GetRequest().GetHttp()

path = httpReq.GetPath()
body = httpReq.GetBody()
headers = httpReq.GetHeaders()
rawBody = httpReq.GetRawBody()
method = httpReq.GetMethod()
host = httpReq.GetHost()
version = v3Info

case *ext_authz_v2.CheckRequest:
bs, err = json.Marshal(req)
if err != nil {
return nil, err
attrs := req.GetAttributes()
if attrs == nil || attrs.GetRequest() == nil || attrs.GetRequest().GetHttp() == nil {
return nil, fmt.Errorf("missing required attributes in v2 CheckRequest")
}
path = req.GetAttributes().GetRequest().GetHttp().GetPath()
body = req.GetAttributes().GetRequest().GetHttp().GetBody()
headers = req.GetAttributes().GetRequest().GetHttp().GetHeaders()
httpReq := attrs.GetRequest().GetHttp()

path = httpReq.GetPath()
body = httpReq.GetBody()
headers = httpReq.GetHeaders()
method = httpReq.GetMethod()
host = httpReq.GetHost()
version = v2Info

default:
return nil, fmt.Errorf("unsupported request type: %T", req)
}

err = util.UnmarshalJSON(bs, &input)
if err != nil {
return nil, err
input["attributes"] = map[string]interface{}{
"request": map[string]interface{}{
"http": map[string]interface{}{
"path": path,
"body": body,
"headers": headers,
"method": method,
"host": host,
},
},
}
input["version"] = version

parsedPath, parsedQuery, err := getParsedPathAndQuery(path)
if err != nil {
return nil, err
return nil, fmt.Errorf("error parsing path and query: %w", err)
}

input["parsed_path"] = parsedPath
input["parsed_query"] = parsedQuery

if !skipRequestBodyParse {
parsedBody, isBodyTruncated, err := getParsedBody(logger, headers, body, rawBody, parsedPath, protoSet)
if err != nil {
return nil, err
return nil, fmt.Errorf("error parsing request body: %w", err)
}

input["parsed_body"] = parsedBody
input["truncated_body"] = isBodyTruncated
}
Expand Down

0 comments on commit 1a1d372

Please sign in to comment.