runtime: HTTP2: Canceling token given to HttpClient.SendAsync does not send RST_STREAM
Found by a customer: https://twitter.com/stevejgordon/status/1169995743568048129
This is a high impact bug. A user will cancel a streaming gRPC call on the client, but the server will never be notified. If the server is checking CancellationToken.IsCancellationRequested
then it will hang open forever.
This is a regression of https://github.com/dotnet/corefx/issues/38391
Related: https://github.com/dotnet/corefx/issues/39049
Repro:
git clone https://github.com/JamesNK/grpc-dotnet.git
git checkout jamesnk/duplex-cancellation-regression
dotnet test test\FunctionalTests --filter Name~ServerStreaming_CancellationOnClient_SentToServer
Logic in the test is something like:
- Client makes a server streaming call to the server. This means the client is sending one message in the request’s HttpContent, which then completes.
- Server streams multiple messages to the client
- Client triggers the cancellation token given to gRPC client. HttpClient.SendAsync token is canceled
- The HttpClient should be sending RST_STREAM to the server, and the server should report the call is canceled. This isn’t happening so the server will stream messages forever.
Wireshark log: cancellation-regression.zip
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 20 (20 by maintainers)
Confirmed disposing HttpResponseMessage works and no other gRPC unit tests regressed.
To echo what @stephentoub said: how is this different from existing tests we have, either for GRPC or HttpClient? We know that cancellation does send RST_STREAM for the tests we have, so what’s special about this?
The repo in the original issue should re-create it. However it won’t compile against the latest .NET Core SDK because of breaking changes.
I’m writing a new regression test now.