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

Compress OPA response & accept compressed input #5696

Conversation

AdrianArnautu
Copy link
Contributor

@AdrianArnautu AdrianArnautu commented Feb 24, 2023

This change allows the HTTP clients to consume and send gzip compressed response and request body.
It is available for the following REST API endpoints:

  • GET & POST HTTP methods on /v0/data & /v1/data endpoints
  • POST HTTP method on /v1/compile endpoint.

HTTP clients can optionally:

  • send Accept-Encoding: gzip header and expect a gzip compressed body and a Content-Encoding: gzip response header. The server will send the content encoded as gzip only after a threshold defined by server.gzip_min_length (defaulted on 1024 bytes). If the size is below the threshold, the body is not compressed
  • send Content-Encoding: gzip header and a gzip compressed body and expect the server to correctly interpret the request

Reducing the network load in our setup is the reason for this change.

  • partial evaluation is almost always returns a large response
  • /v1/data endpoint might need to consume a large input because otherwise storing it in the bundle puts pressure on memory

High level implementation details

  • new internal HTTP handler captures the request and watches for Accept-Encoding: gzip request header and responds with a gzip body. The implementation is independent of gorilla/mux HTTP router
  • the handler will decide if the response is compressed or not if the body is larger than server.gzip_min_length configuration
  • data & compile endpoints watches for Content-Encoding: gzip request header and is decompressing the input before consuming it
  • both the input and the response it is logged decompressed to the console regardless of the client's compress headers
  • the compression threshold can be changed from the configuration file, the key is server.gzip_min_length
  • there's also server.gzip_compression_level defaulted to value 9 (best compression). See the gzip library

Fixes #5310
Signed-off-by: Adrian Arnautu [email protected]

@AdrianArnautu AdrianArnautu changed the title #5310 Compress OPA response & accept compressed input Compress OPA response & accept compressed input Feb 24, 2023
@netlify
Copy link

netlify bot commented Feb 24, 2023

Deploy Preview for openpolicyagent ready!

Name Link
🔨 Latest commit 840946e
🔍 Latest deploy log https://app.netlify.com/sites/openpolicyagent/deploys/640860e831323700081d9af6
😎 Deploy Preview https://deploy-preview-5696--openpolicyagent.netlify.app/docs/edge/management-status
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@AdrianArnautu AdrianArnautu force-pushed the compression-handler-data-and-compile branch from eb07d30 to da62d5c Compare February 24, 2023 15:19
@anderseknert
Copy link
Member

This is great! We'll take a closer look next week. I wonder if this is something to consider?

@AdrianArnautu
Copy link
Contributor Author

@anderseknert thank you
A threshold payload size to compress the body seems sensible, I'll do an addendum.

@anderseknert
Copy link
Member

Setting status to waiting-for-response as it is the closest thing we have :) Will be ready for review once the payload threshold has been taken into consideration.

@AdrianArnautu
Copy link
Contributor Author

Setting status to waiting-for-response as it is the closest thing we have :) Will be ready for review once the payload threshold has been taken into consideration.

I'm planning to push the change this week, worst case, next one.

@anderseknert
Copy link
Member

Thanks for the update, @AdrianArnautu 👍

@AdrianArnautu AdrianArnautu force-pushed the compression-handler-data-and-compile branch 2 times, most recently from 543ae95 to 285fce5 Compare March 5, 2023 21:17
@AdrianArnautu
Copy link
Contributor Author

@anderseknert I've pushed the latest changes, this PR is ready for the review.
There's a new config key for changing the threshold value as it is fit based on one's setup. Defaults to 1024.

Let me know if changes are needed, either naming/structure, features or something I've grossly overlooked.

Copy link
Member

@anderseknert anderseknert left a comment

Choose a reason for hiding this comment

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

This is a great contribution! Code looks good to me, and a really extensive set of tests 👏

Only a few questions, really. Perhaps @johanfylling or @ashutosh-narkar could take a look as well, but this is a great improvement 👍

