Closed isosphere closed 2 years ago
If I swap out tonic-web-wasm-client
for grpc-web-client
@ https://github.com/titanous/grpc-web-client.git the same code works without any other modifications, but it does require adjusting all tonic
related dependencies as it's just a prototype that is not actively maintained and was last updated about a year ago.
Regardless, grpc-web-client
isn't a huge project and we can probably ~steal~ learn the solution from there. It looks like it's leveraging tonic::Request
to parse this kind of data instead of rolling its own header parsing code from scratch, but it's also able to directly create such an object from the web_sys::Request
object.
It looks like we intend for httparse::parse_headers
to only get the trailers because of the use of body.split_to(len as usize).freeze()
@ this line but that does not appear to be working for a stream response, body
seems to remain unmodified despite this call. That might be the underlying problem; it's getting the entire data packet.
Perhaps len
is not being picked up correctly? Indeed, with my large data packet above the total length is reported as 7
. That would explain the behaviour and this bug. That's the length of an individual stream's frame; the same length you'd see in a client like Kreya for each individual message for this stream.
This is the full larger body
before we advance
by parsing any of it:
'b"\0\0\0\0\x07\x08\x01\x12\x03AUD\0\0\0\0\x07\x08\x02\x12\x03GBP\0\0\0\0\x07\x08\x03\x12\x03CAD\0\0\0\0\x07\x08\x04\x12\x03CNY\0\0\0\0\x07\x08\x05\x12\x03EUR\0\0\0\0\x07\x08\x06\x12\x03JPY\0\0\0\0\x07\x08\x07\x12\x03NZD\0\0\0\0\x07\x08\x08\x12\x03RUB\0\0\0\0\x07\x08\t\x12\x03USD\0\0\0\0\x07\x08\n\x12\x03AFN\0\0\0\0\x07\x08\x0b\x12\x03ALL\0\0\0\0\x07\x08\x0c\x12\x03DZD\0\0\0\0\x07\x08\r\x12\x03AOA\0\0\0\0\x07\x08\x0e\x12\x03ARS\0\0\0\0\x07\x08\x0f\x12\x03AMD\0\0\0\0\x07\x08\x10\x12\x03AWG\0\0\0\0\x07\x08\x11\x12\x03AZN\0\0\0\0\x07\x08\x12\x12\x03BSD\0\0\0\0\x07\x08\x13\x12\x03BHD\0\0\0\0\x07\x08\x14\x12\x03BDT\0\0\0\0\x07\x08\x15\x12\x03BBD\0\0\0\0\x07\x08\x16\x12\x03BYN\0\0\0\0\x07\x08\x17\x12\x03BZD\0\0\0\0\x07\x08\x18\x12\x03BMD\0\0\0\0\x07\x08\x19\x12\x03BTN\0\0\0\0\x07\x08\x1a\x12\x03BOB\0\0\0\0\x07\x08\x1b\x12\x03BAM\0\0\0\0\x07\x08\x1c\x12\x03BWP\0\0\0\0\x07\x08\x1d\x12\x03BRL\0\0\0\0\x07\x08\x1e\x12\x03BND\0\0\0\0\x07\x08\x1f\x12\x03BGN\0\0\0\0\x07\x08 \x12\x03MMK\0\0\0\0\x07\x08!\x12\x03BIF\0\0\0\0\x07\x08\"\x12\x03KHR\0\0\0\0\x07\x08#\x12\x03CVE\0\0\0\0\x07\x08$\x12\x03KYD\0\0\0\0\x07\x08%\x12\x03XAF\0\0\0\0\x07\x08&\x12\x03XPF\0\0\0\0\x07\x08'\x12\x03CLP\0\0\0\0\x07\x08(\x12\x03COP\0\0\0\0\x07\x08)\x12\x03KMF\0\0\0\0\x07\x08*\x12\x03CDF\0\0\0\0\x07\x08+\x12\x03CRC\0\0\0\0\x07\x08,\x12\x03HRK\0\0\0\0\x07\x08-\x12\x03CUC\0\0\0\0\x07\x08.\x12\x03CUP\0\0\0\0\x07\x08/\x12\x03CZK\0\0\0\0\x07\x080\x12\x03DKK\0\0\0\0\x07\x081\x12\x03DJF\0\0\0\0\x07\x082\x12\x03DOP\0\0\0\0\x07\x083\x12\x03XCD\0\0\0\0\x07\x084\x12\x03EGP\0\0\0\0\x07\x085\x12\x03ERN\0\0\0\0\x07\x086\x12\x03ETB\0\0\0\0\x07\x087\x12\x03FKP\0\0\0\0\x07\x088\x12\x03FJD\0\0\0\0\x07\x089\x12\x03GMD\0\0\0\0\x07\x08:\x12\x03GEL\0\0\0\0\x07\x08;\x12\x03GHS\0\0\0\0\x07\x08<\x12\x03GIP\0\0\0\0\x07\x08=\x12\x03GTQ\0\0\0\0\x07\x08>\x12\x03GNF\0\0\0\0\x07\x08?\x12\x03GYD\0\0\0\0\x07\x08@\x12\x03HTG\0\0\0\0\x07\x08A\x12\x03HNL\0\0\0\0\x07\x08B\x12\x03HKD\0\0\0\0\x07\x08C\x12\x03HUF\0\0\0\0\x07\x08D\x12\x03ISK\0\0\0\0\x07\x08E\x12\x03INR\0\0\0\0\x07\x08F\x12\x03IDR\0\0\0\0\x07\x08G\x12\x03IRR\0\0\0\0\x07\x08H\x12\x03IQD\0\0\0\0\x07\x08I\x12\x03ILS\0\0\0\0\x07\x08J\x12\x03JMD\0\0\0\0\x07\x08K\x12\x03JOD\0\0\0\0\x07\x08L\x12\x03KZT\0\0\0\0\x07\x08M\x12\x03KES\0\0\0\0\x07\x08N\x12\x03KWD\0\0\0\0\x07\x08O\x12\x03KGS\0\0\0\0\x07\x08P\x12\x03LAK\0\0\0\0\x07\x08Q\x12\x03LBP\0\0\0\0\x07\x08R\x12\x03LSL\0\0\0\0\x07\x08S\x12\x03LRD\0\0\0\0\x07\x08T\x12\x03LYD\0\0\0\0\x07\x08U\x12\x03MOP\0\0\0\0\x07\x08V\x12\x03MKD\0\0\0\0\x07\x08W\x12\x03MGA\0\0\0\0\x07\x08X\x12\x03MWK\0\0\0\0\x07\x08Y\x12\x03MYR\0\0\0\0\x07\x08Z\x12\x03MVR\0\0\0\0\x07\x08[\x12\x03MRU\0\0\0\0\x07\x08\\\x12\x03MUR\0\0\0\0\x07\x08]\x12\x03MXN\0\0\0\0\x07\x08^\x12\x03MDL\0\0\0\0\x07\x08_\x12\x03MNT\0\0\0\0\x07\x08`\x12\x03MAD\0\0\0\0\x07\x08a\x12\x03MZN\0\0\0\0\x07\x08b\x12\x03NAD\0\0\0\0\x07\x08c\x12\x03NPR\0\0\0\0\x07\x08d\x12\x03ANG\0\0\0\0\x07\x08e\x12\x03TWD\0\0\0\0\x07\x08f\x12\x03NIO\0\0\0\0\x07\x08g\x12\x03NGN\0\0\0\0\x07\x08h\x12\x03KPW\0\0\0\0\x07\x08i\x12\x03NOK\0\0\0\0\x07\x08j\x12\x03OMR\0\0\0\0\x07\x08k\x12\x03PKR\0\0\0\0\x07\x08l\x12\x03PAB\0\0\0\0\x07\x08m\x12\x03PGK\0\0\0\0\x07\x08n\x12\x03PYG\0\0\0\0\x07\x08o\x12\x03PEN\0\0\0\0\x07\x08p\x12\x03PHP\0\0\0\0\x07\x08q\x12\x03PLN\0\0\0\0\x07\x08r\x12\x03QAR\0\0\0\0\x07\x08s\x12\x03RON\0\0\0\0\x07\x08t\x12\x03RWF\0\0\0\0\x07\x08u\x12\x03SHP\0\0\0\0\x07\x08v\x12\x03WST\0\0\0\0\x07\x08w\x12\x03STN\0\0\0\0\x07\x08x\x12\x03SAR\0\0\0\0\x07\x08y\x12\x03RSD\0\0\0\0\x07\x08z\x12\x03SCR\0\0\0\0\x07\x08{\x12\x03SLL\0\0\0\0\x07\x08|\x12\x03SGD\0\0\0\0\x07\x08}\x12\x03SBD\0\0\0\0\x07\x08~\x12\x03SOS\0\0\0\0\x07\x08\x7f\x12\x03ZAR\0\0\0\0\x08\x08\x80\x01\x12\x03KRW\0\0\0\0\x08\x08\x81\x01\x12\x03SSP\0\0\0\0\x08\x08\x82\x01\x12\x03LKR\0\0\0\0\x08\x08\x83\x01\x12\x03SDG\0\0\0\0\x08\x08\x84\x01\x12\x03SRD\0\0\0\0\x08\x08\x85\x01\x12\x03SZL\0\0\0\0\x08\x08\x86\x01\x12\x03SEK\0\0\0\0\x08\x08\x87\x01\x12\x03CHF\0\0\0\0\x08\x08\x88\x01\x12\x03SYP\0\0\0\0\x08\x08\x89\x01\x12\x03TJS\0\0\0\0\x08\x08\x8a\x01\x12\x03TZS\0\0\0\0\x08\x08\x8b\x01\x12\x03THB\0\0\0\0\x08\x08\x8c\x01\x12\x03TOP\0\0\0\0\x08\x08\x8d\x01\x12\x03TTD\0\0\0\0\x08\x08\x8e\x01\x12\x03TND\0\0\0\0\x08\x08\x8f\x01\x12\x03TRY\0\0\0\0\x08\x08\x90\x01\x12\x03TMT\0\0\0\0\x08\x08\x91\x01\x12\x03UGX\0\0\0\0\x08\x08\x92\x01\x12\x03UAH\0\0\0\0\x08\x08\x93\x01\x12\x03AED\0\0\0\0\x08\x08\x94\x01\x12\x03UYU\0\0\0\0\x08\x08\x95\x01\x12\x03UZS\0\0\0\0\x08\x08\x96\x01\x12\x03VUV\0\0\0\0\x08\x08\x97\x01\x12\x03VED\0\0\0\0\x08\x08\x98\x01\x12\x03VES\0\0\0\0\x08\x08\x99\x01\x12\x03VND\0\0\0\0\x08\x08\x9a\x01\x12\x03XOF\0\0\0\0\x08\x08\x9b\x01\x12\x03YER\0\0\0\0\x08\x08\x9c\x01\x12\x03ZMW\x80\0\0\0\x0fgrpc-status:0\r\n\n"',
It does not appear to be pre-pended with a length; the 64bit integers take up 8 bytes which leaves only a single byte before the data, a 0x00 null byte (possibly indicating no compression). Either body
arrives incomplete into this function for streams, or streams need to be handled differently.
Hi. Thanks, for creating this issue. Can you give me some sample code for your server so that I can generate same response as you're generating to reproduce this?
I've published a new release on crates.io. Can you verify if it works?
I've published a new release on crates.io. Can you verify if it works?
Yup, I can confirm it works! Thank you, that was quick!
Proto in use:
This is the value of
body
for a successful non-streamResponse
at this line, for a type defined likemessage Response{}
:The value of the parsed header for the above
body
is[Header { name: "grpc-status", value: "0" }]
Here's a stream
Response
which triggersClientError::HeaderParsingError
(as would be see byhttparse::parse_headers
):which is a bunch of int64's followed by some string labels, as it should be.
I've made a separate client using only
tonic
and it parses the above without complaint. The GUI GRPC client "Kreya" is also happy with the response body above.