From: Tomas Weinfurt Date: Thu, 5 Aug 2021 18:23:17 +0000 (-0700) Subject: fix h/3 ResponseContent with large buffer (#56892) X-Git-Tag: accepted/tizen/unified/20220110.054933~616 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f61d5c83f952a58c9e1cf2423ce4f6d9363ee97b;p=platform%2Fupstream%2Fdotnet%2Fruntime.git fix h/3 ResponseContent with large buffer (#56892) --- diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs index 45b7447..8ec6cdb 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs @@ -1028,6 +1028,11 @@ namespace System.Net.Http totalBytesRead += bytesRead; _responseDataPayloadRemaining -= bytesRead; buffer = buffer.Slice(bytesRead); + + if (_responseDataPayloadRemaining == 0) + { + break; + } } } @@ -1085,6 +1090,11 @@ namespace System.Net.Http totalBytesRead += bytesRead; _responseDataPayloadRemaining -= bytesRead; buffer = buffer.Slice(bytesRead); + + if (_responseDataPayloadRemaining == 0) + { + break; + } } } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index aced777..4132bce 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; +using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; @@ -801,5 +802,59 @@ namespace System.Net.Quic.Tests await Assert.ThrowsAsync(() => serverStream.ReadAsync(buffer).AsTask()); }).WaitAsync(TimeSpan.FromMilliseconds(PassingTestTimeoutMilliseconds)); } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task BigWrite_SmallRead_Success(bool closeWithData) + { + const int size = 100; + (QuicConnection clientConnection, QuicConnection serverConnection) = await CreateConnectedQuicConnection(); + using (clientConnection) + using (serverConnection) + { + byte[] buffer = new byte[1] { 42 }; + + QuicStream clientStream = clientConnection.OpenBidirectionalStream(); + Task t = serverConnection.AcceptStreamAsync().AsTask(); + await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientStream.WriteAsync(buffer).AsTask(), t, PassingTestTimeoutMilliseconds); + QuicStream serverStream = t.Result; + Assert.Equal(1, await serverStream.ReadAsync(buffer)); + + // streams are new established and in good shape. + using (clientStream) + using (serverStream) + { + byte[] expected = RandomNumberGenerator.GetBytes(size); + byte[] actual = new byte[size]; + + // should be small enough to fit. + await serverStream.WriteAsync(expected, closeWithData); + + // Add delay to have chance to receive the 100b block before ReadAsync starts. + await Task.Delay(10); + int remaining = size; + int readLength; + while (remaining > 0) + { + readLength = await clientStream.ReadAsync(new Memory(actual, size - remaining, 1)); + Assert.Equal(1, readLength); + remaining--; + } + + Assert.Equal(expected, actual); + + if (!closeWithData) + { + serverStream.Shutdown(); + } + + readLength = await clientStream.ReadAsync(actual); + Assert.Equal(0, readLength); + + Assert.Equal(expected, actual); + } + } + } } }