1# gRPC over HTTP2 2 3## Introduction 4This document serves as a detailed description for an implementation of gRPC carried over <a href="https://tools.ietf.org/html/rfc7540">HTTP2 framing</a>. It assumes familiarity with the HTTP2 specification. 5 6## Protocol 7Production rules are using <a href="https://tools.ietf.org/html/rfc5234">ABNF syntax</a>. 8 9### Outline 10 11The following is the general sequence of message atoms in a GRPC request & response message stream 12 13* Request → Request-Headers \*Length-Prefixed-Message EOS 14* Response → (Response-Headers \*Length-Prefixed-Message Trailers) / Trailers-Only 15 16 17### Requests 18 19* Request → Request-Headers \*Length-Prefixed-Message EOS 20 21Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames. 22 23* **Request-Headers** → Call-Definition \*Custom-Metadata 24* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] Content-Type [Message-Type] [Message-Encoding] [Message-Accept-Encoding] [User-Agent] 25* **Method** → ":method POST" 26* **Scheme** → ":scheme " ("http" / "https") 27* **Path** → ":path" "/" Service-Name "/" {_method name_} ; But see note below. 28* **Service-Name** → {_IDL-specific service name_} 29* **Authority** → ":authority" {_virtual host name of authority_} 30* **TE** → "te" "trailers" ; Used to detect incompatible proxies 31* **Timeout** → "grpc-timeout" TimeoutValue TimeoutUnit 32* **TimeoutValue** → {_positive integer as ASCII string of at most 8 digits_} 33* **TimeoutUnit** → Hour / Minute / Second / Millisecond / Microsecond / Nanosecond 34 * **Hour** → "H" 35 * **Minute** → "M" 36 * **Second** → "S" 37 * **Millisecond** → "m" 38 * **Microsecond** → "u" 39 * **Nanosecond** → "n" 40* **Content-Type** → "content-type" "application/grpc" [("+proto" / "+json" / {_custom_})] 41* **Content-Coding** → "identity" / "gzip" / "deflate" / "snappy" / {_custom_} 42* <a name="message-encoding"></a>**Message-Encoding** → "grpc-encoding" Content-Coding 43* **Message-Accept-Encoding** → "grpc-accept-encoding" Content-Coding \*("," Content-Coding) 44* **User-Agent** → "user-agent" {_structured user-agent string_} 45* **Message-Type** → "grpc-message-type" {_type name for message schema_} 46* **Custom-Metadata** → Binary-Header / ASCII-Header 47* **Binary-Header** → {Header-Name "-bin" } {_base64 encoded value_} 48* **ASCII-Header** → Header-Name ASCII-Value 49* **Header-Name** → 1\*( %x30-39 / %x61-7A / "\_" / "-" / ".") ; 0-9 a-z \_ - . 50* **ASCII-Value** → 1\*( %x20-%x7E ) ; space and printable ASCII 51 52 53HTTP2 requires that reserved headers, ones starting with ":" appear before all other headers. Additionally implementations should send **Timeout** immediately after the reserved headers and they should send the **Call-Definition** headers before sending **Custom-Metadata**. 54 55**Path** is case-sensitive. Some gRPC implementations may allow the **Path** 56format shown above to be overridden, but this functionality is strongly 57discouraged. gRPC does not go out of its way to break users that are using this 58kind of override, but we do not actively support it, and some functionality 59(e.g., service config support) will not work when the path is not of the form 60shown above. 61 62If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements. 63 64If **Content-Type** does not begin with "application/grpc", gRPC servers SHOULD respond with HTTP status of 415 (Unsupported Media Type). This will prevent other HTTP/2 clients from interpreting a gRPC error response, which uses status 200 (OK), as successful. 65 66**Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**. 67 68Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. Applications define binary headers by having their names end with "-bin". Runtime libraries use this suffix to detect binary headers and properly apply base64 encoding & decoding as headers are sent and received. 69 70**Custom-Metadata** header order is not guaranteed to be preserved except for 71values with duplicate header names. Duplicate header names may have their values 72joined with "," as the delimiter and be considered semantically equivalent. 73Implementations must split **Binary-Header**s on "," before decoding the 74Base64-encoded values. 75 76**ASCII-Value** should not have leading or trailing whitespace. If it contains 77leading or trailing whitespace, it may be stripped. The **ASCII-Value** 78character range defined is stricter than HTTP. Implementations must not error 79due to receiving an invalid **ASCII-Value** that's a valid **field-value** in 80HTTP, but the precise behavior is not strictly defined: they may throw the value 81away or accept the value. If accepted, care must be taken to make sure that the 82application is permitted to echo the value back as metadata. For example, if the 83metadata is provided to the application as a list in a request, the application 84should not trigger an error by providing that same list as the metadata in the 85response. 86 87Servers may limit the size of **Request-Headers**, with a default of 8 KiB 88suggested. Implementations are encouraged to compute total header size like 89HTTP/2's `SETTINGS_MAX_HEADER_LIST_SIZE`: the sum of all header fields, for each 90field the sum of the uncompressed field name and value lengths plus 32, with 91binary values' lengths being post-Base64. 92 93The repeated sequence of **Length-Prefixed-Message** items is delivered in DATA frames 94 95* **Length-Prefixed-Message** → Compressed-Flag Message-Length Message 96* <a name="compressed-flag"></a>**Compressed-Flag** → 0 / 1 ; encoded as 1 byte unsigned integer 97* **Message-Length** → {_length of Message_} ; encoded as 4 byte unsigned integer (big endian) 98* **Message** → \*{binary octet} 99 100A **Compressed-Flag** value of 1 indicates that the binary octet sequence of **Message** is compressed using the mechanism declared by the **Message-Encoding** header. A value of 0 indicates that no encoding of **Message** bytes has occurred. Compression contexts are NOT maintained over message boundaries, implementations must create a new context for each message in the stream. If the **Message-Encoding** header is omitted then the **Compressed-Flag** must be 0. 101 102For requests, **EOS** (end-of-stream) is indicated by the presence of the END_STREAM flag on the last received DATA frame. In scenarios where the **Request** stream needs to be closed but no data remains to be sent implementations MUST send an empty DATA frame with this flag set. 103 104### Responses 105 106* **Response** → (Response-Headers \*Length-Prefixed-Message Trailers) / Trailers-Only 107* **Response-Headers** → HTTP-Status [Message-Encoding] [Message-Accept-Encoding] Content-Type \*Custom-Metadata 108* **Trailers-Only** → HTTP-Status Content-Type Trailers 109* **Trailers** → Status [Status-Message] [Status-Details] \*Custom-Metadata 110* **HTTP-Status** → ":status 200" 111* **Status** → "grpc-status" 1\*DIGIT ; 0-9 112* **Status-Message** → "grpc-message" Percent-Encoded 113* **Status-Details** → "grpc-status-details-bin" {base64 encoded value} ; See notes below. 114* **Percent-Encoded** → 1\*(Percent-Byte-Unencoded / Percent-Byte-Encoded) 115* **Percent-Byte-Unencoded** → 1\*( %x20-%x24 / %x26-%x7E ) ; space and VCHAR, except % 116* **Percent-Byte-Encoded** → "%" 2HEXDIGIT ; 0-9 A-F 117 118**Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK. 119 120For responses end-of-stream is indicated by the presence of the END_STREAM flag on the last received HEADERS frame that carries **Trailers**. 121 122Implementations should expect broken deployments to send non-200 HTTP status codes in responses as well as a variety of non-GRPC content-types and to omit **Status** & **Status-Message**. Implementations must synthesize a **Status** & **Status-Message** to propagate to the application layer when this occurs. 123 124Clients may limit the size of **Response-Headers**, **Trailers**, and 125**Trailers-Only**, with a default of 8 KiB each suggested. 126 127The value portion of **Status** is a decimal-encoded integer as an ASCII string, 128without any leading zeros. 129 130The value portion of **Status-Message** is conceptually a Unicode string 131description of the error, physically encoded as UTF-8 followed by 132percent-encoding. Percent-encoding is specified in [RFC 3986 133§2.1](https://tools.ietf.org/html/rfc3986#section-2.1), although the form used 134here has different restricted characters. When decoding invalid values, 135implementations MUST NOT error or throw away the message. At worst, the 136implementation can abort decoding the status message altogether such that the 137user would received the raw percent-encoded form. Alternatively, the 138implementation can decode valid portions while leaving broken %-encodings as-is 139or replacing them with a replacement character (e.g., '?' or the Unicode 140replacement character). 141 142**Status-Details** is allowed only if **Status** is not OK. If it is set, it 143contains additional information about the RPC error. If it contains a status 144code field, it MUST NOT contradict the **Status** header. The consumer MUST 145verify this requirement. 146 147#### Example 148 149Sample unary-call showing HTTP2 framing sequence 150 151**Request** 152 153``` 154HEADERS (flags = END_HEADERS) 155:method = POST 156:scheme = http 157:path = /google.pubsub.v2.PublisherService/CreateTopic 158:authority = pubsub.googleapis.com 159grpc-timeout = 1S 160content-type = application/grpc+proto 161grpc-encoding = gzip 162authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v 163 164DATA (flags = END_STREAM) 165<Length-Prefixed Message> 166``` 167**Response** 168``` 169HEADERS (flags = END_HEADERS) 170:status = 200 171grpc-encoding = gzip 172content-type = application/grpc+proto 173 174DATA 175<Length-Prefixed Message> 176 177HEADERS (flags = END_STREAM, END_HEADERS) 178grpc-status = 0 # OK 179trace-proto-bin = jher831yy13JHy3hc 180``` 181 182#### User Agents 183 184While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers 185``` 186User-Agent → "grpc-" Language ?("-" Variant) "/" Version ?( " (" *(AdditionalProperty ";") ")" ) 187``` 188E.g. 189 190``` 191grpc-java/1.2.3 192grpc-ruby/1.2.3 193grpc-ruby-jruby/1.3.4 194grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile) 195``` 196 197#### Idempotency and Retries 198 199Unless explicitly defined to be, gRPC Calls are not assumed to be idempotent. Specifically: 200 201* Calls that cannot be proven to have started will not be retried. 202* There is no mechanism for duplicate suppression as it is not necessary. 203* Calls that are marked as idempotent may be sent multiple times. 204 205 206#### HTTP2 Transport Mapping 207 208##### Stream Identification 209All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These ids are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs. 210 211##### Data Frames 212DATA frame boundaries have no relation to **Length-Prefixed-Message** boundaries and implementations should make no assumptions about their alignment. 213 214##### Errors 215 216When an application or runtime error occurs during an RPC a **Status** and **Status-Message** are delivered in **Trailers**. 217 218In some cases it is possible that the framing of the message stream has become corrupt and the RPC runtime will choose to use an **RST_STREAM** frame to indicate this state to its peer. RPC runtime implementations should interpret RST_STREAM as immediate full-closure of the stream and should propagate an error up to the calling application layer. 219 220The following mapping from RST_STREAM error codes to GRPC error codes is applied. 221 222HTTP2 Code|GRPC Code 223----------|----------- 224NO_ERROR(0)|INTERNAL - An explicit GRPC status of OK should have been sent but this might be used to aggressively [lameduck](https://landing.google.com/sre/sre-book/chapters/load-balancing-datacenter/#identifying-bad-tasks-flow-control-and-lame-ducks-bEs0uy) in some scenarios. 225PROTOCOL_ERROR(1)|INTERNAL 226INTERNAL_ERROR(2)|INTERNAL 227FLOW_CONTROL_ERROR(3)|INTERNAL 228SETTINGS_TIMEOUT(4)|INTERNAL 229STREAM_CLOSED|No mapping as there is no open stream to propagate to. Implementations should log. 230FRAME_SIZE_ERROR|INTERNAL 231REFUSED_STREAM|UNAVAILABLE - Indicates that no processing occurred and the request can be retried, possibly elsewhere. 232CANCEL(8)|Mapped to call cancellation when sent by a client.Mapped to CANCELLED when sent by a server. Note that servers should only use this mechanism when they need to cancel a call but the payload byte sequence is incomplete. 233COMPRESSION_ERROR|INTERNAL 234CONNECT_ERROR|INTERNAL 235ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by runtime to indicate that the exhausted resource is bandwidth. 236INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that permission was denied as protocol is not secure enough for call. 237 238 239##### Security 240 241The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations. 242 243##### Connection Management 244 245###### GOAWAY Frame 246Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated. 247 248Servers should send GOAWAY before terminating a connection to reliably inform clients which work has been accepted by the server and is being executed. 249 250###### PING Frame 251Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. This is used to assert that the connection is still live as well as providing a means to estimate end-to-end latency. If a server initiated PING does not receive a response within the deadline expected by the runtime all outstanding calls on the server will be closed with a CANCELLED status. An expired client initiated PING will cause all calls to be closed with an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent on the network environment, implementations are free to adjust PING frequency based on network and application requirements. 252 253###### Connection failure 254If a detectable connection failure occurs on the client all calls will be closed with an UNAVAILABLE status. For servers open calls will be closed with a CANCELLED status. 255 256 257### Appendix A - GRPC for Protobuf 258 259The service interfaces declared by protobuf are easily mapped onto GRPC by 260code generation extensions to protoc. The following defines the mapping 261to be used. 262 263* **Service-Name** → ?( {_proto package name_} "." ) {_service name_} 264* **Message-Type** → {_fully qualified proto message name_} 265* **Content-Type** → "application/grpc+proto" 266* **Status-Details** → {_google.rpc.Status proto message_} 267