Skip to content

Commit 04bf1bf

Browse files
authored
Implement new bedrock listener abstraction and re-plat Kestrel on top (#10321)
This is a massive set of changes to Kestrel to remove the existing pubternal transport layer and implement a public facing API for listeners and clients, see the details here #10308. This change only has the server side pieces of the story as I don't want to add the client APIs without having ported SignalR to use them. Here are the highlights: - Transport.Abstractions is empty (will be removed in a separate PR as it requires removing it from a ton of places) - TransportConnection has been moved to Connection.Abstractions (we can decide if we need to consolidate with DefaultConnectionContext in a later PR) - Added FileHandleEndPoint which allows binding to a file handle (could be a pipe or tcp handle) ListenOptions has been gutted for most pubternal API and returns various types of binding information . The source of truth is the EndPoint instance. - Cleaned up a bunch of libuv tests decoupling them from Kestrel.Core ## Breaking changes - Removing pubternal API is itself a breaking change but one that we already planned to do. - We've removed the ability to set the scheduling mode on Kestrel - DisposeAsync was added to ConnectionContext - NoDelay was removed from ListenOptions. This has been moved to each of the transports. One major difference though is that it's no longer localized per endpoint but is global. We'd need a derived EndPoint type (or maybe extend IPEndPoint) to store both the socket options and the binding information.
1 parent 9ebabc1 commit 04bf1bf

File tree

143 files changed

+2109
-2091
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+2109
-2091
lines changed

src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@ public static partial class ConnectionBuilderExtensions
3030
public abstract partial class ConnectionContext
3131
{
3232
protected ConnectionContext() { }
33+
public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
3334
public abstract string ConnectionId { get; set; }
3435
public abstract Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get; }
3536
public abstract System.Collections.Generic.IDictionary<object, object> Items { get; set; }
37+
public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
38+
public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
3639
public abstract System.IO.Pipelines.IDuplexPipe Transport { get; set; }
3740
public virtual void Abort() { }
3841
public virtual void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { }
42+
public virtual System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
3943
}
4044
public delegate System.Threading.Tasks.Task ConnectionDelegate(Microsoft.AspNetCore.Connections.ConnectionContext connection);
4145
public abstract partial class ConnectionHandler
@@ -70,40 +74,97 @@ public partial class ConnectionResetException : System.IO.IOException
7074
public ConnectionResetException(string message) { }
7175
public ConnectionResetException(string message, System.Exception inner) { }
7276
}
73-
public partial class DefaultConnectionContext : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionIdFeature, Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature, Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature, Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature, Microsoft.AspNetCore.Connections.Features.IConnectionUserFeature, System.IDisposable
77+
public partial class DefaultConnectionContext : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionEndPointFeature, Microsoft.AspNetCore.Connections.Features.IConnectionIdFeature, Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature, Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature, Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature, Microsoft.AspNetCore.Connections.Features.IConnectionUserFeature, System.IDisposable
7478
{
7579
public DefaultConnectionContext() { }
7680
public DefaultConnectionContext(string id) { }
7781
public DefaultConnectionContext(string id, System.IO.Pipelines.IDuplexPipe transport, System.IO.Pipelines.IDuplexPipe application) { }
7882
public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
79-
public System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
83+
public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
8084
public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
8185
public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
8286
public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
87+
public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
88+
public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
8389
public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
8490
public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
8591
public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { }
8692
public void Dispose() { }
93+
public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
94+
}
95+
public partial class FileHandleEndPoint : System.Net.EndPoint
96+
{
97+
public FileHandleEndPoint(ulong fileHandle, Microsoft.AspNetCore.Connections.FileHandleType fileHandleType) { }
98+
public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
99+
public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
100+
}
101+
public enum FileHandleType
102+
{
103+
Auto = 0,
104+
Tcp = 1,
105+
Pipe = 2,
87106
}
88107
public partial interface IConnectionBuilder
89108
{
90109
System.IServiceProvider ApplicationServices { get; }
91110
Microsoft.AspNetCore.Connections.ConnectionDelegate Build();
92111
Microsoft.AspNetCore.Connections.IConnectionBuilder Use(System.Func<Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Connections.ConnectionDelegate> middleware);
93112
}
113+
public partial interface IConnectionListener
114+
{
115+
System.Net.EndPoint EndPoint { get; }
116+
System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> AcceptAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
117+
System.Threading.Tasks.ValueTask DisposeAsync();
118+
System.Threading.Tasks.ValueTask UnbindAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
119+
}
120+
public partial interface IConnectionListenerFactory
121+
{
122+
System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.IConnectionListener> BindAsync(System.Net.EndPoint endpoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
123+
}
94124
[System.FlagsAttribute]
95125
public enum TransferFormat
96126
{
97127
Binary = 1,
98128
Text = 2,
99129
}
130+
public abstract partial class TransportConnection : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionIdFeature, Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature, Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature, Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature, Microsoft.AspNetCore.Connections.Features.IMemoryPoolFeature, Microsoft.AspNetCore.Http.Features.IFeatureCollection, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.Type, object>>, System.Collections.IEnumerable
131+
{
132+
public TransportConnection() { }
133+
public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
134+
public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
135+
public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
136+
public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get { throw null; } }
137+
public override System.Collections.Generic.IDictionary<object, object> Items { get { throw null; } set { } }
138+
public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
139+
public virtual System.Buffers.MemoryPool<byte> MemoryPool { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
140+
System.Collections.Generic.IDictionary<object, object> Microsoft.AspNetCore.Connections.Features.IConnectionItemsFeature.Items { get { throw null; } set { } }
141+
System.Threading.CancellationToken Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature.ConnectionClosed { get { throw null; } set { } }
142+
System.IO.Pipelines.IDuplexPipe Microsoft.AspNetCore.Connections.Features.IConnectionTransportFeature.Transport { get { throw null; } set { } }
143+
System.Buffers.MemoryPool<byte> Microsoft.AspNetCore.Connections.Features.IMemoryPoolFeature.MemoryPool { get { throw null; } }
144+
bool Microsoft.AspNetCore.Http.Features.IFeatureCollection.IsReadOnly { get { throw null; } }
145+
object Microsoft.AspNetCore.Http.Features.IFeatureCollection.this[System.Type key] { get { throw null; } set { } }
146+
int Microsoft.AspNetCore.Http.Features.IFeatureCollection.Revision { get { throw null; } }
147+
public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
148+
public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
149+
public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { }
150+
void Microsoft.AspNetCore.Connections.Features.IConnectionLifetimeFeature.Abort() { }
151+
TFeature Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get<TFeature>() { throw null; }
152+
void Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set<TFeature>(TFeature feature) { }
153+
System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<System.Type, object>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.Type,System.Object>>.GetEnumerator() { throw null; }
154+
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
155+
}
100156
}
101157
namespace Microsoft.AspNetCore.Connections.Features
102158
{
103159
public partial interface IConnectionCompleteFeature
104160
{
105161
void OnCompleted(System.Func<object, System.Threading.Tasks.Task> callback, object state);
106162
}
163+
public partial interface IConnectionEndPointFeature
164+
{
165+
System.Net.EndPoint LocalEndPoint { get; set; }
166+
System.Net.EndPoint RemoteEndPoint { get; set; }
167+
}
107168
public partial interface IConnectionHeartbeatFeature
108169
{
109170
void OnHeartbeat(System.Action<object> action, object state);

src/Servers/Connections.Abstractions/src/ConnectionContext.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
using System.Collections.Generic;
55
using System.IO.Pipelines;
6+
using System.Net;
7+
using System.Threading;
8+
using System.Threading.Tasks;
69
using Microsoft.AspNetCore.Connections.Features;
710
using Microsoft.AspNetCore.Http.Features;
811

@@ -18,6 +21,12 @@ public abstract class ConnectionContext
1821

1922
public abstract IDuplexPipe Transport { get; set; }
2023

24+
public virtual CancellationToken ConnectionClosed { get; set; }
25+
26+
public virtual EndPoint LocalEndPoint { get; set; }
27+
28+
public virtual EndPoint RemoteEndPoint { get; set; }
29+
2130
public virtual void Abort(ConnectionAbortedException abortReason)
2231
{
2332
// We expect this to be overridden, but this helps maintain back compat
@@ -27,5 +36,10 @@ public virtual void Abort(ConnectionAbortedException abortReason)
2736
}
2837

2938
public virtual void Abort() => Abort(new ConnectionAbortedException("The connection was aborted by the application via ConnectionContext.Abort()."));
39+
40+
public virtual ValueTask DisposeAsync()
41+
{
42+
return default;
43+
}
3044
}
3145
}

