Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 706ff04

Browse files
committed
Merge branch 'benaadams/statemachines' into dev
2 parents c451ce1 + c41b449 commit 706ff04

File tree

2 files changed

+84
-22
lines changed

2 files changed

+84
-22
lines changed

src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ public abstract partial class Frame : FrameContext, IFrameControl
4444
protected readonly FrameRequestHeaders _requestHeaders = new FrameRequestHeaders();
4545
private readonly FrameResponseHeaders _responseHeaders = new FrameResponseHeaders();
4646

47-
private List<KeyValuePair<Func<object, Task>, object>> _onStarting;
47+
protected List<KeyValuePair<Func<object, Task>, object>> _onStarting;
4848

49-
private List<KeyValuePair<Func<object, Task>, object>> _onCompleted;
49+
protected List<KeyValuePair<Func<object, Task>, object>> _onCompleted;
5050

5151
private bool _requestProcessingStarted;
5252
private Task _requestProcessingTask;
@@ -144,8 +144,9 @@ public CancellationToken RequestAborted
144144
{
145145
// If a request abort token was previously explicitly set, return it.
146146
if (_manuallySetRequestAbortToken.HasValue)
147+
{
147148
return _manuallySetRequestAbortToken.Value;
148-
149+
}
149150
// Otherwise, get the abort CTS. If we have one, which would mean that someone previously
150151
// asked for the RequestAborted token, simply return its token. If we don't,
151152
// check to see whether we've already aborted, in which case just return an
@@ -416,7 +417,28 @@ public void Write(ArraySegment<byte> data)
416417
}
417418
}
418419

419-
public async Task WriteAsync(ArraySegment<byte> data, CancellationToken cancellationToken)
420+
public Task WriteAsync(ArraySegment<byte> data, CancellationToken cancellationToken)
421+
{
422+
if (!_responseStarted)
423+
{
424+
return WriteAsyncAwaited(data, cancellationToken);
425+
}
426+
427+
if (_autoChunk)
428+
{
429+
if (data.Count == 0)
430+
{
431+
return TaskUtilities.CompletedTask;
432+
}
433+
return WriteChunkedAsync(data, cancellationToken);
434+
}
435+
else
436+
{
437+
return SocketOutput.WriteAsync(data, immediate: true, cancellationToken: cancellationToken);
438+
}
439+
}
440+
441+
public async Task WriteAsyncAwaited(ArraySegment<byte> data, CancellationToken cancellationToken)
420442
{
421443
await ProduceStartAndFireOnStarting(immediate: false);
422444

@@ -501,10 +523,27 @@ public void ProduceContinue()
501523
}
502524
}
503525

504-
public async Task ProduceStartAndFireOnStarting(bool immediate = true)
526+
public Task ProduceStartAndFireOnStarting(bool immediate = true)
505527
{
506-
if (_responseStarted) return;
528+
if (_responseStarted) return TaskUtilities.CompletedTask;
529+
530+
if (_onStarting != null)
531+
{
532+
return FireOnStartingProduceStart(immediate: immediate);
533+
}
507534

535+
if (_applicationException != null)
536+
{
537+
throw new ObjectDisposedException(
538+
"The response has been aborted due to an unhandled application exception.",
539+
_applicationException);
540+
}
541+
542+
return ProduceStart(immediate, appCompleted: false);
543+
}
544+
545+
private async Task FireOnStartingProduceStart(bool immediate)
546+
{
508547
await FireOnStarting();
509548

510549
if (_applicationException != null)
@@ -527,15 +566,15 @@ private Task ProduceStart(bool immediate, bool appCompleted)
527566
return CreateResponseHeader(statusBytes, appCompleted, immediate);
528567
}
529568

530-
protected async Task ProduceEnd()
569+
protected Task ProduceEnd()
531570
{
532571
if (_applicationException != null)
533572
{
534573
if (_responseStarted)
535574
{
536575
// We can no longer respond with a 500, so we simply close the connection.
537576
_requestProcessingStopping = true;
538-
return;
577+
return TaskUtilities.CompletedTask;
539578
}
540579
else
541580
{
@@ -547,8 +586,26 @@ protected async Task ProduceEnd()
547586
}
548587
}
549588

589+
590+
if (!_responseStarted)
591+
{
592+
return ProduceEndAwaited();
593+
}
594+
595+
WriteSuffix();
596+
597+
return TaskUtilities.CompletedTask;
598+
}
599+
600+
private async Task ProduceEndAwaited()
601+
{
550602
await ProduceStart(immediate: true, appCompleted: true);
551603

604+
WriteSuffix();
605+
}
606+
607+
private void WriteSuffix()
608+
{
552609
// _autoChunk should be checked after we are sure ProduceStart() has been called
553610
// since ProduceStart() may set _autoChunk to true.
554611
if (_autoChunk)

src/Microsoft.AspNet.Server.Kestrel/Http/FrameOfT.cs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,27 @@ public override async Task RequestProcessingAsync()
4040
{
4141
try
4242
{
43-
var terminated = false;
44-
while (!terminated && !_requestProcessingStopping)
43+
while (!_requestProcessingStopping)
4544
{
46-
while (!terminated && !_requestProcessingStopping && !TakeStartLine(SocketInput))
45+
while (!_requestProcessingStopping && !TakeStartLine(SocketInput))
4746
{
48-
terminated = SocketInput.RemoteIntakeFin;
49-
if (!terminated)
47+
if (SocketInput.RemoteIntakeFin)
5048
{
51-
await SocketInput;
49+
return;
5250
}
51+
await SocketInput;
5352
}
5453

55-
while (!terminated && !_requestProcessingStopping && !TakeMessageHeaders(SocketInput, _requestHeaders))
54+
while (!_requestProcessingStopping && !TakeMessageHeaders(SocketInput, _requestHeaders))
5655
{
57-
terminated = SocketInput.RemoteIntakeFin;
58-
if (!terminated)
56+
if (SocketInput.RemoteIntakeFin)
5957
{
60-
await SocketInput;
58+
return;
6159
}
60+
await SocketInput;
6261
}
6362

64-
if (!terminated && !_requestProcessingStopping)
63+
if (!_requestProcessingStopping)
6564
{
6665
var messageBody = MessageBody.For(HttpVersion, _requestHeaders, this);
6766
_keepAlive = messageBody.RequestKeepAlive;
@@ -89,12 +88,15 @@ public override async Task RequestProcessingAsync()
8988
// already failed. If an OnStarting callback throws we can go through
9089
// our normal error handling in ProduceEnd.
9190
// https://github.com/aspnet/KestrelHttpServer/issues/43
92-
if (!_responseStarted && _applicationException == null)
91+
if (!_responseStarted && _applicationException == null && _onStarting != null)
9392
{
9493
await FireOnStarting();
9594
}
9695

97-
await FireOnCompleted();
96+
if (_onCompleted != null)
97+
{
98+
await FireOnCompleted();
99+
}
98100

99101
_application.DisposeContext(context, _applicationException);
100102

@@ -114,7 +116,10 @@ public override async Task RequestProcessingAsync()
114116
_responseBody.StopAcceptingWrites();
115117
}
116118

117-
terminated = !_keepAlive;
119+
if (!_keepAlive)
120+
{
121+
return;
122+
}
118123
}
119124

120125
Reset();

0 commit comments

Comments
 (0)