|
1 | | -using System.Net.Quic; |
| 1 | +using System.Diagnostics; |
| 2 | +using System.Net.Quic; |
2 | 3 | using CHttpServer.Http3; |
3 | 4 | using Microsoft.AspNetCore.Http.Features; |
4 | 5 |
|
@@ -55,22 +56,24 @@ public async Task MultipleWrites_HeaderFrame() |
55 | 56 |
|
56 | 57 | TaskCompletionSource tcs = new(TaskCreationOptions.RunContinuationsAsynchronously); |
57 | 58 | sut.Initialize(null, await serverStreamTask); |
58 | | - var testApp = new TestBase.TestApplication(ctx => |
| 59 | + var testApp = new TestBase.TestApplication(async ctx => |
59 | 60 | { |
60 | 61 | Assert.Equal("/", ctx.Request.Path); |
61 | 62 | Assert.Equal("https", ctx.Request.Scheme); |
62 | 63 | Assert.Equal("localhost", ctx.Request.Host.ToString()); |
63 | 64 | Assert.Equal(HttpMethod.Get.ToString(), ctx.Request.Method); |
64 | | - tcs.SetResult(); |
65 | | - return Task.CompletedTask; |
| 65 | + |
| 66 | + // This callback shall not complete before the 2nd flush, otherwise the |
| 67 | + // server might close the stream before the flush succeeds. |
| 68 | + await tcs.Task; |
66 | 69 | }); |
67 | 70 | var processing = sut.ProcessStreamAsync(testApp, TestContext.Current.CancellationToken); |
68 | 71 |
|
69 | 72 | // Second Write |
70 | 73 | await clientStream.WriteAsync(headersFrame[i..], TestContext.Current.CancellationToken); |
71 | 74 | await clientStream.FlushAsync(TestContext.Current.CancellationToken); |
| 75 | + tcs.SetResult(); |
72 | 76 |
|
73 | | - await tcs.Task.WaitAsync(DefaultTimeout, TestContext.Current.CancellationToken); |
74 | 77 | clientStream.Close(); |
75 | 78 | await processing; |
76 | 79 | await quicConnection.DisposeAsync(); |
@@ -112,37 +115,38 @@ public async Task SingleWrite_HeaderFrame_ReservedFrame() |
112 | 115 | public async Task MultipleWrites_HeaderFrame_ReservedFrame() |
113 | 116 | { |
114 | 117 | byte[] data = [.. Http3FrameFixture.GetHeadersFrame(), .. Http3FrameFixture.GetReservedFrame(10)]; |
115 | | - var quicConnection = await QuicConnectionFixture.SetupConnectionAsync(Port, TestContext.Current.CancellationToken); |
| 118 | + await using var quicConnection = await QuicConnectionFixture.SetupConnectionAsync(Port, TestContext.Current.CancellationToken); |
116 | 119 | for (int i = 1; i < data.Length; i++) |
117 | 120 | { |
118 | 121 | var serverStreamTask = Task.Run(async () => await quicConnection.ServerConnection.AcceptInboundStreamAsync()); |
119 | 122 | var sut = new Http3Stream([]); |
120 | 123 |
|
121 | | - var clientStream = await quicConnection.ClientConnection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional, TestContext.Current.CancellationToken); |
| 124 | + await using var clientStream = await quicConnection.ClientConnection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional, TestContext.Current.CancellationToken); |
122 | 125 | await clientStream.WriteAsync(data.AsMemory(0, i), TestContext.Current.CancellationToken); |
123 | 126 | await clientStream.FlushAsync(TestContext.Current.CancellationToken); |
124 | 127 |
|
125 | | - TaskCompletionSource tcs = new(TaskCreationOptions.RunContinuationsAsynchronously); |
| 128 | + TaskCompletionSource secondFlushCompleted = new(TaskCreationOptions.RunContinuationsAsynchronously); |
126 | 129 | sut.Initialize(null, await serverStreamTask); |
127 | | - var testApp = new TestBase.TestApplication(ctx => |
| 130 | + var testApp = new TestBase.TestApplication(async ctx => |
128 | 131 | { |
129 | 132 | Assert.Equal("/", ctx.Request.Path); |
130 | 133 | Assert.Equal("https", ctx.Request.Scheme); |
131 | 134 | Assert.Equal("localhost", ctx.Request.Host.ToString()); |
132 | 135 | Assert.Equal(HttpMethod.Get.ToString(), ctx.Request.Method); |
133 | | - tcs.SetResult(); |
134 | | - return Task.CompletedTask; |
| 136 | + |
| 137 | + // This callback shall not complete before the 2nd flush, otherwise the |
| 138 | + // server might close the stream before the flush succeeds. |
| 139 | + await secondFlushCompleted.Task; |
135 | 140 | }); |
136 | 141 | var processing = sut.ProcessStreamAsync(testApp, TestContext.Current.CancellationToken); |
137 | 142 |
|
138 | 143 | await clientStream.WriteAsync(data.AsMemory(i), TestContext.Current.CancellationToken); |
139 | 144 | await clientStream.FlushAsync(TestContext.Current.CancellationToken); |
| 145 | + secondFlushCompleted.SetResult(); |
140 | 146 |
|
141 | | - await tcs.Task.WaitAsync(DefaultTimeout, TestContext.Current.CancellationToken); |
142 | | - clientStream.Close(); |
143 | 147 | await processing; |
| 148 | + clientStream.Close(); |
144 | 149 | } |
145 | | - await quicConnection.DisposeAsync(); |
146 | 150 | } |
147 | 151 |
|
148 | 152 | [Fact] |
|
0 commit comments