diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs index 5d0fb49db747aa..ff87d5a89f9432 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs @@ -425,7 +425,7 @@ private enum ParsingState : byte Done } - public override bool NeedsDrain => (_connection != null); + public override bool NeedsDrain => CanReadFromConnection; public override async ValueTask DrainAsync(int maxDrainBytes) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs index dd667f0706030d..786f285a93c75e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs @@ -190,7 +190,7 @@ private ReadOnlyMemory ReadFromConnectionBuffer(int maxBytesToRead) return connectionBuffer.Slice(0, bytesToConsume); } - public override bool NeedsDrain => (_connection != null); + public override bool NeedsDrain => CanReadFromConnection; public override async ValueTask DrainAsync(int maxDrainBytes) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs index 4daad8f2b0ec76..02ba78ab99ca93 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentReadStream.cs @@ -28,6 +28,17 @@ public HttpContentReadStream(HttpConnection connection) : base(connection) protected bool IsDisposed => _disposed == 1; + protected bool CanReadFromConnection + { + get + { + // _connection == null typically means that we have finished reading the response. + // Cancellation may lead to a state where a disposed _connection is not null. + HttpConnection? connection = _connection; + return connection != null && connection._disposed != Status_Disposed; + } + } + public virtual ValueTask DrainAsync(int maxDrainBytes) { Debug.Fail($"DrainAsync should not be called for this response stream: {GetType()}");