Why is envoy proxy required for grpc-web? - grpc

If the browser supports http/2, why does grpc-web require envoy proxy?
Is it just required for older browsers that do not support http/2?

Answered in https://github.com/grpc/grpc-web/issues/347. For gRPC-Web to work, we need a lot of the underlying transport to be exposed to us but that's not the case currently cross browsers. We cannot leverage the full http2 protocol given the current set of browser APIs.

Related

Enable http2 in nginx only for some clients

I have two set of users using okhttp/2.7.0 and okhttp/3.12.0. I want to enable http2 in nginx only for those users who are using okhttp/3.12.0. The client ensures to send their identifier. Is there a way to use this information and enable http2 only for those users.
Note: Multiple ports is not an option for me.
My nginx and OS version
nginx version: nginx/1.14.2
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4)
built with OpenSSL 1.0.2h 3 May 2016
TLS SNI support enabled
My nginx conf goes like this
server {
listen 443 ssl http2;
...
This is not really possible. The client is only sent as part of a HTTP message, which is only sent after the version of HTTP to use is decided, obviously. The initially message to create the connection, and set up the SSL/TLS parameters won’t have the client (which is usually where the HTTP version is decided using the ALPN extension to TLS).
There are however other ways this might be possible, including:
Depending on the capabilities of the client. I’m not familiar with okhttp but from a quick Google it seems ALPN support was only added in v3, so you could disable the older NPN on your server and then, if that is correct, then in theory the older client will not be able to negotiate HTTP/2 so will fallback to HTTP/1.1. Unfortunately there appears to be no Nginx config option for that so you’d need to build a special version of OpenSSL without NPN support and then compile Nginx against that. Probably more hassle than it’s worth.
Use Apache instead of Nginx as it never supported NPN
Using Multiple IPs and somehow directing each version to a separate IP. Though I suspect as you cannot use separate ports you probably cannot do this either.
All in all it’s a bit of hack to be honest and so is not something that I would suggest you pursue. What you have not explained however is why you want to use HTTP/2 for one set of clients but not the other. Maybe there’s a better way to achieve what you want if you explain that.

Why do browsers not support gRPC?

gRPC is based on HTTP/2, which (assumption) is widely supported by browsers. Therefore, I feel there should be no problem with gRPC from a browser.
However, it is clear that there is a problem. The protocol, grpc web, is different, as exists "due to browser limitation". There are also numerous blog post describing complicated tech stacks deployed to get gRPC to work from a browser.
I'm missing the actual problem - why does gRPC not simply work from browsers?
I now understand that browsers only supports HTTP/2 in the sense that they use it to fetch resources from the server on behalf of your application (javascript) code.
Javascipt application code can still only use HTTP/1 (which may be handled under the hood by the browser in an HTTP/2 connection). Therefore it is not possible for application code to use grpc.
If anyone should find where this is explained in the docs, it would be good to add a link to it here.
Most browsers use HTTP1.1 whereas GRPC only works with HTTP2. You can use nginx, envoy or traefic to run it behind a reverse proxy, very similar to how web sockets are often used behind a reverse proxy(in that case the http1 is upgraded to a websockets connection). The reverse proxy will send the grpc request sent over http1 to an http2 backend and vice versa. You can use Envoy(suggested/currently used by grpc-web), traefik(am using this personally) and nginx.

How to test HTTP/2 implementation on non-supporting browser?

To implement HTTP/2 support on nginx/1.11.1, I'm going to redirect all HTTP Request to HTTPS.
In this case, how will Bot and Browsers, that don't support HTTP/2 protocol, behave and render the page?
Is there a way for me to simulate HTTP/1.1 browser behavior on Chrome Developer Tools?
You are mixing two concepts here that are somehow related, but they are largely different: HTTP to HTTPs redirect, and HTTP 1.1 vs HTTP/2 negotiation.
Redirecting HTTP to HTTPS requests is fine. Virtually every client (browser, bot, etc) available these days is capable of understanding HTTPS requests.
As for HTTP 1.1 vs HTTP/2, Nginx will fallback to HTTP 1.1 if the HTTP/2 connection fails because the client doesn't support it.
Last but not least, this question has very little to do with StackOverflow. It is more appropriate in ServerFault or SuperUser.
Potentially interesting
TCP retransmission will increase. This could lead on poorly configured devices for connection abort.

HTTP/2 compatibility with old/ unsupported browsers

How does a website behave on a client that does not support the HTTP/2 protocol?Is there a backward compatibility of the server that the server falls back on HTTP/1?
Standard webservers will handle HTTP 1.x requests just fine and reply with HTTP 1.x responses. There are just too many browsers out there that don't speak HTTP/2 yet to completely drop HTTP 1.x support from a server.

Can RESTful web service benefit from SPDY protocol?

I am designing a RESTful web service. It will include some GET and POST requests. I am a bit confused whether the web service can benefit from SPDY protocol. I intend to use Ruby on Rails for the implementation. Are there any gems that support SPDY?
Potentially, yes.
One of the major design goals of SPDY is to reduce and amount of latency associated with each request. The way this is accomplished is by enabling multiplexing over the same TCP connection. Additionally, SPDY does header compression, which is a big win especially for REST style interactions which often cary very small (JSON) payloads, but send large HTTP headers (cookies, etc).
So, would SPDY give you a performance boost? It depends on your application, but there are specific optimizations within SPDY which should definitely help.
As far as "gems" for Ruby. There is the spdy gem which parses the protocol, but you shouldn't need it. SPDY is a layer below HTTP and should be mostly handled for you by the server. If you're interested in experimenting with it and you're using Rails, I would recommend trying Passenger + mod_spdy.
SPDY has nothing to do with the application itself. If you're using Apache, check mod_spdy. There is also SPDY daemon for rack.

Resources