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

Commit

Permalink
Don't pause and resume read timing on upgrade requests (#1904).
Browse files Browse the repository at this point in the history
  • Loading branch information
Cesar Blum Silveira committed Jun 19, 2017
1 parent f67a105 commit fe7fc91
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
using Microsoft.Extensions.Logging;

namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
Expand Down Expand Up @@ -92,14 +93,14 @@ private async Task PumpAsync()
{
// Backpressure, stop controlling incoming data rate until data is read.
backpressure = true;
_context.TimeoutControl.PauseTimingReads();
TryPauseTimingReads();
}

await writeAwaitable;

if (backpressure)
{
_context.TimeoutControl.ResumeTimingReads();
TryResumeTimingReads();
}

if (done)
Expand Down Expand Up @@ -273,6 +274,22 @@ private void TryStartTimingReads()
}
}

private void TryPauseTimingReads()
{
if (!RequestUpgrade)
{
_context.TimeoutControl.PauseTimingReads();
}
}

private void TryResumeTimingReads()
{
if (!RequestUpgrade)
{
_context.TimeoutControl.ResumeTimingReads();
}
}

private void TryStopTimingReads()
{
if (!RequestUpgrade)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,29 @@ public async Task LogsWhenStopsReadingRequestBody()
}
}

[Fact]
public async Task PausesAndResumesRequestBodyTimeoutOnBackpressure()
{
using (var input = new TestInput())
{
var mockTimeoutControl = new Mock<ITimeoutControl>();
input.FrameContext.TimeoutControl = mockTimeoutControl.Object;

var body = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderContentLength = "12" }, input.Frame);

// Add some input and read it to start PumpAsync
input.Add("hello,");
Assert.Equal(6, await body.ReadAsync(new ArraySegment<byte>(new byte[6])));

input.Add(" world");
Assert.Equal(6, await body.ReadAsync(new ArraySegment<byte>(new byte[6])));

// Due to the limits set on Frame.RequestBodyPipe, backpressure should be triggered on every write to that pipe.
mockTimeoutControl.Verify(timeoutControl => timeoutControl.PauseTimingReads(), Times.Exactly(2));
mockTimeoutControl.Verify(timeoutControl => timeoutControl.ResumeTimingReads(), Times.Exactly(2));
}
}

[Fact]
public async Task OnlyEnforcesRequestBodyTimeoutAfterSending100Continue()
{
Expand Down Expand Up @@ -701,6 +724,12 @@ public async Task DoesNotEnforceRequestBodyTimeoutOnUpgradeRequests()

mockTimeoutControl.Verify(timeoutControl => timeoutControl.StartTimingReads(), Times.Never);
mockTimeoutControl.Verify(timeoutControl => timeoutControl.StopTimingReads(), Times.Never);

// Due to the limits set on Frame.RequestBodyPipe, backpressure should be triggered on every
// write to that pipe. Verify that read timing pause and resume are not called on upgrade
// requests.
mockTimeoutControl.Verify(timeoutControl => timeoutControl.PauseTimingReads(), Times.Never);
mockTimeoutControl.Verify(timeoutControl => timeoutControl.ResumeTimingReads(), Times.Never);
}
}

Expand Down

0 comments on commit fe7fc91

Please sign in to comment.