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.

143 lines
5.0 KiB

8 years ago
# gRPC Web
gRPC-Web provides a JS client library that supports the same API
as gRPC-Node to access a gRPC service. Due to browser limitation,
the Web client library implements a different protocol than the
[native gRPC protocol](PROTOCOL-HTTP2.md).
This protocol is designed to make it easy for a proxy to translate
between the protocols as this is the most likely deployment model.
This document lists the differences between the two protocols.
To help tracking future revisions, this document describes a delta
with the protocol details specified in the
[native gRPC protocol](PROTOCOL-HTTP2.md).
# Design goals
For the gRPC-Web protocol, we have decided on the following design goals:
* adopt the same framing as “application/grpc” whenever possible
5 years ago
* decouple from HTTP/2 framing which is not, and will never be, directly
exposed by browsers
* support text streams (e.g. base64) in order to provide cross-browser
support (e.g. IE-10)
While the new protocol will be published/reviewed publicly, we also
intend to keep the protocol as an internal detail to gRPC-Web.
More specifically, we expect the protocol to
* evolve over time, mainly to optimize for browser clients or support
web-specific features such as CORS, XSRF
* become optional (in 1-2 years) when browsers are able to speak the native
gRPC protocol via the new [whatwg streams API](https://github.com/whatwg/streams)
# Protocol differences vs [gRPC over HTTP2](PROTOCOL-HTTP2.md)
Content-Type
1. application/grpc-web
* e.g. application/grpc-web+[proto, json, thrift]
* the sender should always specify the message format, e.g. +proto, +json
* the receiver should assume the default is "+proto" when the message format is missing in Content-Type (as "application/grpc-web")
2. application/grpc-web-text
* text-encoded streams of “application/grpc-web”
* e.g. application/grpc-web-text+[proto, thrift]
---
HTTP wire protocols
1. support any HTTP/*, with no dependency on HTTP/2 specific framing
web: make HTTP field names case-insensitive (#32364) I'm opening this PR to (hopefully!) stimulate a discussion. In brief, I'd like to amend the gRPC-Web protocol docs to encourage implementations to follow HTTP semantics and compare HTTP field names case-insensitively. The gRPC-Web specification is a nicely-designed way for proxies to expose standard HTTP/2 gRPC servers to clients using less tightly-controlled HTTP stacks, such as web browsers. To serve that goal, it seems valuable to have the gRPC-Web specification follow [RFC 9110 (HTTP Semantics)](https://www.rfc-editor.org/rfc/rfc9110.html#name-field-names). Like previous RFCs, 9110 specifies that "field names are case-insensitive." However, the current gRPC-Web specification requires that servers and proxies "use lower-case header/trailer names" on the wire. In principle, mandating casing on the wire is normal for HTTP/2 and fine (if unusual) for HTTP/1.1; however, it encourages implementations to violate HTTP semantics and require lower-case names when _reading_ headers and trailers. I'd like to loosen the gRPC-Web specification to permit any casing on the wire for HTTP/1.1. I'd also like to emphasize that gRPC-Web implementations ought to follow standard HTTP semantics when _reading_ fields and compare names case-insensitively. Implementations that can't treat names case-insensitively without breaking backward compatibility should instead normalize field names to lowercase. Among the Google-maintained gRPC implementations, at least `grpc-go` and `grpc-java` already compare names case-insensitively (even though they're HTTP/2-only). `grpc-dart` does the opposite and compares names case-sensitively. `grpc-web` is sometimes case-insensitive (when reading `grpc-status` and `grpc-message` from trailers-only responses) and sometimes case-sensitive (when hand-parsing a block of length-prefixed trailers). The proposed amendment does not affect the correctness of Envoy (which may continue to use lower-case field names). It partially affects `grpc-web`, which would require a small patch to always normalize names. (Both patched and unpatched versions of `grpc-web` would work with Envoy.) `grpc-dart` would need to either begin treating field names case-insensitively or normalize names, depending on what's possible in Dart without breaking backward compatibility. Relates to https://github.com/improbable-eng/grpc-web/issues/228, https://github.com/bufbuild/connect-go/issues/453/, and https://github.com/grpc/grpc-dart/issues/594.
2 years ago
2. header names may be upper- or mixed-case over HTTP/1.1, but trailers encoded in
the last length-prefixed message must always use lower-case names.
3. use EOF (end of body) to close the stream
---
HTTP/2 related behavior (specified in [gRPC over HTTP2](PROTOCOL-HTTP2.md))
1. stream-id is not supported or used
2. go-away is not supported or used
---
Message framing (vs. [http2-transport-mapping](PROTOCOL-HTTP2.md#http2-transport-mapping))
1. Response status encoded as part of the response body
* Key-value pairs encoded as a HTTP/1 headers block (without the terminating newline), per https://tools.ietf.org/html/rfc7230#section-3.2
```
key1: foo\r\n
key2: bar\r\n
```
2. 8th (MSB) bit of the 1st gRPC frame byte
* 0: data
* 1: trailers
```
10000000b: an uncompressed trailer (as part of the body)
10000001b: a compressed trailer
```
3. Trailers must be the last message of the response, as enforced
by the implementation
4. Trailers-only responses: no change to the gRPC protocol spec.
Trailers may be sent together with response headers, with no message
in the body.
---
User Agent
* Do NOT use User-Agent header (which is to be set by browsers, by default)
* Use X-User-Agent: grpc-web-javascript/0.1 (follow the same format as specified in [gRPC over HTTP2](PROTOCOL-HTTP2.md))
---
Text-encoded (response) streams
1. The client library should indicate to the server via the "Accept" header that
the response stream needs to be text encoded e.g. when XHR is used or due
to security policies with XHR
* Accept: application/grpc-web-text
2. The default text encoding is base64
* Note that “Content-Transfer-Encoding: base64” should not be used.
Due to in-stream base64 padding when delimiting messages, the entire
response body is not necessarily a valid base64-encoded entity
* While the server runtime will always base64-encode and flush gRPC messages
atomically the client library should not assume base64 padding always
happens at the boundary of message frames. That is, the implementation may send base64-encoded "chunks" with potential padding whenever the runtime needs to flush a byte buffer.
# Other features
Retries, caching
* Will spec out the support after their respective gRPC spec extensions
are finalized
* Safe retries: PUT
* Caching: header encoded request and/or a web specific spec
---
Keep-alive
* HTTP/2 PING is not supported or used
* Will not support send-beacon (GET)
---
Bidi-streaming, with flow-control
* Pending on [whatwg fetch/streams](https://github.com/whatwg/fetch) to be
finalized and implemented in modern browsers
* gRPC-Web client will support the native gRPC protocol with modern browsers
---
Versioning
* Special headers may be introduced to support features that may break compatibility.
---
Browser-specific features
* For features that are unique to browser or HTML clients, check the [spec doc](https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md) published in the grpc/grpc-web repo.