mirror of https://github.com/grpc/grpc.git
The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
https://grpc.io/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
5.8 KiB
118 lines
5.8 KiB
## **gRPC Compression** |
|
|
|
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", |
|
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be |
|
interpreted as described in [RFC 2119](http://www.ietf.org/rfc/rfc2119.txt). |
|
|
|
### Intent |
|
|
|
Compression is used to reduce the amount of bandwidth used between peers. The |
|
compression supported by gRPC acts _at the individual message level_, taking |
|
_message_ [as defined in the wire format |
|
document](PROTOCOL-HTTP2.md). |
|
|
|
The implementation supports different compression algorithms. A _default |
|
compression level_, to be used in the absence of message-specific settings, MAY |
|
be specified for during channel creation. |
|
|
|
The ability to control compression settings per call and to enable/disable |
|
compression on a per message basis MAY be used to prevent CRIME/BEAST attacks. |
|
It also allows for asymmetric compression communication, whereby a response MAY |
|
be compressed differently, if at all. |
|
|
|
### Specification |
|
|
|
Compression MAY be configured by the Client Application by calling the |
|
appropriate API method. There are two scenarios where compression MAY be |
|
configured: |
|
|
|
+ At channel creation time, which sets the channel default compression and |
|
therefore the compression that SHALL be used in the absence of per-RPC |
|
compression configuration. |
|
+ At response time, via: |
|
+ For unary RPCs, the {Client,Server}Context instance. |
|
+ For streaming RPCs, the {Client,Server}Writer instance. In this case, |
|
configuration is reduced to disabling compression altogether. |
|
|
|
### Compression Method Asymmetry Between Peers |
|
|
|
A gRPC peer MAY choose to respond using a different compression method to that |
|
of the request, including not performing any compression, regardless of channel |
|
and RPC settings (for example, if compression would result in small or negative |
|
gains). |
|
|
|
When a message from a client compressed with an unsupported algorithm is |
|
processed by a server, it WILL result in an `UNIMPLEMENTED` error status on the |
|
server. The server will then include in its response a `grpc-accept-encoding` |
|
header specifying the algorithms it does accept. If an `UNIMPLEMENTED` error |
|
status is returned from the server despite having used one of the algorithms |
|
from the `grpc-accept-encoding` header, the cause MUST NOT be related to |
|
compression. Data sent from a server compressed with an algorithm not supported |
|
by the client WILL result in an `INTERNAL` error status on the client side. |
|
|
|
Note that a peer MAY choose to not disclose all the encodings it supports. |
|
However, if it receives a message compressed in an undisclosed but supported |
|
encoding, it MUST include said encoding in the response's `grpc-accept-encoding |
|
h`eader. |
|
|
|
For every message a server is requested to compress using an algorithm it knows |
|
the client doesn't support (as indicated by the last `grpc-accept-encoding` |
|
header received from the client), it SHALL send the message uncompressed. |
|
|
|
### Specific Disabling of Compression |
|
|
|
If the user (through the previously described mechanisms) requests to disable |
|
compression the next message MUST be sent uncompressed. This is instrumental in |
|
preventing BEAST/CRIME attacks. This applies to both the the unary and streaming |
|
cases. |
|
|
|
### Compression Levels and Algorithms |
|
|
|
The set of supported algorithm is implementation dependent. In order to simplify |
|
the public API and to operate seamlessly across implementations (both in terms |
|
of languages but also different version of the same one), we introduce the idea |
|
of _compression levels_ (such as "low", "medium", "high"). |
|
|
|
Levels map to concrete algorithms and/or their settings (such as "low" mapping |
|
to "gzip -3" and "high" mapping to "gzip -9") automatically depending on what a |
|
peer is known to support. A server is always aware of what its clients support, |
|
as clients disclose it in their Message-Accept-Encoding header as part of their |
|
initial call. A client doesn't a priori (presently) know which algorithms a |
|
server supports. This issue can be addressed with an initial negotiation of |
|
capabilities or an automatic retry mechanism. These features will be implemented |
|
in the future. Currently however, compression levels are only supported at the |
|
server side, which is aware of the client's capabilities through the incoming |
|
Message-Accept-Encoding header. |
|
|
|
### Propagation to child RPCs |
|
|
|
The inheritance of the compression configuration by child RPCs is left up to the |
|
implementation. Note that in the absence of changes to the parent channel, its |
|
configuration will be used. |
|
|
|
### Test cases |
|
|
|
1. When a compression level is not specified for either the channel or the |
|
message, the default channel level _none_ is considered: data MUST NOT be |
|
compressed. |
|
1. When per-RPC compression configuration isn't present for a message, the |
|
channel compression configuration MUST be used. |
|
1. When a compression method (including no compression) is specified for an |
|
outgoing message, the message MUST be compressed accordingly. |
|
1. A message compressed by a client in a way not supported by its server MUST |
|
fail with status `UNIMPLEMENTED`, its associated description indicating the |
|
unsupported condition as well as the supported ones. The returned |
|
`grpc-accept-encoding` header MUST NOT contain the compression method |
|
(encoding) used. |
|
1. A message compressed by a server in a way not supported by its client MUST |
|
fail with status `INTERNAL`, its associated description indicating the |
|
unsupported condition as well as the supported ones. The returned |
|
`grpc-accept-encoding` header MUST NOT contain the compression method |
|
(encoding) used. |
|
1. An ill-constructed message with its [Compressed-Flag |
|
bit](PROTOCOL-HTTP2.md#compressed-flag) |
|
set but lacking a |
|
"[grpc-encoding](PROTOCOL-HTTP2.md#message-encoding)" |
|
entry different from _identity_ in its metadata MUST fail with `INTERNAL` |
|
status, its associated description indicating the invalid Compressed-Flag |
|
condition.
|
|
|