OLD | NEW |
(Empty) | |
| 1 # gRPC over HTTP2 |
| 2 |
| 3 ## Introduction |
| 4 This document serves as a detailed description for an implementation of gRPC car
ried over HTTP2 draft 17 framing. It assumes familiarity with the HTTP2 specific
ation. |
| 5 |
| 6 ## Protocol |
| 7 Production rules are using <a href="http://tools.ietf.org/html/rfc5234">ABNF syn
tax</a>. |
| 8 |
| 9 ### Outline |
| 10 |
| 11 The following is the general sequence of message atoms in a GRPC request & respo
nse message stream |
| 12 |
| 13 * Request → Request-Headers \*Length-Prefixed-Message EOS |
| 14 * Response → (Response-Headers \*Length-Prefixed-Message Trailers) / Trailers-On
ly |
| 15 |
| 16 |
| 17 ### Requests |
| 18 |
| 19 * Request → Request-Headers \*Length-Prefixed-Message EOS |
| 20 |
| 21 Request-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" {_path identifying method within exposed API_} |
| 28 * **Authority** → ":authority" {_virtual host name of authority_} |
| 29 * **TE** → "te" "trailers" # Used to detect incompatible proxies |
| 30 * **Timeout** → "grpc-timeout" TimeoutValue TimeoutUnit |
| 31 * **TimeoutValue** → {_positive integer as ASCII string of at most 8 digits_} |
| 32 * **TimeoutUnit** → Hour / Minute / Second / Millisecond / Microsecond / Nanosec
ond |
| 33 * **Hour** → "H" |
| 34 * **Minute** → "M" |
| 35 * **Second** → "S" |
| 36 * **Millisecond** → "m" |
| 37 * **Microsecond** → "u" |
| 38 * **Nanosecond** → "n" |
| 39 * **Content-Type** → "content-type" "application/grpc" [("+proto" / "+json" / {_
custom_})] |
| 40 * **Content-Coding** → "identity" / "gzip" / "deflate" / "snappy" / {_custom_} |
| 41 * **Message-Encoding** → "grpc-encoding" Content-Coding |
| 42 * **Message-Accept-Encoding** → "grpc-accept-encoding" Content-Coding \*("," Con
tent-Coding) |
| 43 * **User-Agent** → "user-agent" {_structured user-agent string_} |
| 44 * **Message-Type** → "grpc-message-type" {_type name for message schema_} |
| 45 * **Custom-Metadata** → Binary-Header / ASCII-Header |
| 46 * **Binary-Header** → {Header-Name "-bin" } {_base64 encoded value_} |
| 47 * **ASCII-Header** → Header-Name ASCII-Value |
| 48 * **Header-Name** → 1\*( %x30-39 / %x61-7A / "\_" / "-" / ".") ; 0-9 a-z \_ - . |
| 49 * **ASCII-Value** → 1\*( %x20-%x7E ) ; space and printable ASCII |
| 50 |
| 51 |
| 52 HTTP2 requires that reserved headers, ones starting with ":" appear before all o
ther headers. Additionally implementations should send **Timeout** immediately a
fter the reserved headers and they should send the **Call-Definition** headers b
efore sending **Custom-Metadata**. |
| 53 |
| 54 If **Timeout** is omitted a server should assume an infinite timeout. Client imp
lementations are free to send a default minimum timeout based on their deploymen
t requirements. |
| 55 |
| 56 **Custom-Metadata** is an arbitrary set of key-value pairs defined by the applic
ation 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
**. |
| 57 |
| 58 Note that HTTP2 does not allow arbitrary octet sequences for header values so bi
nary header values must be encoded using Base64 as per https://tools.ietf.org/ht
ml/rfc4648#section-4. Implementations MUST accept padded and un-padded values an
d should emit un-padded values. Applications define binary headers by having the
ir names end with "-bin". Runtime libraries use this suffix to detect binary hea
ders and properly apply base64 encoding & decoding as headers are sent and recei
ved. |
| 59 |
| 60 **Custom-Metadata** header order is not guaranteed to be preserved except for |
| 61 values with duplicate header names. Duplicate header names may have their values |
| 62 joined with "," as the delimiter and be considered semantically equivalent. |
| 63 Implementations must split **Binary-Header**s on "," before decoding the |
| 64 Base64-encoded values. |
| 65 |
| 66 **ASCII-Value** should not have leading or trailing whitespace. If it contains |
| 67 leading or trailing whitespace, it may be stripped. The **ASCII-Value** |
| 68 character range defined is more strict than HTTP. Implementations must not error |
| 69 due to receiving an invalid **ASCII-Value** that's a valid **field-value** in |
| 70 HTTP, but the precise behavior is not strictly defined: they may throw the value |
| 71 away or accept the value. If accepted, care must be taken to make sure that the |
| 72 application is permitted to echo the value back as metadata. For example, if the |
| 73 metadata is provided to the application as a list in a request, the application |
| 74 should not trigger an error by providing that same list as the metadata in the |
| 75 response. |
| 76 |
| 77 Servers may limit the size of **Request-Headers**, with a default of 8 KiB |
| 78 suggested. Implementations are encouraged to compute total header size like |
| 79 HTTP/2's `SETTINGS_MAX_HEADER_LIST_SIZE`: the sum of all header fields, for each |
| 80 field the sum of the uncompressed field name and value lengths plus 32, with |
| 81 binary values' lengths being post-Base64. |
| 82 |
| 83 The repeated sequence of **Length-Prefixed-Message** items is delivered in DATA
frames |
| 84 |
| 85 * **Length-Prefixed-Message** → Compressed-Flag Message-Length Message |
| 86 * **Compressed-Flag** → 0 / 1 # encoded as 1 byte unsigned integer |
| 87 * **Message-Length** → {_length of Message_} # encoded as 4 byte unsigned integ
er |
| 88 * **Message** → \*{binary octet} |
| 89 |
| 90 A **Compressed-Flag** value of 1 indicates that the binary octet sequence of **M
essage** is compressed using the mechanism declared by the **Message-Encoding**
header. A value of 0 indicates that no encoding of **Message** bytes has occurre
d. Compression contexts are NOT maintained over message boundaries, implementati
ons must create a new context for each message in the stream. If the **Message-E
ncoding** header is omitted then the **Compressed-Flag** must be 0. |
| 91 |
| 92 For requests, **EOS** (end-of-stream) is indicated by the presence of the END_ST
REAM flag on the last received DATA frame. In scenarios where the **Request** st
ream needs to be closed but no data remains to be sent implementations MUST send
an empty DATA frame with this flag set. |
| 93 |
| 94 ###Responses |
| 95 |
| 96 * **Response** → (Response-Headers \*Length-Prefixed-Message Trailers) / Trailer
s-Only |
| 97 * **Response-Headers** → HTTP-Status [Message-Encoding] [Message-Accept-Encoding
] Content-Type \*Custom-Metadata |
| 98 * **Trailers-Only** → HTTP-Status Content-Type Trailers |
| 99 * **Trailers** → Status [Status-Message] \*Custom-Metadata |
| 100 * **HTTP-Status** → ":status 200" |
| 101 * **Status** → "grpc-status" <status-code-as-ASCII-string> |
| 102 * **Status-Message** → "grpc-message" <descriptive text for status as ASCII stri
ng> |
| 103 |
| 104 **Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HE
ADERS frame block. Most responses are expected to have both headers and trailers
but **Trailers-Only** is permitted for calls that produce an immediate error. S
tatus must be sent in **Trailers** even if the status code is OK. |
| 105 |
| 106 For responses end-of-stream is indicated by the presence of the END_STREAM flag
on the last received HEADERS frame that carries **Trailers**. |
| 107 |
| 108 Implementations should expect broken deployments to send non-200 HTTP status cod
es in responses as well as a variety of non-GRPC content-types and to omit **Sta
tus** & **Status-Message**. Implementations must synthesize a **Status** & **Sta
tus-Message** to propagate to the application layer when this occurs. |
| 109 |
| 110 Clients may limit the size of **Response-Headers**, **Trailers**, and |
| 111 **Trailers-Only**, with a default of 8 KiB each suggested. |
| 112 |
| 113 ####Example |
| 114 |
| 115 Sample unary-call showing HTTP2 framing sequence |
| 116 |
| 117 **Request** |
| 118 |
| 119 ``` |
| 120 HEADERS (flags = END_HEADERS) |
| 121 :method = POST |
| 122 :scheme = http |
| 123 :path = /google.pubsub.v2.PublisherService/CreateTopic |
| 124 :authority = pubsub.googleapis.com |
| 125 grpc-timeout = 1S |
| 126 content-type = application/grpc+proto |
| 127 grpc-encoding = gzip |
| 128 authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v |
| 129 |
| 130 DATA (flags = END_STREAM) |
| 131 <Length-Prefixed Message> |
| 132 ``` |
| 133 **Response** |
| 134 ``` |
| 135 HEADERS (flags = END_HEADERS) |
| 136 :status = 200 |
| 137 grpc-encoding = gzip |
| 138 |
| 139 DATA |
| 140 <Length-Prefixed Message> |
| 141 |
| 142 HEADERS (flags = END_STREAM, END_HEADERS) |
| 143 grpc-status = 0 # OK |
| 144 trace-proto-bin = jher831yy13JHy3hc |
| 145 ``` |
| 146 ####User Agents |
| 147 |
| 148 While the protocol does not require a user-agent to function it is recommended t
hat clients provide a structured user-agent string that provides a basic descrip
tion of the calling library, version & platform to facilitate issue diagnosis in
heterogeneous environments. The following structure is recommended to library d
evelopers |
| 149 ``` |
| 150 User-Agent → "grpc-" Language ?("-" Variant) "/" Version ?( " (" *(AdditionalPr
operty ";") ")" ) |
| 151 ``` |
| 152 E.g. |
| 153 |
| 154 ``` |
| 155 grpc-java/1.2.3 |
| 156 grpc-ruby/1.2.3 |
| 157 grpc-ruby-jruby/1.3.4 |
| 158 grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile) |
| 159 ``` |
| 160 ####HTTP2 Transport Mapping |
| 161 |
| 162 #####Stream Identification |
| 163 All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as c
all identifiers in this scheme. NOTE: These id’s are contextual to an open HTTP2
session and will not be unique within a given process that is handling more tha
n one HTTP2 session nor can they be used as GUIDs. |
| 164 |
| 165 #####Data Frames |
| 166 DATA frame boundaries have no relation to **Length-Prefixed-Message** boundaries
and implementations should make no assumptions about their alignment. |
| 167 |
| 168 #####Errors |
| 169 |
| 170 When an application or runtime error occurs during an RPC a **Status** and **Sta
tus-Message** are delivered in **Trailers**. |
| 171 |
| 172 In some cases it is possible that the framing of the message stream has become c
orrupt and the RPC runtime will choose to use an **RST_STREAM** frame to indicat
e this state to its peer. RPC runtime implementations should interpret RST_STREA
M as immediate full-closure of the stream and should propagate an error up to th
e calling application layer. |
| 173 |
| 174 The following mapping from RST_STREAM error codes to GRPC error codes is applied
. |
| 175 |
| 176 HTTP2 Code|GRPC Code |
| 177 ----------|----------- |
| 178 NO_ERROR(0)|INTERNAL - An explicit GRPC status of OK should have been sent but t
his might be used to aggressively lameduck in some scenarios. |
| 179 PROTOCOL_ERROR(1)|INTERNAL |
| 180 INTERNAL_ERROR(2)|INTERNAL |
| 181 FLOW_CONTROL_ERROR(3)|INTERNAL |
| 182 SETTINGS_TIMEOUT(4)|INTERNAL |
| 183 STREAM_CLOSED|No mapping as there is no open stream to propagate to. Implementat
ions should log. |
| 184 FRAME_SIZE_ERROR|INTERNAL |
| 185 REFUSED_STREAM|UNAVAILABLE - Indicates that no processing occurred and the reque
st can be retried, possibly elsewhere. |
| 186 CANCEL(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 the
y need to cancel a call but the payload byte sequence is incomplete. |
| 187 COMPRESSION_ERROR|INTERNAL |
| 188 CONNECT_ERROR|INTERNAL |
| 189 ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED ...with additional error detail provided by
runtime to indicate that the exhausted resource is bandwidth. |
| 190 INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating that
permission was denied as protocol is not secure enough for call. |
| 191 |
| 192 |
| 193 #####Security |
| 194 |
| 195 The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used w
ith 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 secu
rity mechanisms about which the specification can make no meaningful recommendat
ions. |
| 196 |
| 197 #####Connection Management |
| 198 ######GOAWAY Frame |
| 199 Sent by servers to clients to indicate that they will no longer accept any new s
treams on the associated connections. This frame includes the id of the last suc
cessfully accepted stream by the server. Clients should consider any stream init
iated after the last successfully accepted stream as UNAVAILABLE and retry the c
all elsewhere. Clients are free to continue working with the already accepted st
reams until they complete or the connection is terminated. |
| 200 |
| 201 Servers should send GOAWAY before terminating a connection to reliably inform cl
ients which work has been accepted by the server and is being executed. |
| 202 |
| 203 ######PING Frame |
| 204 Both 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 CANCELL
ED status. An expired client initiated PING will cause all calls to be closed wi
th an UNAVAILABLE status. Note that the frequency of PINGs is highly dependent o
n the network environment, implementations are free to adjust PING frequency bas
ed on network and application requirements. |
| 205 |
| 206 ######Connection failure |
| 207 If 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 CANCEL
LED status. |
| 208 |
| 209 |
| 210 ### Appendix A - GRPC for Protobuf |
| 211 |
| 212 The service interfaces declared by protobuf are easily mapped onto GRPC by code
generation extensions to protoc. The following defines the mapping to be used |
| 213 |
| 214 |
| 215 * **Path** → / Service-Name / {_method name_} |
| 216 * **Service-Name** → ?( {_proto package name_} "." ) {_service name_} |
| 217 * **Message-Type** → {_fully qualified proto message name_} |
| 218 * **Content-Type** → "application/grpc+proto" |
| 219 |
| 220 |
OLD | NEW |