Files
releases/util/decoding/context.go
T
Philip Conrad ee9ab0bf75 util+server: Fix bug around chunked request handling. (#6906)
This commit fixes a request handling bug introduced in #6868, which
caused OPA to treat all incoming chunked requests as if they had
zero-length request bodies.

The fix detects cases where the request body size is unknown in the
DecodingLimits handler, and propagates a request context key down to
the `util.ReadMaybeCompressedBody` function, allowing it to correctly
select between using the original `io.ReadAll` style for chunked
requests, or the newer preallocated buffers approach (for requests of
known size).

This change has a small, but barely visible performance impact for large
requests (<5% increase in GC pauses for a 1GB request JSON blob), and
minimal, if any, effect on RPS under load.

Fixes: #6904

Signed-off-by: Philip Conrad <philip@chariot-chaser.net>
2024-08-01 15:22:51 -04:00

32 lines
1.0 KiB
Go

package decoding
import "context"
type requestContextKey string
// Note(philipc): We can add functions later to add the max request body length
// to contexts, if we ever need to.
const (
reqCtxKeyMaxLen = requestContextKey("server-decoding-plugin-context-max-length")
reqCtxKeyGzipMaxLen = requestContextKey("server-decoding-plugin-context-gzip-max-length")
)
func AddServerDecodingMaxLen(ctx context.Context, maxLen int64) context.Context {
return context.WithValue(ctx, reqCtxKeyMaxLen, maxLen)
}
func AddServerDecodingGzipMaxLen(ctx context.Context, maxLen int64) context.Context {
return context.WithValue(ctx, reqCtxKeyGzipMaxLen, maxLen)
}
// Used for enforcing max body content limits when dealing with chunked requests.
func GetServerDecodingMaxLen(ctx context.Context) (int64, bool) {
maxLength, ok := ctx.Value(reqCtxKeyMaxLen).(int64)
return maxLength, ok
}
func GetServerDecodingGzipMaxLen(ctx context.Context) (int64, bool) {
gzipMaxLength, ok := ctx.Value(reqCtxKeyGzipMaxLen).(int64)
return gzipMaxLength, ok
}