`transport/Stream.RecvCompress` returns what the header contains, if present,
or empty string if a context error occurs. However, it "prefers" the header
data even if there is a context error, to prevent a related race. What happens
here is:
1. RPC starts.
2. Client cancels RPC.
3. `RecvCompress` tells `ClientStream.Recv` that compression used is "" because
of the context error. `as.decomp` is left nil, because there is no
compressor to look up in the registry.
4. Server's header and first message hit client.
5. Client sees the header and message and allows grpc's stream to see them.
(We only provide context errors if we need to block.)
6. Client performs a successful `Read` on the stream, receiving the gzipped
payload, then checks `as.decomp`.
7. We have no decompressor but the payload has a bit set indicating the message
is compressed, so this is an error. However, when forming the error string,
`RecvCompress` now returns "gzip" because it doesn't need to block to get
this from the now-received header. This leads to the confusing message
about how "gzip" is not installed even though it is.
This change makes `waitOnHeader` close the stream when context cancellation happens.
Then `RecvCompress` uses whatever value is present in the stream at that time, which
can no longer change because the stream is closed. Also, this will be in sync with
the messages on the stream - if there are any messages present, the headers must
have been processed first, and `RecvCompress` will contain the proper value.
* Closes the client transport stream, if context is cancelled while recvBuffer is reading.
* Passes a function pointer to recvBufferReader, instead of a Stream and an http2Client.
* Adds more descriptive error messages.
* If waitOnHeader notices the context cancelation, shouldRetry no longer returns a ContextError. Instead, it returns the error from the last try.
* Makes sure that test gets both statuses at least 5 times.
* Makse cntPermDenied a lambda function.