improbable-eng / grpc-web

gRPC Web implementation for Golang and TypeScript
Apache License 2.0
4.39k stars 436 forks source link

grpcwebproxy: 400 bad request on websocket connection attempts #1180

Open nikoprotic opened 8 months ago

nikoprotic commented 8 months ago

Versions of relevant software used 0.15.0

What happened I have a simple ping-pong bidi stream RPC:

message req {
  string message = 1;
}

message res {
  string message = 1;
}

service TestService {
  rpc TestStream(stream req) returns (stream res);
}

I auto-generate typescript client code and implement a client as described in the test files:

export const testStreamClient: grpc.Client<TestStreamRequest, TestStreamResponse> = grpc.client(
  TestService.TestStream,
  {
    host: "http://localhost:6457",
    transport: grpc.WebsocketTransport(),
    debug: true,
  }
);

My server is a vanilla gRPC server written in C++, so I have spun up a docker-compose file with my server in one container, and the grpcwebproxy in another (I am exposing the relevant ports). I run the proxy with the following command:

command: [
  "grpcwebproxy",
  "--server_http_tls_port=6457",
  "--server_http_debug_port=6458",
  "--use_websockets",
  # "--websocket_compression_mode=disabled",
  "--backend_tls=false",
  # "--run_tls_server=false",
  "--allow_all_origins",
  "--backend_addr=service:6456",
  "--server_tls_cert_file=/misc/cad_service_web_proxy_certificate.pem",
  "--server_tls_key_file=/misc/cad_service_web_proxy_private.key",
  "--backend_tls_noverify",
  "--enable_request_debug=true",
  # "--enable_health_check_service=true",
  # "--enable_health_endpoint=true",
]

(as you can see I've tried a few different things at this point).

With both my client and with postman, attempts to open websocket connections to ws://localhost:6457 simply return "400 bad request". Furthermore, attempts to POST to the debug server with http://localhost:6458/debug/events and http://localhost:6458/debug/requests returns 'not allowed'. For what it's worth, GET to /metrics works but returns a massive dump of data that is hard to decipher by hand.

What you expected to happen

I expect websocket connections to open and stay open. I expect to receive data from the debug endpoints.

How to reproduce it (as minimally and precisely as possible):

See above.

Full logs to relevant components

Anything else we need to know

alex-hadrian commented 7 months ago

The answer here was to switch to TLS. wss://localhost:6457 and https://localhost:6457/... both work as intended. Separately, The metrics endpoint returns good prometheus metrics, but the requests/events pages don't load anything.