tower-rs/tower-grpc

Response stream errors out with grpc-status header missing

mzabaluev opened this issue · 1 comments

Upon receiving a healthy looking response stream from a tower-grpc+tower-hyper server, the stream items are yielded, but then the response stream reports an error: Status { code: Unknown, message: "grpc-status header missing, mapped from HTTP status code 200" }.

Packet sent by the client with request headers:

HyperText Transfer Protocol 2
    Stream: HEADERS, Stream ID: 9, Length 30, POST /iohk.chain.node.Node/GetBlocks
        Length: 30
        Type: HEADERS (1)
        Flags: 0x04
        0... .... .... .... .... .... .... .... = Reserved: 0x0
        .000 0000 0000 0000 0000 0000 0000 1001 = Stream Identifier: 9
        [Pad Length: 0]
        Header Block Fragment: 8386c1049760c79faae49c66a97a8f2157d2790ac622a6ed…
        [Header Length: 175]
        [Header Count: 6]
        Header: :method: POST
        Header: :scheme: http
        Header: :authority: 127.0.0.1:12001
        Header: :path: /iohk.chain.node.Node/GetBlocks
        Header: te: trailers
        Header: content-type: application/grpc+proto

Followed by request body:

HyperText Transfer Protocol 2
    Stream: DATA, Stream ID: 9, Length 39 (partial entity body)
        Length: 39
        Type: DATA (0)
        Flags: 0x00
        0... .... .... .... .... .... .... .... = Reserved: 0x0
        .000 0000 0000 0000 0000 0000 0000 1001 = Stream Identifier: 9
        [Pad Length: 0]
        Reassembled body in frame: 435
        Data: 00000000220a20302958eb0e18ff5924688550a53654878d…
    Stream: DATA, Stream ID: 9, Length 0
        Length: 0
        Type: DATA (0)
        Flags: 0x01
        0... .... .... .... .... .... .... .... = Reserved: 0x0
        .000 0000 0000 0000 0000 0000 0000 1001 = Stream Identifier: 9
        [Pad Length: 0]
        [1 Body fragment (39 bytes): #435(39)]
        Data: 00000000220a20302958eb0e18ff5924688550a53654878d…
    GRPC Message: /iohk.chain.node.Node/GetBlocks, Request
        Compressed Flag: Not Compressed (0)
        Message Length: 34
        Message Data: 34 bytes
    Protocol Buffers: application/grpc+proto,/iohk.chain.node.Node/GetBlocks,request
        Field[1]
            .000 1... = Field Number: 1
            .... .010 = Wire Type: Length-delimited (2)
            Value Length: 32
            Value: 302958eb0e18ff5924688550a53654878d3ce8e6d31f7a81…

The server starts its response with the headers:

HyperText Transfer Protocol 2
    Stream: HEADERS, Stream ID: 9, Length 26, 200 OK
        Length: 26
        Type: HEADERS (1)
        Flags: 0x04
        0... .... .... .... .... .... .... .... = Reserved: 0x0
        .000 0000 0000 0000 0000 0000 0000 1001 = Stream Identifier: 9
        [Pad Length: 0]
        Header Block Fragment: 88c16196c361be94038a6e2d6a08017d403b71a15c03aa62…
        [Header Length: 101]
        [Header Count: 3]
        Header: :status: 200 OK
        Header: content-type: application/grpc+proto
        Header: date: Fri, 06 Sep 2019 07:42:07 GMT

Followed by the stream items:

HyperText Transfer Protocol 2
    Stream: DATA, Stream ID: 9, Length 704 (partial entity body)
        Length: 704
        Type: DATA (0)
        Flags: 0x00
        0... .... .... .... .... .... .... .... = Reserved: 0x0
        .000 0000 0000 0000 0000 0000 0000 1001 = Stream Identifier: 9
        [Pad Length: 0]
        Reassembled body in frame: 439
        Data: 00000002bb0ab80502b60002000000000000048a00000001…

Followed by trailers including grpc-status:

HyperText Transfer Protocol 2
    Stream: HEADERS, Stream ID: 9, Length 1
        Length: 1
        Type: HEADERS (1)
        Flags: 0x05
        0... .... .... .... .... .... .... .... = Reserved: 0x0
        .000 0000 0000 0000 0000 0000 0000 1001 = Stream Identifier: 9
        [1 Body fragment (704 bytes): #438(704)]
        Data: 00000002bb0ab80502b60002000000000000048a00000001…
        [Pad Length: 0]
        Header Block Fragment: c0
        [Header Length: 20]
        [Header Count: 1]
        Header: grpc-status: 0
    GRPC Message: /iohk.chain.node.Node/GetBlocks, Response
        Compressed Flag: Not Compressed (0)
        Message Length: 699
        Message Data: 699 bytes
    Protocol Buffers: application/grpc+proto,/iohk.chain.node.Node/GetBlocks,response
        Field[1]
            .000 1... = Field Number: 1
            .... .010 = Wire Type: Length-delimited (2)
            Value Length: 696
            Value: 02b60002000000000000048a00000001000000040e5751c0…

I've tracked the problem down to the application's use of .forward() on the result stream, which triggers a bug in futures: rust-lang/futures-rs#1864