Skip to content

Commit

Permalink
fix(prose/golang): access response headers while processing reponse body
Browse files Browse the repository at this point in the history
Previously, we were accessing ContentType header of the request, while
attempting to analyze the body of both request and response. Now, we correctly
save and access response headers for response body, while still using request
headers for request body.
  • Loading branch information
qlonik committed Apr 25, 2024
1 parent 3cb0b16 commit ee1bc3d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 12 deletions.
20 changes: 15 additions & 5 deletions privacy-profile-composer/pkg/envoyfilter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ type Filter struct {

// Runtime state of the filter
parentSpanContext model.SpanContext
headerMetadata common.HeaderMetadata
reqHeaderMetadata common.RequestHeaderMetadata
resHeaderMetadata common.ResponseHeaderMetadata
thirdPartyURL string
processDecodeBody bool
decodeDataBuffer string
Expand All @@ -52,7 +53,7 @@ func (f *Filter) DecodeHeaders(header api.RequestHeaderMap, endStream bool) api.
span.Tag("SIDECAR_DIRECTION", string(f.config.direction))
span.Tag("DATA_FLOW", "DECODE_HEADERS")

f.headerMetadata = common.ExtractHeaderData(header)
f.reqHeaderMetadata = common.ExtractRequestHeaderData(header)

// common.LogDecodeHeaderData(header)

Expand Down Expand Up @@ -88,7 +89,7 @@ func (f *Filter) DecodeHeaders(header api.RequestHeaderMap, endStream bool) api.
return api.Continue
}

f.thirdPartyURL = f.headerMetadata.Host
f.thirdPartyURL = f.reqHeaderMetadata.Host
f.processDecodeBody = true

default:
Expand Down Expand Up @@ -169,6 +170,8 @@ func (f *Filter) EncodeHeaders(header api.ResponseHeaderMap, endStream bool) api
span.Tag("SIDECAR_DIRECTION", string(f.config.direction))
span.Tag("DATA_FLOW", "ENCODE_HEADERS")

f.resHeaderMetadata = common.ExtractResponseHeaderData(header)

if endStream {
// here we have a header-only request
return api.Continue
Expand Down Expand Up @@ -262,14 +265,21 @@ func (f *Filter) processBody(ctx context.Context, body string, isDecode bool) (s

proseTags[PROSE_SIDECAR_DIRECTION] = string(f.config.direction)

jsonBody, err := common.GetJSONBody(ctx, f.headerMetadata, body)
var contentType *string
if isDecode {
contentType = f.reqHeaderMetadata.ContentType
} else {
contentType = f.resHeaderMetadata.ContentType
}

jsonBody, err := common.GetJSONBody(ctx, contentType, body)
if err != nil {
proseTags[PROSE_JSON_BODY_ERROR] = fmt.Sprintf("%s", err)
return false, err, proseTags
}

// Run Presidio and add tags for PII types or an error from Presidio
piiTypes, err := common.PiiAnalysis(ctx, f.config.presidioUrl, f.headerMetadata.SvcName, jsonBody)
piiTypes, err := common.PiiAnalysis(ctx, f.config.presidioUrl, f.reqHeaderMetadata.SvcName, jsonBody)
if err != nil {
proseTags[PROSE_PRESIDIO_ERROR] = fmt.Sprintf("%s", err)
return false, err, proseTags
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
const anyPurpose = "ANY"
const unknownSvcName = "UNKNOWN SVC"

type HeaderMetadata struct {
type RequestHeaderMetadata struct {
Host string
Method string
Path string
Expand All @@ -27,6 +27,11 @@ type HeaderMetadata struct {
Purpose string
}

type ResponseHeaderMetadata struct {
ContentType *string
ContentLength *string
}

type SidecarDirection string

const (
Expand All @@ -51,8 +56,8 @@ func LogEncodeHeaderData(header api.ResponseHeaderMap) {
//})
}

func ExtractHeaderData(header api.RequestHeaderMap) HeaderMetadata {
metadata := HeaderMetadata{
func ExtractRequestHeaderData(header api.RequestHeaderMap) RequestHeaderMetadata {
metadata := RequestHeaderMetadata{
Host: header.Host(),
Method: header.Method(),
Path: header.Path(),
Expand Down Expand Up @@ -99,6 +104,22 @@ func ExtractHeaderData(header api.RequestHeaderMap) HeaderMetadata {
return metadata
}

func ExtractResponseHeaderData(headers api.ResponseHeaderMap) ResponseHeaderMetadata {
metadata := ResponseHeaderMetadata{}

contentType, exists := headers.Get("content-type")
if exists {
metadata.ContentType = &contentType
}

contentLength, exists := headers.Get("content-length")
if exists {
metadata.ContentLength = &contentLength
}

return metadata
}

func GetDirection(callbacks api.FilterCallbackHandler) (SidecarDirection, error) {
directionEnum, err := callbacks.GetProperty("xds.listener_direction")
if err != nil {
Expand Down Expand Up @@ -128,15 +149,15 @@ func GetDirection(callbacks api.FilterCallbackHandler) (SidecarDirection, error)
"check the Envoy docs for the range of values for this key", directionInt)
}

func GetJSONBody(ctx context.Context, headerMetadata HeaderMetadata, body string) (interface{}, error) {
func GetJSONBody(ctx context.Context, contentType *string, body string) (interface{}, error) {
span, ctx := GlobalTracer.StartSpanFromContext(ctx, "getJSONBody")
defer span.Finish()

if headerMetadata.ContentType == nil {
if contentType == nil {
return nil, fmt.Errorf("cannot analyze body, since 'ContentType' header is not set")
}

switch *headerMetadata.ContentType {
switch *contentType {
case "application/json":
var data interface{}

Expand All @@ -154,6 +175,6 @@ func GetJSONBody(ctx context.Context, headerMetadata HeaderMetadata, body string

return query, nil
default:
return nil, fmt.Errorf("cannot analyze a body with ContentType '%s'", *headerMetadata.ContentType)
return nil, fmt.Errorf("cannot analyze a body with ContentType '%s'", *contentType)
}
}

0 comments on commit ee1bc3d

Please sign in to comment.