docs/content/configuration.md Outdated Show resolved Hide resolved
plugins/server/config.go Outdated Show resolved Hide resolved
@AdrianArnautu AdrianArnautu force-pushed the compression-handler-data-and-compile branch from 285fce5 to e1a6c76 Compare March 6, 2023 11:49
@AdrianArnautu
Copy link
Contributor Author

I've done the changes and rebased the branch.

anderseknert
anderseknert previously approved these changes Mar 6, 2023
Copy link
Member

@anderseknert anderseknert left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@srenatus srenatus left a comment

Choose a reason for hiding this comment

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

Nice work! Some minor questions from my side 👇

runtime/logging.go Outdated Show resolved Hide resolved
runtime/logging_test.go Outdated Show resolved Hide resolved
server/handlers/compress.go Show resolved Hide resolved
@AdrianArnautu AdrianArnautu force-pushed the compression-handler-data-and-compile branch 2 times, most recently from 2bf6b5d to 74394a8 Compare March 6, 2023 15:40
@AdrianArnautu AdrianArnautu requested review from srenatus and anderseknert and removed request for srenatus and anderseknert March 6, 2023 15:52
@AdrianArnautu
Copy link
Contributor Author

Ready for review @anderseknert & @srenatus

anderseknert
anderseknert previously approved these changes Mar 6, 2023
runtime/logging.go Outdated Show resolved Hide resolved
plugins/server/config.go Outdated Show resolved Hide resolved
docs/content/configuration.md Outdated Show resolved Hide resolved
server/server.go Outdated Show resolved Hide resolved
@AdrianArnautu AdrianArnautu force-pushed the compression-handler-data-and-compile branch from 9597f39 to f9839d6 Compare March 7, 2023 12:05
@AdrianArnautu AdrianArnautu force-pushed the compression-handler-data-and-compile branch 2 times, most recently from efbcc7e to 840946e Compare March 8, 2023 10:18
srenatus
srenatus previously approved these changes Mar 8, 2023
Copy link
Contributor

@srenatus srenatus left a comment

Choose a reason for hiding this comment

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

Thanks, that's an impressive first contribution.

@@ -73,8 +74,26 @@ func (h *LoggingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
bs, r.Body, err = readBody(r.Body)
}
if err == nil {
fields["req_body"] = string(bs)
} else {
if gzipReceived(r.Header) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It's somewhat unfortunate that we have to decompress what we've ourselves compressed before just for logging it. I wonder if there's a different way of chaining handlers possible that would let us avoid that...

@ashutosh-narkar
Copy link
Member

@AdrianArnautu thanks for this contribution. Can you please update the commit message explaining why the changes were made? Here are some guidelines. We can then merge this.

…ed response and request body.

It is available for the following REST API endpoints:
- GET & POST HTTP methods on /v0/data & /v1/data endpoints
- POST HTTP method on /v1/compile endpoint

HTTP clients can optionally:
- send 'Accept-Encoding: gzip' header and expect a gzip compressed body and a Content-Encoding: gzip response header. The server will send the content encoded as gzip only after a threshold defined by server.encoding.gzip.min_length (default value is 1024). If the size is below the threshold, the body is not compressed
- send 'Content-Encoding: gzip' header and a gzip compressed body and expect the server to correctly interpret the request

Fixes open-policy-agent#5310

Signed-off-by: aarnautu <[email protected]>
@anderseknert anderseknert force-pushed the compression-handler-data-and-compile branch from 911e794 to 727b33e Compare March 9, 2023 08:23
@AdrianArnautu
Copy link
Contributor Author

@anderseknert , @srenatus & @ashutosh-narkar - thank you.

@anderseknert anderseknert merged commit 9e97f98 into open-policy-agent:main Mar 9, 2023
@anderseknert
Copy link
Member

Thank YOU @AdrianArnautu 👏

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.

server: compress large response payloads if client supports it
4 participants