hyperium / tonic

A native gRPC client & server implementation with async/await support.
https://docs.rs/tonic
MIT License
10.02k stars 1.02k forks source link

tonic report invalid flag err but it's not #1029

Closed TENX-S closed 2 years ago

TENX-S commented 2 years ago

env: tonic v0.7.2 tonic-build v0.7.2

macOS 12.4

Hi, I'm trying to make a tool like bloomRPC. And I prefer to implement the core API with rust. Here is my attempt. Start the server first, then the client. And I get:

request: {"name": "World"}
reply: {"message": "Hello World!"}
Err(
    Status {
        code: Internal,
        message: "protocol error: received message with invalid compression flag: 10 (valid flags are 0 and 1) while receiving response with status: 200 OK",
        source: None,
    },
)

This error is confusing. I use Wireshark to get the packet and the compression flag is not corrupted:

WeChatb9a6711a0a68355539af8edde50c453d
LucioFranco commented 2 years ago

So this error usually happens when the incoming frames don't match what hyper expects. This could be due to you sending h1 when it really expects h2. If you're using the transport feature and Server by default it will have http2_only on by default. This could be the cause of the failure of reading the frame.

TENX-S commented 2 years ago

Sorry, I didn't get it. I guess there is no h1 come into my code?

TENX-S commented 2 years ago

I've been debugging it for a while. It seems like the Err is returned here:

https://github.com/hyperium/tonic/blob/9ea03c2c44ad6bf76e4141e6fb40870b9b30ab63/tonic/src/codec/decode.rs#L173

it will jump to:

https://github.com/hyperium/tonic/blob/9ea03c2c44ad6bf76e4141e6fb40870b9b30ab63/tonic/src/codec/decode.rs#L143

then: https://github.com/hyperium/tonic/blob/9ea03c2c44ad6bf76e4141e6fb40870b9b30ab63/tonic/src/codec/decode.rs#L290

and we got the "invalid compression flag" here:

https://github.com/tokio-rs/bytes/blob/28a1eab1e0531a0e7b9624e474a8c06dfd5c8072/src/buf/buf_impl.rs#L289

image

It seems like the error arises when tonic try to fetch the trailers and clear the body. But it's not the correct body?

TENX-S commented 2 years ago

I've captured the packet by using the default client and server. And found that the packet is exactly the same as the previous one, except the date of header. So, I guess there's a problem with my decoder?

TENX-S commented 2 years ago

I made it, but I don't know why: just change my decoder to:

fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
        let buf = src.chunk();
        let length = buf.len();
        let resp = get_hello_response(buf);
        src.advance(length);
        Ok(Some(resp))
}

and it works!