runtime: SslStream.WriteAsync hangs after updating to CoreFx 4.4
We’ve recently updated package references in Kestrel to CoreFx 4.4 https://github.com/aspnet/KestrelHttpServer/commit/5b8f7c2b2be5744edac8ce3c5a2dea86ed65b8ee.
After this update, Kestrel can’t serve HTTPS anymore. We have a stream that wraps an SslStream, and it’s hanging when writing here:
Reproing is straightforward: just run the Kestrel sample app (under samples/SampleApp in the repo) and hit it with any client, and you will see the hang.
This only happens on .NET Core. Desktop .NET works fine.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 40 (30 by maintainers)
.NET Full Framework 1.1+ had async methods
Stream.BeginWrite/Stream.EndWriteandStream.BeginRead/Stream.EndReadon the base class. This approach to async was depreciated whenTasks became a thing and the new Task based methodsStream.WriteAsyncandStream.ReadAsyncbecame the preferred method of doing async.The base classes implementation of
BeginX/EndXare sync methods to support Streams that don’t actually have async methods. A lot of the conversions for the historic Streams newerXXXAsyncmethods have wrapped theseBeginX/EndXmethods to achieve the newer async paths; using helpers that do the conversion.As these methods were deprecated they were not brought to .NET Core. To reuse the same code that expected
BeginX/EndXwithout doing lots of rewriting to directly implementWriteAsync/ReadAsync; which would be additional replumbing and testing to end up with the same result (although it would be cleaner); extension methods were created to behave as theBeginX/EndXmethods. So all was fine…However, as part of returning the apis for .NET Standard 2.0; this has meant the base class implementations for
BeginX/EndXhave reappeared. The virtual base class methods take precedence over extension methods; so the behaviour has moved back to sync-blocking on the async methods; rather than actually being async.Hence this issue has arisen… 😢
The fastest way to fix it is likely to copy paste the extension methods code into SslStream/NetworkStream etc. The best way to fix it would be to actually implement the
WriteAsync/ReadAsyncmethods - though likely that would also be more risky.