xref: /aosp_15_r20/external/grpc-grpc/doc/compression.md (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker## gRPC Compression
2*cc02d7e2SAndroid Build Coastguard Worker
3*cc02d7e2SAndroid Build Coastguard WorkerThe keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
4*cc02d7e2SAndroid Build Coastguard Worker"SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this document are to be
5*cc02d7e2SAndroid Build Coastguard Workerinterpreted as described in [RFC 2119](http://www.ietf.org/rfc/rfc2119.txt).
6*cc02d7e2SAndroid Build Coastguard Worker
7*cc02d7e2SAndroid Build Coastguard Worker### Intent
8*cc02d7e2SAndroid Build Coastguard Worker
9*cc02d7e2SAndroid Build Coastguard WorkerCompression is used to reduce the amount of bandwidth used between peers. The
10*cc02d7e2SAndroid Build Coastguard Workercompression supported by gRPC acts _at the individual message level_, taking
11*cc02d7e2SAndroid Build Coastguard Worker_message_ [as defined in the wire format
12*cc02d7e2SAndroid Build Coastguard Workerdocument](PROTOCOL-HTTP2.md).
13*cc02d7e2SAndroid Build Coastguard Worker
14*cc02d7e2SAndroid Build Coastguard WorkerThe implementation supports different compression algorithms. A _default
15*cc02d7e2SAndroid Build Coastguard Workercompression level_, to be used in the absence of message-specific settings, MAY
16*cc02d7e2SAndroid Build Coastguard Workerbe specified for during channel creation.
17*cc02d7e2SAndroid Build Coastguard Worker
18*cc02d7e2SAndroid Build Coastguard WorkerThe ability to control compression settings per call and to enable/disable
19*cc02d7e2SAndroid Build Coastguard Workercompression on a per message basis MAY be used to prevent CRIME/BEAST attacks.
20*cc02d7e2SAndroid Build Coastguard WorkerIt also allows for asymmetric compression communication, whereby a response MAY
21*cc02d7e2SAndroid Build Coastguard Workerbe compressed differently, if at all.
22*cc02d7e2SAndroid Build Coastguard Worker
23*cc02d7e2SAndroid Build Coastguard Worker### Specification
24*cc02d7e2SAndroid Build Coastguard Worker
25*cc02d7e2SAndroid Build Coastguard WorkerCompression MAY be configured by the Client Application by calling the
26*cc02d7e2SAndroid Build Coastguard Workerappropriate API method. There are two scenarios where compression MAY be
27*cc02d7e2SAndroid Build Coastguard Workerconfigured:
28*cc02d7e2SAndroid Build Coastguard Worker
29*cc02d7e2SAndroid Build Coastguard Worker+  At channel creation time, which sets the channel default compression and
30*cc02d7e2SAndroid Build Coastguard Worker   therefore the compression that SHALL be used in the absence of per-RPC
31*cc02d7e2SAndroid Build Coastguard Worker   compression configuration.
32*cc02d7e2SAndroid Build Coastguard Worker+  At response time, via:
33*cc02d7e2SAndroid Build Coastguard Worker   +  For unary RPCs, the {Client,Server}Context instance.
34*cc02d7e2SAndroid Build Coastguard Worker   +  For streaming RPCs, the {Client,Server}Writer instance. In this case,
35*cc02d7e2SAndroid Build Coastguard Worker      configuration is reduced to disabling compression altogether.
36*cc02d7e2SAndroid Build Coastguard Worker
37*cc02d7e2SAndroid Build Coastguard Worker### Compression Method Asymmetry Between Peers
38*cc02d7e2SAndroid Build Coastguard Worker
39*cc02d7e2SAndroid Build Coastguard WorkerA gRPC peer MAY choose to respond using a different compression method to that
40*cc02d7e2SAndroid Build Coastguard Workerof the request, including not performing any compression, regardless of channel
41*cc02d7e2SAndroid Build Coastguard Workerand RPC settings (for example, if compression would result in small or negative
42*cc02d7e2SAndroid Build Coastguard Workergains).
43*cc02d7e2SAndroid Build Coastguard Worker
44*cc02d7e2SAndroid Build Coastguard WorkerIf a client message is compressed by an algorithm that is not supported
45*cc02d7e2SAndroid Build Coastguard Workerby a server, the message WILL result in an `UNIMPLEMENTED` error status on the
46*cc02d7e2SAndroid Build Coastguard Workerserver. The server will then include a `grpc-accept-encoding` response
47*cc02d7e2SAndroid Build Coastguard Workerheader which specifies the algorithms that the server accepts. If the client
48*cc02d7e2SAndroid Build Coastguard Workermessage is compressed using one of the algorithms from the `grpc-accept-encoding` header
49*cc02d7e2SAndroid Build Coastguard Workerand an `UNIMPLEMENTED` error status is returned from the server, the cause of the error
50*cc02d7e2SAndroid Build Coastguard WorkerMUST NOT be related to compression. If a server sent data which is compressed by an algorithm
51*cc02d7e2SAndroid Build Coastguard Workerthat is not supported by the client, an `INTERNAL` error status will occur on the client side.
52*cc02d7e2SAndroid Build Coastguard Worker
53*cc02d7e2SAndroid Build Coastguard WorkerNote that a peer MAY choose to not disclose all the encodings it supports.
54*cc02d7e2SAndroid Build Coastguard WorkerHowever, if it receives a message compressed in an undisclosed but supported
55*cc02d7e2SAndroid Build Coastguard Workerencoding, it MUST include said encoding in the response's `grpc-accept-encoding`
56*cc02d7e2SAndroid Build Coastguard Workerheader.
57*cc02d7e2SAndroid Build Coastguard Worker
58*cc02d7e2SAndroid Build Coastguard WorkerFor every message a server is requested to compress using an algorithm it knows
59*cc02d7e2SAndroid Build Coastguard Workerthe client doesn't support (as indicated by the last `grpc-accept-encoding`
60*cc02d7e2SAndroid Build Coastguard Workerheader received from the client), it SHALL send the message uncompressed.
61*cc02d7e2SAndroid Build Coastguard Worker
62*cc02d7e2SAndroid Build Coastguard Worker### Specific Disabling of Compression
63*cc02d7e2SAndroid Build Coastguard Worker
64*cc02d7e2SAndroid Build Coastguard WorkerIf the user (through the previously described mechanisms) requests to disable
65*cc02d7e2SAndroid Build Coastguard Workercompression the next message MUST be sent uncompressed. This is instrumental in
66*cc02d7e2SAndroid Build Coastguard Workerpreventing BEAST/CRIME attacks. This applies to both the unary and streaming
67*cc02d7e2SAndroid Build Coastguard Workercases.
68*cc02d7e2SAndroid Build Coastguard Worker
69*cc02d7e2SAndroid Build Coastguard Worker### Compression Levels and Algorithms
70*cc02d7e2SAndroid Build Coastguard Worker
71*cc02d7e2SAndroid Build Coastguard WorkerThe set of supported algorithm is implementation dependent. In order to simplify
72*cc02d7e2SAndroid Build Coastguard Workerthe public API and to operate seamlessly across implementations (both in terms
73*cc02d7e2SAndroid Build Coastguard Workerof languages but also different version of the same one), we introduce the idea
74*cc02d7e2SAndroid Build Coastguard Workerof _compression levels_ (such as "low", "medium", "high").
75*cc02d7e2SAndroid Build Coastguard Worker
76*cc02d7e2SAndroid Build Coastguard WorkerLevels map to concrete algorithms and/or their settings (such as "low" mapping
77*cc02d7e2SAndroid Build Coastguard Workerto "gzip -3" and "high" mapping to "gzip -9") automatically depending on what a
78*cc02d7e2SAndroid Build Coastguard Workerpeer is known to support. A server is always aware of what its clients support,
79*cc02d7e2SAndroid Build Coastguard Workeras clients disclose it in the Message-Accept-Encoding header as part of the
80*cc02d7e2SAndroid Build Coastguard WorkerRPC. A client doesn't a priori (presently) know which algorithms a
81*cc02d7e2SAndroid Build Coastguard Workerserver supports. This issue can be addressed with an initial negotiation of
82*cc02d7e2SAndroid Build Coastguard Workercapabilities or an automatic retry mechanism. These features will be implemented
83*cc02d7e2SAndroid Build Coastguard Workerin the future. Currently however, compression levels are only supported at the
84*cc02d7e2SAndroid Build Coastguard Workerserver side, which is aware of the client's capabilities through the incoming
85*cc02d7e2SAndroid Build Coastguard WorkerMessage-Accept-Encoding header.
86*cc02d7e2SAndroid Build Coastguard Worker
87*cc02d7e2SAndroid Build Coastguard Worker### Propagation to child RPCs
88*cc02d7e2SAndroid Build Coastguard Worker
89*cc02d7e2SAndroid Build Coastguard WorkerThe inheritance of the compression configuration by child RPCs is left up to the
90*cc02d7e2SAndroid Build Coastguard Workerimplementation. Note that in the absence of changes to the parent channel, its
91*cc02d7e2SAndroid Build Coastguard Workerconfiguration will be used.
92*cc02d7e2SAndroid Build Coastguard Worker
93*cc02d7e2SAndroid Build Coastguard Worker### Deflate Compression
94*cc02d7e2SAndroid Build Coastguard Worker
95*cc02d7e2SAndroid Build Coastguard WorkerLike HTTP implementations, gRPC implementations MUST use the "deflate"
96*cc02d7e2SAndroid Build Coastguard Workercompression to mean the zlib structure (defined in
97*cc02d7e2SAndroid Build Coastguard Worker[RFC 1950](https://datatracker.ietf.org/doc/html/rfc1950))
98*cc02d7e2SAndroid Build Coastguard Workerwith the deflate compression algorithm (defined in
99*cc02d7e2SAndroid Build Coastguard Worker[RFC 1951](https://datatracker.ietf.org/doc/html/rfc1951)).
100*cc02d7e2SAndroid Build Coastguard WorkerServers and clients MUST NOT send raw deflate data.
101*cc02d7e2SAndroid Build Coastguard Worker
102*cc02d7e2SAndroid Build Coastguard Worker### Test cases
103*cc02d7e2SAndroid Build Coastguard Worker
104*cc02d7e2SAndroid Build Coastguard Worker1. When a compression level is not specified for either the channel or the
105*cc02d7e2SAndroid Build Coastguard Workermessage, the default channel level _none_ is considered: data MUST NOT be
106*cc02d7e2SAndroid Build Coastguard Workercompressed.
107*cc02d7e2SAndroid Build Coastguard Worker1. When per-RPC compression configuration isn't present for a message, the
108*cc02d7e2SAndroid Build Coastguard Workerchannel compression configuration MUST be used.
109*cc02d7e2SAndroid Build Coastguard Worker1. When a compression method (including no compression) is specified for an
110*cc02d7e2SAndroid Build Coastguard Workeroutgoing message, the message MUST be compressed accordingly.
111*cc02d7e2SAndroid Build Coastguard Worker1. A message compressed by a client in a way not supported by its server MUST
112*cc02d7e2SAndroid Build Coastguard Workerfail with status `UNIMPLEMENTED`, its associated description indicating the
113*cc02d7e2SAndroid Build Coastguard Workerunsupported condition as well as the supported ones. The returned
114*cc02d7e2SAndroid Build Coastguard Worker`grpc-accept-encoding` header MUST NOT contain the compression method
115*cc02d7e2SAndroid Build Coastguard Worker(encoding) used.
116*cc02d7e2SAndroid Build Coastguard Worker1. A message compressed by a server in a way not supported by its client MUST
117*cc02d7e2SAndroid Build Coastguard Workerfail with status `INTERNAL`, its associated description indicating the
118*cc02d7e2SAndroid Build Coastguard Workerunsupported condition as well as the supported ones. The returned
119*cc02d7e2SAndroid Build Coastguard Worker`grpc-accept-encoding` header MUST NOT contain the compression method
120*cc02d7e2SAndroid Build Coastguard Worker(encoding) used.
121*cc02d7e2SAndroid Build Coastguard Worker1. An ill-constructed message with its [Compressed-Flag
122*cc02d7e2SAndroid Build Coastguard Workerbit](PROTOCOL-HTTP2.md#compressed-flag)
123*cc02d7e2SAndroid Build Coastguard Workerset but lacking a
124*cc02d7e2SAndroid Build Coastguard Worker[grpc-encoding](PROTOCOL-HTTP2.md#message-encoding)
125*cc02d7e2SAndroid Build Coastguard Workerentry different from _identity_ in its metadata MUST fail with `INTERNAL`
126*cc02d7e2SAndroid Build Coastguard Workerstatus, its associated description indicating the invalid Compressed-Flag
127*cc02d7e2SAndroid Build Coastguard Workercondition.
128