feat(codec): Add ServerCompressionInterceptor for gRPC compression - #2649
feat(codec): Add ServerCompressionInterceptor for gRPC compression#2649sauravzg wants to merge 2 commits into
Conversation
beb2595 to
5acb682
Compare
5acb682 to
b4af9e3
Compare
b4af9e3 to
bcfd493
Compare
|
@saurav - this PR is not targetting master. Is that intentional? |
Yes. I am trying out a stacked PR approach, every PR is targetting its parent PR. |
So then.... we end up with a branch that has all the changes on it that we want, and then we create a final PR that merges that branch to master once it's all done? |
|
I plan to rely on https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches#working-with-branches to retarget branch to head when the parent PR gets merged. So, I am supposed to merge the parent PR first i.e. #2648 . After which , github will auto target this PR to master. So, the the features missing from https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches#working-with-branches , are
I don't care about 1 right now and plan to manually handle 2 myself. |
bcfd493 to
5fac1c7
Compare
5fac1c7 to
480516d
Compare
…istry This change introduces the foundational compression abstractions and implementations for the grpc server component. - **Compression API (`grpc/src/codec/compression.rs`)**: Defines the `Compressor` and `Decompressor` traits for handling the compression and decompression of gRPC payloads via byte buffers. - **Simplified Design Philosophy**: The API is intentionally kept simple. It deliberately avoids handling concerns like limiting input and output buffer sizes, instead delegating these safety boundaries to the higher-level gRPC business logic. - **Performance Improvements**: By relying on direct buffer manipulation, this implementation avoids the hidden memory copying overhead present in the `tonic` crate (which utilizes 8KB intermediate buffers for I/O). - **Standard Algorithms**: Implements `gzip`, `deflate`, and `zstd` compression logic in their respective modules. These are conditionally compiled based on feature flags. - **Global Registry (`registry.rs`)**: Introduces a thread-safe `GlobalCompressionRegistry` (backed by `RwLock` and `Arc`) to manage registered compressors and decompressors. It handles safe concurrent access and automatically updates the broadcasted `grpc-accept-encoding` headers. - **Module Integration**: Exposes the new `codec` and `compression` modules to the library's root structure.
⚠️ TRADEOFFS & LIMITATIONS⚠️ Due to the current limitations of the `RecvStream` API (which lacks out-of-band compression signals), this implementation introduces a high degree of coupling between the HTTP transport, compression, and serialization layers. Consequently, this design necessitates type erasure(IncomingRawMessage) and incurs a forced `Box` allocation penalty to function within the existing stream boundaries. This change introduces the `ServerCompressionInterceptor`, which integrates compression and decompression capabilities into the server-side gRPC request/response lifecycle. Key additions: - **`ServerCompressionInterceptor`**: Implements the `Intercept` trait to wrap incoming requests. It parses the `grpc-encoding` and `grpc-accept-encoding` headers to determine the appropriate `Compressor` and `Decompressor` to use. - **Decompression Bomb Mitigation**: Protects against decompression bomb (zip bomb) attacks by strictly limiting writes during the decompression process. - **`CompressionResolver` Integration**: Uses a `CompressionResolver` registry to look up algorithms by name. - **Stream Wrapping**: Wraps the underlying `RecvStream` (to decompress incoming messages) and `SendStream` (to compress outgoing messages and inject the correct `grpc-encoding` header). - **Error Handling**: Returns standard gRPC status errors if an encoding is unsupported or if compression/decompression fails during stream processing. - **Unit Tests**: Includes a comprehensive suite of Tokio-based tests covering successful compression/decompression, unsupported encoding errors, registry lookup failures, and fallback mechanisms.
480516d to
0f77d89
Compare
RecvStreamAPI (which lacks out-of-band compression signals), this implementation introduces a high degree of coupling between the HTTP transport, compression, and serialization layers. Consequently, this design necessitates type erasure(IncomingRawMessage) and incurs a forcedBoxallocation penalty to function within the existing stream boundaries.This change introduces the
ServerCompressionInterceptor, which integrates compression and decompression capabilities into the server-side gRPC request/response lifecycle.Key additions:
ServerCompressionInterceptor: Implements theIntercepttrait to wrap incoming requests. It parses thegrpc-encodingandgrpc-accept-encodingheaders to determine the appropriateCompressorandDecompressorto use.CompressionResolverIntegration: Uses aCompressionResolverregistry to look up algorithms by name.RecvStream(to decompress incoming messages) andSendStream(to compress outgoing messages and inject the correctgrpc-encodingheader).