|
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 |
|
@@ -112,37 +113,38 @@ public async Task SingleWrite_HeaderFrame_ReservedFrame() |
112 | 113 | public async Task MultipleWrites_HeaderFrame_ReservedFrame() |
113 | 114 | { |
114 | 115 | byte[] data = [.. Http3FrameFixture.GetHeadersFrame(), .. Http3FrameFixture.GetReservedFrame(10)]; |
115 | | - var quicConnection = await QuicConnectionFixture.SetupConnectionAsync(Port, TestContext.Current.CancellationToken); |
| 116 | + await using var quicConnection = await QuicConnectionFixture.SetupConnectionAsync(Port, TestContext.Current.CancellationToken); |
116 | 117 | for (int i = 1; i < data.Length; i++) |
117 | 118 | { |
118 | 119 | var serverStreamTask = Task.Run(async () => await quicConnection.ServerConnection.AcceptInboundStreamAsync()); |
119 | 120 | var sut = new Http3Stream([]); |
120 | 121 |
|
121 | | - var clientStream = await quicConnection.ClientConnection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional, TestContext.Current.CancellationToken); |
| 122 | + await using var clientStream = await quicConnection.ClientConnection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional, TestContext.Current.CancellationToken); |
122 | 123 | await clientStream.WriteAsync(data.AsMemory(0, i), TestContext.Current.CancellationToken); |
123 | 124 | await clientStream.FlushAsync(TestContext.Current.CancellationToken); |
124 | 125 |
|
125 | | - TaskCompletionSource tcs = new(TaskCreationOptions.RunContinuationsAsynchronously); |
| 126 | + TaskCompletionSource secondFlushCompleted = new(TaskCreationOptions.RunContinuationsAsynchronously); |
126 | 127 | sut.Initialize(null, await serverStreamTask); |
127 | | - var testApp = new TestBase.TestApplication(ctx => |
| 128 | + var testApp = new TestBase.TestApplication(async ctx => |
128 | 129 | { |
129 | 130 | Assert.Equal("/", ctx.Request.Path); |
130 | 131 | Assert.Equal("https", ctx.Request.Scheme); |
131 | 132 | Assert.Equal("localhost", ctx.Request.Host.ToString()); |
132 | 133 | Assert.Equal(HttpMethod.Get.ToString(), ctx.Request.Method); |
133 | | - tcs.SetResult(); |
134 | | - return Task.CompletedTask; |
| 134 | + |
| 135 | + // This callback shall not complete before the 2nd flush, otherwise the |
| 136 | + // server might close the stream before the flush succeeds. |
| 137 | + await secondFlushCompleted.Task; |
135 | 138 | }); |
136 | 139 | var processing = sut.ProcessStreamAsync(testApp, TestContext.Current.CancellationToken); |
137 | 140 |
|
138 | 141 | await clientStream.WriteAsync(data.AsMemory(i), TestContext.Current.CancellationToken); |
139 | 142 | await clientStream.FlushAsync(TestContext.Current.CancellationToken); |
| 143 | + secondFlushCompleted.SetResult(); |
140 | 144 |
|
141 | | - await tcs.Task.WaitAsync(DefaultTimeout, TestContext.Current.CancellationToken); |
142 | | - clientStream.Close(); |
143 | 145 | await processing; |
| 146 | + clientStream.Close(); |
144 | 147 | } |
145 | | - await quicConnection.DisposeAsync(); |
146 | 148 | } |
147 | 149 |
|
148 | 150 | [Fact] |
|
0 commit comments