timostamm / protobuf-ts

Protobuf and RPC for TypeScript
Apache License 2.0
1.1k stars 129 forks source link

Compression with gRPC-Web: ERROR RpcError: premature EOF #655

Closed ma54ik closed 4 months ago

ma54ik commented 4 months ago

Hi, I'm trying to use the compressed response from a gRPC-server in a Angular Frontend (TS).

The use case with uncompressed messages is working fine. If I'm adding the header grpc-accept-encoding: br to the request via

rpcOptions: RpcOptions = {
    meta: {
      'Grpc-Accept-Encoding': 'br'
    }
    // interceptors: [
    //   {
    //     // adds compression header to unary requests
    //     interceptUnary(next, method, input, options: RpcOptions): UnaryCall {
    //       if (!options.meta) {
    //         options.meta = {};
    //       }
    //       options.meta['grpc-accept-encoding'] = 'br';
    //       return next(method, input, options);
    //     }
    //   }
    // ],
  }

(I tried both ways adding the header in rpcOptions) the server responds with a compressed message (Grpc-Encoding: br) as expected, but the application throws the error ERROR RpcError: premature EOF and I'm unable to use the response. The client stubs are generated with the protoc-tool as described in the manual, the server is written in C# and the request is listed blow.

  transport = new GrpcWebFetchTransport({
    baseUrl: "http://localhost:5263",
    format: "binary"
  });

  async greetingBr() {
    let client = new GreeterClient(this.transport);

    let request: HelloRequest = { name: "compressed gRPC-Web-message" };

    let { response } = await client.sayHello(request, this.rpcOptions);

    console.log(response);
  }

I've seen the issue #332 which seems to provide the answer to the same question in gRPC and I'm aware of the browser limitations mentioned in the spec. The issues grpc/grpc-dotnet/issues/1141, grpc/grpc-web/issues/1000 and grpc/grpc-web/issues/561 unfortunately do not provide any final solution to this problem.

Question: Is there a way to use compression with gRPC-Web with protobuf-ts (or any other package)?

timostamm commented 4 months ago

Per-message compression is not supported by the client. You can use full-body compression (standard Accept-Encoding and Content-Encoding fields). You need good control over chunking for server-streaming RPCs through your infra.