Skip to content

Commit b52eac2

Browse files
committed
Update
1 parent 6fa0432 commit b52eac2

File tree

5 files changed

+30
-29
lines changed

5 files changed

+30
-29
lines changed

src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,6 @@ public Http3Connection(Http3ConnectionContext context)
4747
_context = context;
4848
_systemClock = context.ServiceContext.SystemClock;
4949

50-
if (_context.TimeoutControl == null)
51-
{
52-
var timeoutControl = new TimeoutControl(this);
53-
54-
// Ensure TimeoutControl._lastTimestamp is initialized before anything that could set timeouts runs.
55-
timeoutControl.Initialize(_systemClock.UtcNowTicks);
56-
57-
_context.TimeoutControl = timeoutControl;
58-
}
59-
6050
_errorCodeFeature = context.ConnectionFeatures.Get<IProtocolErrorCodeFeature>()!;
6151

6252
var httpLimits = context.ServiceContext.ServerOptions.Limits;
@@ -80,7 +70,6 @@ internal long HighestStreamId
8070
}
8171
}
8272

83-
public ITimeoutControl TimeoutControl => _context.TimeoutControl!;
8473
private IKestrelTrace Log => _context.ServiceContext.Log;
8574
public KestrelServerLimits Limits => _context.ServiceContext.ServerOptions.Limits;
8675
public Http3ControlStream? OutboundControlStream { get; set; }
@@ -215,8 +204,6 @@ public void Tick()
215204
}
216205
}
217206

218-
TimeoutControl.Tick(now);
219-
220207
// TODO cancel process stream loop to update logic.
221208
}
222209

@@ -293,7 +280,7 @@ internal async Task InnerProcessStreamsAsync<TContext>(IHttpApplication<TContext
293280
streamContext.Transport,
294281
streamContext,
295282
_serverSettings);
296-
httpConnectionContext.TimeoutControl = _context.TimeoutControl!;
283+
httpConnectionContext.TimeoutControl = CreateStreamTimeout();
297284

298285
if (!quicStreamFeature.CanWrite)
299286
{
@@ -457,13 +444,26 @@ private async ValueTask<Http3ControlStream> CreateNewUnidirectionalStreamAsync<T
457444
streamContext.Transport,
458445
streamContext,
459446
_serverSettings);
460-
461-
// Each HTTP/3 stream has its own transport. Create timeout control per stream.
462-
httpConnectionContext.TimeoutControl = new TimeoutControl(this);
447+
httpConnectionContext.TimeoutControl = CreateStreamTimeout();
463448

464449
return new Http3ControlStream<TContext>(application, this, httpConnectionContext);
465450
}
466451

452+
private ITimeoutControl CreateStreamTimeout()
453+
{
454+
// Each HTTP/3 stream has its own transport. Create timeout control per stream.
455+
if (_context.TimeoutControlCreator != null)
456+
{
457+
return _context.TimeoutControlCreator(this);
458+
}
459+
else
460+
{
461+
var timeoutControl = new TimeoutControl(this);
462+
timeoutControl.Initialize(_systemClock.UtcNowTicks);
463+
return timeoutControl;
464+
}
465+
}
466+
467467
private ValueTask<FlushResult> SendGoAway(long id)
468468
{
469469
lock (_sync)

src/Servers/Kestrel/Core/src/Internal/Http3ConnectionContext.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.Buffers;
56
using System.Net;
67
using Microsoft.AspNetCore.Connections.Experimental;
78
using Microsoft.AspNetCore.Http.Features;
9+
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3;
810
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
911

1012
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
@@ -38,8 +40,8 @@ public Http3ConnectionContext(
3840
public IPEndPoint? RemoteEndPoint { get; }
3941

4042
/// <summary>
41-
/// Will be be set by unit tests or created by Http3Connection ctor.
43+
/// Will be be set by unit tests. If not set, default TimeoutControl is created.
4244
/// </summary>
43-
public ITimeoutControl? TimeoutControl { get; set; }
45+
public Func<Http3Connection, ITimeoutControl>? TimeoutControlCreator { get; set; }
4446
}
4547
}

src/Servers/Kestrel/shared/test/TestContextFactory.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ public static Http3ConnectionContext CreateHttp3ConnectionContext(
7979
IFeatureCollection connectionFeatures = null,
8080
MemoryPool<byte> memoryPool = null,
8181
IPEndPoint localEndPoint = null,
82-
IPEndPoint remoteEndPoint = null,
83-
ITimeoutControl timeoutControl = null)
82+
IPEndPoint remoteEndPoint = null)
8483
{
8584
var http3ConnectionContext = new Http3ConnectionContext(
8685
"TestConnectionId",
@@ -90,7 +89,6 @@ public static Http3ConnectionContext CreateHttp3ConnectionContext(
9089
memoryPool ?? PinnedBlockMemoryPoolFactory.Create(),
9190
localEndPoint,
9291
remoteEndPoint);
93-
http3ConnectionContext.TimeoutControl = timeoutControl;
9492

9593
return http3ConnectionContext;
9694
}

src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3TestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ protected void CreateConnection()
221221
memoryPool: _memoryPool,
222222
localEndPoint: null,
223223
remoteEndPoint: null);
224-
httpConnectionContext.TimeoutControl = _mockTimeoutControl.Object;
224+
httpConnectionContext.TimeoutControlCreator = c => _mockTimeoutControl.Object;
225225

226226
Connection = new Http3Connection(httpConnectionContext);
227227
_mockTimeoutHandler.Setup(h => h.OnTimeout(It.IsAny<TimeoutReason>()))

src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3TimeoutTests.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Net.Http;
66
using System.Threading.Tasks;
77
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
8+
using Microsoft.AspNetCore.Testing;
89
using Moq;
910
using Xunit;
1011

@@ -27,14 +28,14 @@ public async Task HEADERS_IncompleteFrameReceivedWithinRequestHeadersTimeout_Abo
2728

2829
_timeoutControl.Initialize(mockSystemClock.UtcNow.Ticks);
2930

30-
var requestStream = await InitializeConnectionAndStreamsAsync(_noopApplication);
31+
var requestStream = await InitializeConnectionAndStreamsAsync(_noopApplication).DefaultTimeout();
3132

32-
var controlStream = await GetInboundControlStream();
33-
await controlStream.ExpectSettingsAsync();
33+
var controlStream = await GetInboundControlStream().DefaultTimeout();
34+
await controlStream.ExpectSettingsAsync().DefaultTimeout();
3435

35-
await timerStartedTcs.Task;
36+
await timerStartedTcs.Task.DefaultTimeout();
3637

37-
await requestStream.SendHeadersPartialAsync();
38+
await requestStream.SendHeadersPartialAsync().DefaultTimeout();
3839

3940
AdvanceClock(limits.RequestHeadersTimeout + Heartbeat.Interval);
4041

@@ -48,7 +49,7 @@ public async Task HEADERS_IncompleteFrameReceivedWithinRequestHeadersTimeout_Abo
4849
ignoreNonGoAwayFrames: false,
4950
expectedLastStreamId: 0,
5051
expectedErrorCode: Http3ErrorCode.RequestRejected,
51-
expectedErrorMessage: CoreStrings.BadRequest_RequestHeadersTimeout);
52+
expectedErrorMessage: CoreStrings.BadRequest_RequestHeadersTimeout).DefaultTimeout();
5253

5354
_mockTimeoutHandler.VerifyNoOtherCalls();
5455
}

0 commit comments

Comments
 (0)