-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace SocketsHttpConnectionFactory with SocketsConnectionFactory (#…
…40506) Introduces SocketsConnectionFactory from #40044 without the factory methods for NetworkStream and IDuplexPipe
- Loading branch information
1 parent
ff975e8
commit 8e5da14
Showing
25 changed files
with
779 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexStreamPipe.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.IO; | ||
using System.IO.Pipelines; | ||
|
||
namespace System.Net.Connections | ||
{ | ||
internal sealed class DuplexStreamPipe : IDuplexPipe | ||
{ | ||
private static readonly StreamPipeReaderOptions s_readerOpts = new StreamPipeReaderOptions(leaveOpen: true); | ||
private static readonly StreamPipeWriterOptions s_writerOpts = new StreamPipeWriterOptions(leaveOpen: true); | ||
|
||
public DuplexStreamPipe(Stream stream) | ||
{ | ||
Input = PipeReader.Create(stream, s_readerOpts); | ||
Output = PipeWriter.Create(stream, s_writerOpts); | ||
} | ||
|
||
public PipeReader Input { get; } | ||
|
||
public PipeWriter Output { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
...ies/System.Net.Connections/src/System/Net/Connections/Sockets/SocketsConnectionFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.IO; | ||
using System.IO.Pipelines; | ||
using System.Net.Sockets; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace System.Net.Connections | ||
{ | ||
/// <summary> | ||
/// A <see cref="ConnectionFactory"/> to establish socket-based connections. | ||
/// </summary> | ||
/// <remarks> | ||
/// When constructed with <see cref="ProtocolType.Tcp"/>, this factory will create connections with <see cref="Socket.NoDelay"/> enabled. | ||
/// In case of IPv6 sockets <see cref="Socket.DualMode"/> is also enabled. | ||
/// </remarks> | ||
public class SocketsConnectionFactory : ConnectionFactory | ||
{ | ||
private readonly AddressFamily _addressFamily; | ||
private readonly SocketType _socketType; | ||
private readonly ProtocolType _protocolType; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="SocketsConnectionFactory"/> class. | ||
/// </summary> | ||
/// <param name="addressFamily">The <see cref="AddressFamily"/> to forward to the socket.</param> | ||
/// <param name="socketType">The <see cref="SocketType"/> to forward to the socket.</param> | ||
/// <param name="protocolType">The <see cref="ProtocolType"/> to forward to the socket.</param> | ||
public SocketsConnectionFactory( | ||
AddressFamily addressFamily, | ||
SocketType socketType, | ||
ProtocolType protocolType) | ||
{ | ||
_addressFamily = addressFamily; | ||
_socketType = socketType; | ||
_protocolType = protocolType; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="SocketsConnectionFactory"/> class | ||
/// that will forward <see cref="AddressFamily.InterNetworkV6"/> to the Socket constructor. | ||
/// </summary> | ||
/// <param name="socketType">The <see cref="SocketType"/> to forward to the socket.</param> | ||
/// <param name="protocolType">The <see cref="ProtocolType"/> to forward to the socket.</param> | ||
/// <remarks>The created socket will be an IPv6 socket with <see cref="Socket.DualMode"/> enabled.</remarks> | ||
public SocketsConnectionFactory(SocketType socketType, ProtocolType protocolType) | ||
: this(AddressFamily.InterNetworkV6, socketType, protocolType) | ||
{ | ||
} | ||
|
||
/// <inheritdoc /> | ||
/// <exception cref="ArgumentNullException">When <paramref name="endPoint"/> is <see langword="null"/>.</exception> | ||
public override async ValueTask<Connection> ConnectAsync( | ||
EndPoint? endPoint, | ||
IConnectionProperties? options = null, | ||
CancellationToken cancellationToken = default) | ||
{ | ||
if (endPoint == null) throw new ArgumentNullException(nameof(endPoint)); | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
Socket socket = CreateSocket(_addressFamily, _socketType, _protocolType, endPoint, options); | ||
|
||
try | ||
{ | ||
using var args = new TaskSocketAsyncEventArgs(); | ||
args.RemoteEndPoint = endPoint; | ||
|
||
if (socket.ConnectAsync(args)) | ||
{ | ||
using (cancellationToken.UnsafeRegister(static o => Socket.CancelConnectAsync((SocketAsyncEventArgs)o!), args)) | ||
{ | ||
await args.Task.ConfigureAwait(false); | ||
} | ||
} | ||
|
||
if (args.SocketError != SocketError.Success) | ||
{ | ||
if (args.SocketError == SocketError.OperationAborted) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
} | ||
|
||
throw NetworkErrorHelper.MapSocketException(new SocketException((int)args.SocketError)); | ||
} | ||
|
||
return new SocketConnection(socket); | ||
} | ||
catch (SocketException socketException) | ||
{ | ||
socket.Dispose(); | ||
throw NetworkErrorHelper.MapSocketException(socketException); | ||
} | ||
catch | ||
{ | ||
socket.Dispose(); | ||
throw; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Creates the socket that shall be used with the connection. | ||
/// </summary> | ||
/// <param name="addressFamily">The <see cref="AddressFamily"/> to forward to the socket.</param> | ||
/// <param name="socketType">The <see cref="SocketType"/> to forward to the socket.</param> | ||
/// <param name="protocolType">The <see cref="ProtocolType"/> to forward to the socket.</param> | ||
/// <param name="endPoint">The <see cref="EndPoint"/> this socket will be connected to.</param> | ||
/// <param name="options">Properties, if any, that might change how the socket is initialized.</param> | ||
/// <returns>A new unconnected <see cref="Socket"/>.</returns> | ||
/// <remarks> | ||
/// In case of TCP sockets, the default implementation of this method will create a socket with <see cref="Socket.NoDelay"/> enabled. | ||
/// In case of IPv6 sockets <see cref="Socket.DualMode"/> is also be enabled. | ||
/// </remarks> | ||
protected virtual Socket CreateSocket( | ||
AddressFamily addressFamily, | ||
SocketType socketType, | ||
ProtocolType protocolType, | ||
EndPoint? endPoint, | ||
IConnectionProperties? options) | ||
{ | ||
Socket socket = new Socket(addressFamily, socketType, protocolType); | ||
|
||
if (protocolType == ProtocolType.Tcp) | ||
{ | ||
socket.NoDelay = true; | ||
} | ||
|
||
if (addressFamily == AddressFamily.InterNetworkV6) | ||
{ | ||
socket.DualMode = true; | ||
} | ||
|
||
return socket; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.