tonic_web_wasm_client not sending content-type header for gRPC web requests

136 Views Asked by At

I have a gRPC GO server that I am trying to connect to using a Rust WASM client. The proto file looks like this:

syntax = "proto3";

package pb;

message SubscribeRequest {
  string id = 1;
}
message Response {
  string transcript = 1;
}

service CallCenter {
  rpc SubscribeCall(SubscribeRequest) returns (stream Response) {}
}

Since rust WASM doesn't support gRPC I am having to use gRPC web with the tonic_web_wasm_client crate. First I create the gRPC web proxy server on my GO server like this:

wrappedGrpc := grpcweb.WrapServer(grpcServer)
handler := func(resp http.ResponseWriter, req *http.Request) {
    if wrappedGrpc.IsGrpcWebRequest(req) {
        wrappedGrpc.ServeHTTP(resp, req)
    } else {
        log.Println("Received non-gRPC-Web request")
    }
}
go func() {
    port := "8082"
    log.Println("Starting gRPC-Web proxy server on port", port)
    log.Fatal(http.ListenAndServe(":"+port, http.HandlerFunc(handler)))
}()

Then in wasm I call the server like this:

pub async fn test_stream(&self) -> wasm_streams::readable::sys::ReadableStream {
        let mut c = Client::new("http://0.0.0.0:8082".to_string());
        let options = FetchOptions::new();
        let options = options.mode(tonic_web_wasm_client::options::Mode::NoCors);
        c.with_options(options);
        let mut client = pb::call_center_client::CallCenterClient::new(c);

        let result = client
            .subscribe_call(tonic::Request::new(
                pb::SubscribeRequest {
                    id: "test_id".to_string(),
                },
            ))
            .await;
        if result.is_err() {
            console_log!("error: {:?}", result);
        }
        let stream = result
            .unwrap()
            .into_inner()
            .map(|x| Ok(JsValue::from_str(&x.unwrap().transcript)));
        ReadableStream::from_stream(stream).into_raw()
    }

I had to add the NoCors part because otherwise the calls were getting blocked. Now the problem I am having is the GO gRPC web proxy server is getting the calls, but it is thinking they are not gRPC requests because they are missing the content-type header. I don't understand how they don't have this though because looking through the tonic_web_wasm_client code it definitely adds the header. But looking at the calls coming from the web browser the requests definitely don't have the header. Then I am getting an error on the wasm side of:

error: Err(Status { code: Unknown, message: "missing content-type header in grpc response", source: Some(MissingContentTypeHeader) })

I'm guessing this is because the server isn't including the header because it doesn't think the request is gRPC web. I don't understand why this is happening. Any help would be appreciated!

0

There are 0 best solutions below