src/Servers/Connections.Abstractions/src/ConnectionDelegate.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System.Threading.Tasks;
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Threading.Tasks;
25

36
namespace Microsoft.AspNetCore.Connections
47
{

src/Servers/Connections.Abstractions/src/DefaultConnectionContext.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
using System;
55
using System.Collections.Generic;
66
using System.IO.Pipelines;
7+
using System.Net;
78
using System.Security.Claims;
89
using System.Threading;
10+
using System.Threading.Tasks;
911
using Microsoft.AspNetCore.Connections.Features;
1012
using Microsoft.AspNetCore.Http.Features;
1113

@@ -17,7 +19,8 @@ public class DefaultConnectionContext : ConnectionContext,
1719
IConnectionItemsFeature,
1820
IConnectionTransportFeature,
1921
IConnectionUserFeature,
20-
IConnectionLifetimeFeature
22+
IConnectionLifetimeFeature,
23+
IConnectionEndPointFeature
2124
{
2225
private CancellationTokenSource _connectionClosedTokenSource = new CancellationTokenSource();
2326

@@ -42,6 +45,7 @@ public DefaultConnectionContext(string id)
4245
Features.Set<IConnectionIdFeature>(this);
4346
Features.Set<IConnectionTransportFeature>(this);
4447
Features.Set<IConnectionLifetimeFeature>(this);
48+
Features.Set<IConnectionEndPointFeature>(this);
4549
}
4650

4751
public DefaultConnectionContext(string id, IDuplexPipe transport, IDuplexPipe application)
@@ -63,7 +67,9 @@ public DefaultConnectionContext(string id, IDuplexPipe transport, IDuplexPipe ap
6367

6468
public override IDuplexPipe Transport { get; set; }
6569

66-
public CancellationToken ConnectionClosed { get; set; }
70+
public override CancellationToken ConnectionClosed { get; set; }
71+
public override EndPoint LocalEndPoint { get; set; }
72+
public override EndPoint RemoteEndPoint { get; set; }
6773

6874
public override void Abort(ConnectionAbortedException abortReason)
6975
{
@@ -74,5 +80,11 @@ public void Dispose()
7480
{
7581
_connectionClosedTokenSource.Dispose();
7682
}
83+
84+
public override ValueTask DisposeAsync()
85+
{
86+
_connectionClosedTokenSource.Dispose();
87+
return base.DisposeAsync();
88+
}
7789
}
7890
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Net;
5+
6+
namespace Microsoft.AspNetCore.Connections.Features
7+
{
8+
public interface IConnectionEndPointFeature
9+
{
10+
EndPoint LocalEndPoint { get; set; }
11+
EndPoint RemoteEndPoint { get; set; }
12+
}
13+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
14
using System.Security.Claims;
25

36
namespace Microsoft.AspNetCore.Connections.Features
@@ -6,4 +9,4 @@ public interface IConnectionUserFeature
69
{
710
ClaimsPrincipal User { get; set; }
811
}
9-
}
12+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Net;
6+
7+
namespace Microsoft.AspNetCore.Connections
8+
{
9+
public class FileHandleEndPoint : EndPoint
10+
{
11+
public FileHandleEndPoint(ulong fileHandle, FileHandleType fileHandleType)
12+
{
13+
FileHandle = fileHandle;
14+
FileHandleType = fileHandleType;
15+
16+
switch (fileHandleType)
17+
{
18+
case FileHandleType.Auto:
19+
case FileHandleType.Tcp:
20+
case FileHandleType.Pipe:
21+
break;
22+
default:
23+
throw new NotSupportedException();
24+
}
25+
}
26+
27+
public ulong FileHandle { get; }
28+
public FileHandleType FileHandleType { get; }
29+
}
30+
}

src/Servers/Kestrel/Transport.Abstractions/src/Internal/FileHandleType.cs renamed to src/Servers/Connections.Abstractions/src/FileHandleType.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// 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-
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal
4+
namespace Microsoft.AspNetCore.Connections
55
{
66
/// <summary>
7-
/// Enumerates the <see cref="IEndPointInformation.FileHandle"/> types.
7+
/// Enumerates the <see cref="FileHandleEndPoint"/> types.
88
/// </summary>
99
public enum FileHandleType
1010
{

src/Servers/Connections.Abstractions/src/IConnectionBuilder.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System;
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
25

36
namespace Microsoft.AspNetCore.Connections
47
{
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Net;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace Microsoft.AspNetCore.Connections
9+
{
10+
public interface IConnectionListener
11+
{
12+
EndPoint EndPoint { get; }
13+
14+
ValueTask<ConnectionContext> AcceptAsync(CancellationToken cancellationToken = default);
15+
16+
ValueTask UnbindAsync(CancellationToken cancellationToken = default);
17+
18+
ValueTask DisposeAsync();
19+
}
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Net;
7+
using System.Text;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
11+
namespace Microsoft.AspNetCore.Connections
12+
{
13+
public interface IConnectionListenerFactory
14+
{
15+
ValueTask<IConnectionListener> BindAsync(EndPoint endpoint, CancellationToken cancellationToken = default);
16+
}
17+
}

0 commit comments

Comments
 (0)