Skip to content

fix: validate grpc-accept-encoding header when client sends gzip request - #12978

Open
jlaportebot wants to merge 8 commits into
grpc:masterfrom
jlaportebot:fix/verify-grpc-accept-encoding
Open

fix: validate grpc-accept-encoding header when client sends gzip request#12978
jlaportebot wants to merge 8 commits into
grpc:masterfrom
jlaportebot:fix/verify-grpc-accept-encoding

Conversation

@jlaportebot

Copy link
Copy Markdown

Summary

This PR implements validation for the grpc-accept-encoding response header when the client sends a gzip-encoded request.

According to the gRPC spec, when a client sends a gzip-encoded request, the server must respond with grpc-accept-encoding: gzip in the response headers to indicate it can accept gzip-encoded responses. If this header is missing or doesn't include gzip, it's a server misbehavior.

Changes

  1. Added validation logic in Http2ClientStreamTransportState.transportHeadersReceived() that:

    • Tracks when the client sends a gzip-encoded request via setMessageCompression(boolean, String)
    • Validates the server's grpc-accept-encoding header when client sent gzip
    • Logs a warning at FINE level if the header is missing or doesn't include gzip
  2. Extended ClientStream interface with setMessageCompression(boolean enabled, String compressorName) method to pass compressor information to the transport layer

  3. Updated all ClientStream implementations to support the new method signature:

    • AbstractClientStream.TransportState (base implementation)
    • Http2ClientStreamTransportState (actual validation logic)
    • ForwardingClientStream, NoopClientStream, DelayedStream, RetriableStream
    • InProcessTransport (both client and server streams)
    • MultiMessageClientStream, SingleMessageClientStream (binder transport)
  4. Added comprehensive unit tests in Http2ClientStreamTransportStateGrpcAcceptEncodingTest.java covering:

    • Valid grpc-accept-encoding: gzip header
    • Missing header when gzip was sent (logs warning)
    • Header with only identity when gzip was sent (logs warning)
    • Header with gzip,deflate when gzip was sent (OK)
    • No client compression (no validation needed)
    • Case-insensitive header value matching (GZIP, gzip)

Testing

All existing tests pass. New tests added for the validation logic.

Fixes #1804

- Add validation in Http2ClientStreamTransportState to check if server response
  includes grpc-accept-encoding: gzip when client sent gzip-encoded request
- Log warning at FINE level when server misbehavior detected (missing or invalid header)
- Add setMessageCompression(boolean, String) method to ClientStream interface and
  implementations to track when client sends gzip-compressed requests
- Add unit tests for grpc-accept-encoding validation

Fixes grpc#1804
@linux-foundation-easycla

linux-foundation-easycla Bot commented Aug 9, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

…nProcessClientStream

NettyClientStream extends AbstractClientStream but compilation failed because
AbstractClientStream did not override the new ClientStream.setMessageCompression(boolean, String)
method added to the interface. The method was only on the inner TransportState class.

Add the override to AbstractClientStream that delegates to transportState(),
matching the pattern of setDecompressorRegistry. Also add the override to
InProcessClientStream (noop, matching existing setMessageCompression(boolean)).

Signed-off-by: jlaportebot <jlaportebot@gmail.com>
NettyClientStream extends AbstractClientStream but compilation failed because
AbstractClientStream did not override the new ClientStream.setMessageCompression(boolean, String)
method added to the interface. The method was only on the inner TransportState class.

Add the override to InProcessClientStream (noop, matching existing setMessageCompression(boolean)).
Also add the override to AbstractClientStream that delegates to transportState(),
matching the pattern of setDecompressorRegistry.

Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…ream and InProcessClientStream

Both classes implement Stream interface which requires setMessageCompression(boolean).
Previously only setMessageCompression(boolean, String) was implemented.

Fixes compilation errors in grpc-inprocess module.
…n(boolean, String)

The ServerStream interface only extends Stream and doesn't declare the
two-argument setMessageCompression method. Only ClientStream has it.
The @OverRide annotation was causing a compilation error.

Signed-off-by: jlaportebot <jlaportebot@gmail.com>
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.

Verify server sends grpc-accept-encoding appropriately

1 participant