Skip to content

Commit 77ff682

Browse files
committed
Make things "simpler"
1 parent d6e0a09 commit 77ff682

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ private async Task WriteToOutputPipe()
149149
(var hasMoreData, var reschedule, currentState, var waitingForWindowUpdates) = producer.ObserveDataAndState(buffer.Length, observed);
150150

151151
var aborted = currentState.HasFlag(Http2OutputProducer.State.Aborted);
152-
var completed = currentState.HasFlag(Http2OutputProducer.State.Completed);
152+
var completed = currentState.HasFlag(Http2OutputProducer.State.Completed) && !hasMoreData;
153153

154154
FlushResult flushResult = default;
155155

@@ -174,7 +174,7 @@ private async Task WriteToOutputPipe()
174174
}
175175
}
176176
}
177-
else if (completed && stream.ResponseTrailers is { Count: > 0 } && !hasMoreData)
177+
else if (completed && stream.ResponseTrailers is { Count: > 0 })
178178
{
179179
// Output is ending and there are trailers to write
180180
// Write any remaining content then write trailers and there's no
@@ -202,7 +202,7 @@ private async Task WriteToOutputPipe()
202202
}
203203
else
204204
{
205-
var endStream = completed && !hasMoreData;
205+
var endStream = completed;
206206

207207
if (endStream)
208208
{
@@ -219,7 +219,7 @@ private async Task WriteToOutputPipe()
219219

220220
reader.AdvanceTo(buffer.End);
221221

222-
if ((completed && !hasMoreData) || aborted)
222+
if (completed || aborted)
223223
{
224224
await reader.CompleteAsync();
225225

src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ internal class Http2OutputProducer : IHttpOutputProducer, IHttpOutputAborter, ID
2828
private IMemoryOwner<byte>? _fakeMemoryOwner;
2929
private byte[]? _fakeMemory;
3030
private bool _startedWritingDataFrames;
31-
private bool _streamCompleted;
31+
private bool _completeScheduled;
3232
private bool _suffixSent;
3333
private bool _appCompletedWithNoResponseBodyOrTrailers;
3434
private bool _writerComplete;
@@ -176,7 +176,7 @@ public void StreamReset(uint initialWindowSize)
176176
_appCompletedWithNoResponseBodyOrTrailers = false;
177177
_suffixSent = false;
178178
_startedWritingDataFrames = false;
179-
_streamCompleted = false;
179+
_completeScheduled = false;
180180
_writerComplete = false;
181181
_pipe.Reset();
182182
_pipeWriter.Reset();
@@ -205,7 +205,7 @@ public void Complete()
205205

206206
Stop();
207207

208-
if (!_streamCompleted)
208+
if (!_completeScheduled)
209209
{
210210
EnqueueStateUpdate(State.Completed);
211211

@@ -256,7 +256,8 @@ public ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken)
256256
lock (_dataWriterLock)
257257
{
258258
ThrowIfSuffixSentOrCompleted();
259-
if (_streamCompleted)
259+
260+
if (_completeScheduled)
260261
{
261262
return new ValueTask<FlushResult>(new FlushResult(false, true));
262263
}
@@ -317,7 +318,7 @@ public ValueTask<FlushResult> Write100ContinueAsync()
317318
{
318319
ThrowIfSuffixSentOrCompleted();
319320

320-
if (_streamCompleted)
321+
if (_completeScheduled)
321322
{
322323
return default;
323324
}
@@ -332,7 +333,7 @@ public void WriteResponseHeaders(int statusCode, string? reasonPhrase, HttpRespo
332333
{
333334
// The HPACK header compressor is stateful, if we compress headers for an aborted stream we must send them.
334335
// Optimize for not compressing or sending them.
335-
if (_streamCompleted)
336+
if (_completeScheduled)
336337
{
337338
return;
338339
}
@@ -366,7 +367,7 @@ public Task WriteDataAsync(ReadOnlySpan<byte> data, CancellationToken cancellati
366367

367368
// This length check is important because we don't want to set _startedWritingDataFrames unless a data
368369
// frame will actually be written causing the headers to be flushed.
369-
if (_streamCompleted || data.Length == 0)
370+
if (_completeScheduled || data.Length == 0)
370371
{
371372
return Task.CompletedTask;
372373
}
@@ -389,12 +390,12 @@ public ValueTask<FlushResult> WriteStreamSuffixAsync()
389390
{
390391
lock (_dataWriterLock)
391392
{
392-
if (_streamCompleted)
393+
if (_completeScheduled)
393394
{
394395
return ValueTask.FromResult<FlushResult>(default);
395396
}
396397

397-
_streamCompleted = true;
398+
_completeScheduled = true;
398399
_suffixSent = true;
399400

400401
EnqueueStateUpdate(State.Completed);
@@ -413,7 +414,7 @@ public ValueTask<FlushResult> WriteRstStreamAsync(Http2ErrorCode error)
413414
{
414415
Stop();
415416
// We queued the stream to complete but didn't complete the response yet
416-
if (_streamCompleted && !_completedResponse)
417+
if (_completeScheduled && !_completedResponse)
417418
{
418419
// Set the error so that we can write the RST when the response completes.
419420
_resetErrorCode = error;
@@ -430,7 +431,7 @@ public void Advance(int bytes)
430431
{
431432
ThrowIfSuffixSentOrCompleted();
432433

433-
if (_streamCompleted)
434+
if (_completeScheduled)
434435
{
435436
return;
436437
}
@@ -449,7 +450,7 @@ public Span<byte> GetSpan(int sizeHint = 0)
449450
{
450451
ThrowIfSuffixSentOrCompleted();
451452

452-
if (_streamCompleted)
453+
if (_completeScheduled)
453454
{
454455
return GetFakeMemory(sizeHint).Span;
455456
}
@@ -464,7 +465,7 @@ public Memory<byte> GetMemory(int sizeHint = 0)
464465
{
465466
ThrowIfSuffixSentOrCompleted();
466467

467-
if (_streamCompleted)
468+
if (_completeScheduled)
468469
{
469470
return GetFakeMemory(sizeHint);
470471
}
@@ -477,7 +478,7 @@ public void CancelPendingFlush()
477478
{
478479
lock (_dataWriterLock)
479480
{
480-
if (_streamCompleted)
481+
if (_completeScheduled)
481482
{
482483
return;
483484
}
@@ -499,7 +500,7 @@ public ValueTask<FlushResult> WriteDataToPipeAsync(ReadOnlySpan<byte> data, Canc
499500

500501
// This length check is important because we don't want to set _startedWritingDataFrames unless a data
501502
// frame will actually be written causing the headers to be flushed.
502-
if (_streamCompleted || data.Length == 0)
503+
if (_completeScheduled || data.Length == 0)
503504
{
504505
return new ValueTask<FlushResult>(new FlushResult(false, true));
505506
}
@@ -543,14 +544,14 @@ public void Stop()
543544
{
544545
_waitingForWindowUpdates = false;
545546

546-
if (_streamCompleted && _completedResponse)
547+
if (_completeScheduled && _completedResponse)
547548
{
548549
// We can overschedule as long as we haven't yet completed the response. This is important because
549550
// we may need to abort the stream if it's waiting for a window update.
550551
return;
551552
}
552553

553-
_streamCompleted = true;
554+
_completeScheduled = true;
554555

555556
EnqueueStateUpdate(State.Aborted);
556557

0 commit comments

Comments
 (0)