cloudendpoints / esp

Extensible Service Proxy
https://cloud.google.com/endpoints/
BSD 2-Clause "Simplified" License
281 stars 74 forks source link

Support for gRPC web text #600

Closed sgammon closed 4 years ago

sgammon commented 5 years ago

Hello esteemed ESP authors,

I have been trying out grpc-web recently and am very happy with it. However, I went to do some server-side streaming, and discovered that it only supports streaming via the base64-based gRPC web text protocol (defined here).

It seems as though, when I send traffic through ESP using the text protocol, it doesn't work, but it does with the binary protocol.

Is there intent to someday support the text protocol?

qiwzhang commented 5 years ago

ESP doesn't support text protocol. Yes, we plan to support it.

sgammon commented 5 years ago

@qiwzhang, thank you. could this issue perhaps serve as a placeholder for that? i wasn't able to find an existing one but perhaps i missed it. sorry to request so many features especially after you have just implemented TLS. we are just big fans 😄

qiwzhang commented 5 years ago

@sgammon yes, we will use this issue to track it. We are glad that users like you requesting enhancement. We feel proud that our product is used by many users.

kanekv commented 4 years ago

@qiwzhang How your roadmap looks like wrt this feature? Thanks!

qiwzhang commented 4 years ago

ESPv2 has this feature. Maybe you can think about migrate to ESPv2

kanekv commented 4 years ago

@qiwzhang thanks for quick response!

agonper commented 4 years ago

ESPv2 has this feature. Maybe you can think about migrate to ESPv2

Hello, I'm testing a bit ESPv2 with grpc-web both in text and binary modes.

I've been able to setup CORS by setting cors preset and allowed headers via the ESPv2_ARGS environment variable through the Dockerfile like this:

ENV ESPv2_ARGS ^++^--cors_preset=basic++--cors_allow_headers="keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,authorization,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout"++--cors_expose_headers="grpc-status,grpc-message"

I've replicated the config from the gRPC-Web Hello World Guide.

However, when I'm making an unary request in text mode (Content-type: application/grpc-web-text) I'm getting a 400 code with this response:

Unexpected token.
AAAAACgKGEhlbGxvIGZy
^

And in binary mode (Content-type: application/grpc-web+proto) I'm getting another error:

Encountered non UTF-8 code points.
(
Hello from a 
^

Any ideas about what could be wrong? Thanks in advance

qiwzhang commented 4 years ago

Did it work without CORS flags? Your error has nothing to do with CORS, let us try it without CORS.

You can turn on debug mode in ESPv2 by setting --enable_debug in the ESPv2_ARGS, and check the ESPv2 Cloud Run log

What kind of client did you use to generate grpc_web request? Could you try to use curl directly to see if it works?

agonper commented 4 years ago

Hello @qiwzhang, many thanks for the fast reply.

Did it work without CORS flags? Your error has nothing to do with CORS, let us try it without CORS.

Sadly it did not work, I had to solve that first, given I was getting a preflight error: 'user-agent' header not being set in 'Access-Control-Allow-Headers'. I guess because it is case sensitive.

You can turn on debug mode in ESPv2 by setting --enable_debug in the ESPv2_ARGS, and check the ESPv2 Cloud Run log

I've just done this. It seems to be specifically failing here:

envoy] [28][http2][external/envoy/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc:607] Transcoding request error INVALID_ARGUMENT:Unexpected token.\nAAAAACgKGEhlbGxvIGZy\n^

Looks like the Base64 string is not being decoded.

What kind of client did you use to generate grpc_web request? Could you try to use curl directly to see if it works?

It's a fresh Vue project with Typescript (client stub is in TypeScript too). Client stub has been generated with latest version of grpc-web. My browser is Chrome/83.0.4103.61.

As you have suggested, I've tried do the same request with curl. In order to do that, I've used "copy as curl" option from Chrome's network tab. You can replicate the output error with the following command:

curl 'https://api-gateway-3t5ec74iwa-ew.a.run.app/api.EphemeralNotes/PublishNote' \
  -H 'authority: api-gateway-3t5ec74iwa-ew.a.run.app' \
  -H 'accept: application/grpc-web-text' \
  -H 'x-user-agent: grpc-web-javascript/0.1' \
  -H 'x-grpc-web: 1' \
  -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36' \
  -H 'content-type: application/grpc-web-text' \
  -H 'origin: http://localhost:8080' \
  -H 'sec-fetch-site: cross-site' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: http://localhost:8080/' \
  -H 'accept-language: es-ES,es;q=0.9,en-US;q=0.8,en;q=0.7,ca-ES;q=0.6,ca;q=0.5' \
  --data-binary 'AAAAACcKGEhlbGxvIGZyb20gYSB3ZWIgY2xpZW50IRILCI3UxfYFEMCZsis=' \
  --compressed

Feel free to test, I'll shut down the Google Cloud project once done testing. This is just a test project. The code is open sourced, in case it helps: https://github.com/agonper/multi-client-grpc. By the way I forgot to mention that both ESP and backend server have been deployed through Google Cloud Run (fully managed) and that I'm using Google Cloud Endpoints.

Many thanks for your help


Edit: Also forgot to mention, that requests against the ESP are working fine from a golang client, which uses a generated Go client and TLS protocol. So the issue is specific to grpc-web

qiwzhang commented 4 years ago

I am investigating this bug now.

agonper commented 4 years ago

Thanks @qiwzhang, I really appreciate it.

Apologies in case this wasn't the best place to post this issue. I've just realized that the ESPv2 code (and issue tracker) is in another repo and not in this one. The ongoing conversation seemed a good fit for this bug ;)

qiwzhang commented 4 years ago

It is fine, it is the same team working on two repo. I believe I have found the problem, will have the fix soon.

agonper commented 4 years ago

Glad to read that! Thanks for your commitment 😄

qiwzhang commented 4 years ago

https://github.com/GoogleCloudPlatform/esp-v2/pull/176

agonper commented 4 years ago

GoogleCloudPlatform/esp-v2#176

After going through the PR, I can see that the bug wasn't easy to catch up. Glad you were able to fix the problem. Many thanks for the fast fix.

May I ask when it will be available at: gcr.io/endpoints-release/endpoints-runtime-serverless?

qiwzhang commented 4 years ago

I just released 2.11.0 with this fix:

qiwzhang commented 4 years ago

For ESPv1, we will not support grpc web test