Skip to content

Commit a57a80f

Browse files
authored
Fix ContentLengthReadAsyncSingleBytesAtATime (#23641)
1 parent a7ab15a commit a57a80f

File tree

1 file changed

+31
-6
lines changed

1 file changed

+31
-6
lines changed

src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,27 +1048,52 @@ await connection.ReceiveEnd(
10481048
}
10491049

10501050
[Fact]
1051-
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/23628")]
10521051
public async Task ContentLengthReadAsyncSingleBytesAtATime()
10531052
{
10541053
var testContext = new TestServiceContext(LoggerFactory);
1055-
var tcs = new TaskCompletionSource();
1056-
var tcs2 = new TaskCompletionSource();
1054+
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
1055+
var tcs2 = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
1056+
1057+
static async Task<ReadResult> ReadAtLeastAsync(PipeReader reader, int numBytes)
1058+
{
1059+
var result = await reader.ReadAsync();
1060+
1061+
while (!result.IsCompleted && result.Buffer.Length < numBytes)
1062+
{
1063+
reader.AdvanceTo(result.Buffer.Start, result.Buffer.End);
1064+
result = await reader.ReadAsync();
1065+
}
1066+
1067+
if (result.Buffer.Length < numBytes)
1068+
{
1069+
throw new IOException("Unexpected end of content.");
1070+
}
1071+
1072+
return result;
1073+
}
1074+
10571075
await using (var server = new TestServer(async httpContext =>
10581076
{
1059-
var readResult = await httpContext.Request.BodyReader.ReadAsync();
1077+
// Buffer 3 bytes.
1078+
var readResult = await ReadAtLeastAsync(httpContext.Request.BodyReader, numBytes: 3);
10601079
Assert.Equal(3, readResult.Buffer.Length);
10611080
tcs.SetResult();
10621081

10631082
httpContext.Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
10641083

1084+
// Buffer 1 more byte.
10651085
readResult = await httpContext.Request.BodyReader.ReadAsync();
10661086
httpContext.Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
10671087
tcs2.SetResult();
10681088

1089+
// Buffer 1 last byte.
10691090
readResult = await httpContext.Request.BodyReader.ReadAsync();
10701091
Assert.Equal(5, readResult.Buffer.Length);
10711092

1093+
// Do one more read to ensure completion is always observed.
1094+
httpContext.Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
1095+
readResult = await httpContext.Request.BodyReader.ReadAsync();
1096+
Assert.True(readResult.IsCompleted);
10721097
}, testContext))
10731098
{
10741099
using (var connection = server.CreateConnection())
@@ -1766,7 +1791,7 @@ await connection.Send(
17661791
[Fact]
17671792
public async Task ContentLengthRequestCallCancelPendingReadWorks()
17681793
{
1769-
var tcs = new TaskCompletionSource();
1794+
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
17701795
var testContext = new TestServiceContext(LoggerFactory);
17711796

17721797
await using (var server = new TestServer(async httpContext =>
@@ -1863,7 +1888,7 @@ public async Task ContentLengthRequestCallCompleteDoesNotCauseException()
18631888
{
18641889
var testContext = new TestServiceContext(LoggerFactory);
18651890

1866-
var tcs = new TaskCompletionSource();
1891+
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
18671892
await using (var server = new TestServer(async httpContext =>
18681893
{
18691894
var request = httpContext.Request;

0 commit comments

Comments
 (0)