Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support scrubbing gzip encoded bundles #36

Merged
merged 7 commits into from
Feb 12, 2024
Merged

Support scrubbing gzip encoded bundles #36

merged 7 commits into from
Feb 12, 2024

Conversation

jurassix
Copy link
Collaborator

@jurassix jurassix commented Feb 5, 2024

FullStory is rolling out gzip compression on the data sent from the client via /rec/bundle. This PR ensures that the plugin behaviour of scrubbing PII within Relay is preserved.

@jurassix jurassix marked this pull request as ready for review February 8, 2024 12:15
@@ -82,7 +81,7 @@ func (service *Service) LastRequestBody() ([]byte, error) {
}

defer request.Body.Close()
body, err := ioutil.ReadAll(request.Body)
body, err := io.ReadAll(request.Body)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note ioutil is deprecated and internally just calls the io package, so I've updated all usages of ioutil.

@jurassix
Copy link
Collaborator Author

jurassix commented Feb 8, 2024

cc @eugene-chang-fs @sethfowler this PR adds support for GZIP compressed bundle data being scrubbed and relayed correct. fs.js now has this ability to emit GZIP encoded bundles so this is now a requirement for Relay as well.

@@ -94,7 +94,7 @@ func (f contentBlockerPluginFactory) New(configSection *config.Section) (traffic
case "header":
plugin.headerBlockers = append(plugin.headerBlockers, blockers...)
default:
return fmt.Errorf(`Unexpected content kind %s`, contentKind)
return fmt.Errorf(`unexpected content kind %s`, contentKind)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note capitalization of error messages is a style lint warning for Golang so fixed these as well generally.

https://google.github.io/styleguide/go/decisions.html#error-strings

Comment on lines +238 to +239
contentLength := int64(len(processedBody))
if contentLength != request.ContentLength {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small change to directly verify the content length is valid instead of indirectly through the existing body content.

Comment on lines 144 to 145
runContentBlockerTest(t, testCase, Identity)
runContentBlockerTest(t, testCase, Gzip)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified this so all blocking tests are verified for compressed and identity encoded data.

Comment on lines 61 to 73
encoding, err := GetContentEncoding(request)
if err != nil {
logger.Printf("URL %v error getting request content encoding: %v", request.URL, err)
request.Body = http.NoBody
return
}

if err := handler.prepareRequestBody(request, encoding); err != nil {
http.Error(response, fmt.Sprintf("Error setting up clientRequest body reader: %s", err), 500)
request.Body = http.NoBody
return
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here preserve content decoding + encoding is working correctly and supports the assumption of our existing plugins. It's possible that the content-blocker-plugin could be modified to work with encoded data. However, our relay plugin model allows for customer created plugins that are expecting data to decoded. Wrapping the decode + encoding at the traffic handler layer preserves our existing ecosystem assumptions.

Copy link
Contributor

@sethfowler sethfowler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM! There's one edge case that we may want to handle; see below.

// Create a new gzip.Reader to decompress the request body
return gzip.NewReader(request.Body)
default:
// If the content is not gzip-compressed, return the original request body
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all of these functions, should we be reporting an error if we don't recognize the encoding?

Copy link
Collaborator Author

@jurassix jurassix Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM - I'll handle "" and "gzip" as the 2 supported cases today

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sethfowler feedback incorporated! PTAL

Copy link
Contributor

@sethfowler sethfowler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks; looks great!

@@ -99,6 +124,42 @@ func (handler *Handler) HandleRequest(clientResponse http.ResponseWriter, client
}
}

func (handler *Handler) ensureBodyContentEncoding(clientRequest *http.Request, encoding Encoding) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: maybe add a comment that this function does not change the qs/header about the existing encoding; this function operates on the assumption that the downstream proxy target will be using the same encoding as what the relay had received (and likely this is always the case), but it wouldn't hurt to point out

@jurassix jurassix merged commit a272202 into master Feb 12, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants