diff --git a/src/libraries/System.Net.Connections/Directory.Build.props b/src/libraries/System.Net.Connections/Directory.Build.props deleted file mode 100644 index 63f02a0f817ef..0000000000000 --- a/src/libraries/System.Net.Connections/Directory.Build.props +++ /dev/null @@ -1,6 +0,0 @@ - - - - Microsoft - - \ No newline at end of file diff --git a/src/libraries/System.Net.Connections/System.Net.Connections.sln b/src/libraries/System.Net.Connections/System.Net.Connections.sln deleted file mode 100644 index a325eb24b9713..0000000000000 --- a/src/libraries/System.Net.Connections/System.Net.Connections.sln +++ /dev/null @@ -1,50 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30310.162 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Net.Connections", "src\System.Net.Connections.csproj", "{1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}" - ProjectSection(ProjectDependencies) = postProject - {132BF813-FC40-4D39-8B6F-E55D7633F0ED} = {132BF813-FC40-4D39-8B6F-E55D7633F0ED} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Net.Connections", "ref\System.Net.Connections.csproj", "{132BF813-FC40-4D39-8B6F-E55D7633F0ED}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E107E9C1-E893-4E87-987E-04EF0DCEAEFD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{2E666815-2EDB-464B-9DF6-380BF4789AD4}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{E0983BCC-F93B-4FFF-A4E4-EA874908783F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.Connections.Tests", "tests\System.Net.Connections.Tests\System.Net.Connections.Tests.csproj", "{A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE}.Release|Any CPU.Build.0 = Release|Any CPU - {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {132BF813-FC40-4D39-8B6F-E55D7633F0ED}.Release|Any CPU.Build.0 = Release|Any CPU - {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1D422B1D-D7C4-41B9-862D-EB3D98DF37DE} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD} - {132BF813-FC40-4D39-8B6F-E55D7633F0ED} = {2E666815-2EDB-464B-9DF6-380BF4789AD4} - {A4DB505A-FFD8-4A7B-B31A-12AD623E7AD9} = {E0983BCC-F93B-4FFF-A4E4-EA874908783F} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5100F629-0FAB-4C6F-9A54-95AE9565EE0D} - EndGlobalSection -EndGlobal diff --git a/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs b/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs deleted file mode 100644 index feca258c46ce2..0000000000000 --- a/src/libraries/System.Net.Connections/ref/System.Net.Connections.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the https://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace System.Net.Connections -{ - public abstract partial class Connection : System.Net.Connections.ConnectionBase - { - protected Connection() { } - public System.IO.Pipelines.IDuplexPipe Pipe { get { throw null; } } - public System.IO.Stream Stream { get { throw null; } } - protected virtual System.IO.Pipelines.IDuplexPipe CreatePipe() { throw null; } - protected virtual System.IO.Stream CreateStream() { throw null; } - public static System.Net.Connections.Connection FromPipe(System.IO.Pipelines.IDuplexPipe pipe, bool leaveOpen = false, System.Net.Connections.IConnectionProperties? properties = null, System.Net.EndPoint? localEndPoint = null, System.Net.EndPoint? remoteEndPoint = null) { throw null; } - public static System.Net.Connections.Connection FromStream(System.IO.Stream stream, bool leaveOpen = false, System.Net.Connections.IConnectionProperties? properties = null, System.Net.EndPoint? localEndPoint = null, System.Net.EndPoint? remoteEndPoint = null) { throw null; } - } - public abstract partial class ConnectionBase : System.IAsyncDisposable, System.IDisposable - { - protected ConnectionBase() { } - public abstract System.Net.Connections.IConnectionProperties ConnectionProperties { get; } - public abstract System.Net.EndPoint? LocalEndPoint { get; } - public abstract System.Net.EndPoint? RemoteEndPoint { get; } - public System.Threading.Tasks.ValueTask CloseAsync(System.Net.Connections.ConnectionCloseMethod method = System.Net.Connections.ConnectionCloseMethod.GracefulShutdown, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - protected abstract System.Threading.Tasks.ValueTask CloseAsyncCore(System.Net.Connections.ConnectionCloseMethod method, System.Threading.CancellationToken cancellationToken); - public void Dispose() { } - public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } - } - public enum ConnectionCloseMethod - { - GracefulShutdown = 0, - Abort = 1, - Immediate = 2, - } - public static partial class ConnectionExtensions - { - public static System.Net.Connections.ConnectionFactory Filter(this System.Net.Connections.ConnectionFactory factory, System.Func> filter) { throw null; } - public static bool TryGet(this System.Net.Connections.IConnectionProperties properties, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out T property) { throw null; } - } - public abstract partial class ConnectionFactory : System.IAsyncDisposable, System.IDisposable - { - protected ConnectionFactory() { } - public abstract System.Threading.Tasks.ValueTask ConnectAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } - protected virtual System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } - } - public abstract partial class ConnectionListener : System.IAsyncDisposable, System.IDisposable - { - protected ConnectionListener() { } - public abstract System.Net.Connections.IConnectionProperties ListenerProperties { get; } - public abstract System.Net.EndPoint? LocalEndPoint { get; } - public abstract System.Threading.Tasks.ValueTask AcceptAsync(System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } - protected virtual System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } - } - public abstract partial class ConnectionListenerFactory : System.IAsyncDisposable, System.IDisposable - { - protected ConnectionListenerFactory() { } - public abstract System.Threading.Tasks.ValueTask ListenAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } - protected virtual System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } - } - public partial interface IConnectionProperties - { - bool TryGet(System.Type propertyKey, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out object? property); - } - public partial class SocketsConnectionFactory : System.Net.Connections.ConnectionFactory - { - public SocketsConnectionFactory(System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } - public SocketsConnectionFactory(System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) { } - public override System.Threading.Tasks.ValueTask ConnectAsync(System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - protected virtual System.Net.Sockets.Socket CreateSocket(System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType, System.Net.EndPoint? endPoint, System.Net.Connections.IConnectionProperties? options) { throw null; } - } -} -namespace System.Net -{ - public enum NetworkError : int - { - Other = 0, - EndPointInUse, - HostNotFound, - TimedOut, - ConnectionRefused, - OperationAborted, - ConnectionAborted, - ConnectionReset, - } - public class NetworkException : System.IO.IOException - { - public NetworkException(NetworkError error, Exception? innerException = null) { } - public NetworkException(string message, NetworkError error, Exception? innerException = null) { } - protected NetworkException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) { } - public NetworkError NetworkError { get { throw null; } } - } -} diff --git a/src/libraries/System.Net.Connections/ref/System.Net.Connections.csproj b/src/libraries/System.Net.Connections/ref/System.Net.Connections.csproj deleted file mode 100644 index fa3a6d8bd7437..0000000000000 --- a/src/libraries/System.Net.Connections/ref/System.Net.Connections.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - $(NetCoreAppCurrent) - enable - - - - - - - - - - - diff --git a/src/libraries/System.Net.Connections/src/Resources/Strings.resx b/src/libraries/System.Net.Connections/src/Resources/Strings.resx deleted file mode 100644 index 004c0da9c8492..0000000000000 --- a/src/libraries/System.Net.Connections/src/Resources/Strings.resx +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - The CreatePipe implementation returned null; a valid reference was expected. - - - The CreateStream implementation returned null; a valid reference was expected. - - - One of CreatePipe or CreateStream must be implemented - - - The Connection's Pipe may not be accessed after Stream has been accessed. - - - The Connection's Stream may not be accessed after Pipe has been accessed. - - - The PipeReader returned a zero-length read. - - \ No newline at end of file diff --git a/src/libraries/System.Net.Connections/src/System.Net.Connections.csproj b/src/libraries/System.Net.Connections/src/System.Net.Connections.csproj deleted file mode 100644 index 055eaef1b57e6..0000000000000 --- a/src/libraries/System.Net.Connections/src/System.Net.Connections.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - $(NetCoreAppCurrent) - enable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/Connection.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/Connection.cs deleted file mode 100644 index f68bac27de6c5..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/Connection.cs +++ /dev/null @@ -1,249 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.IO.Pipelines; -using System.Runtime.ExceptionServices; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - /// - /// A connection. - /// - public abstract class Connection : ConnectionBase - { - private Stream? _stream; - private IDuplexPipe? _pipe; - private bool _initializing; - - /// - /// The connection's . - /// - public Stream Stream => - _stream != null ? _stream : - _pipe != null ? throw new InvalidOperationException(SR.net_connections_stream_use_after_pipe) : - (_stream = CreateStream() ?? throw new InvalidOperationException(SR.net_connections_createstream_null)); - - /// - /// The connection's . - /// - public IDuplexPipe Pipe => - _pipe != null ? _pipe : - _stream != null ? throw new InvalidOperationException(SR.net_connections_pipe_use_after_stream) : - (_pipe = CreatePipe() ?? throw new InvalidOperationException(SR.net_connections_createpipe_null)); - - /// - /// Initializes the for the . - /// - /// A . - /// - /// At least one of and must be overridden. - /// If only is overridden, a user accessing will get a wrapping the . - /// - protected virtual Stream CreateStream() - { - if (_initializing) throw new InvalidOperationException(SR.net_connections_no_create_overrides); - - try - { - _initializing = true; - - IDuplexPipe pipe = CreatePipe(); - if (pipe == null) throw new InvalidOperationException(SR.net_connections_createpipe_null); - - return new DuplexPipeStream(pipe); - } - finally - { - _initializing = false; - } - } - - /// - /// Initializes the for the . - /// - /// An . - /// - /// At least one of and must be overridden. - /// If only is overridden, a user accessing will get a wrapping the . - /// - protected virtual IDuplexPipe CreatePipe() - { - if (_initializing) throw new InvalidOperationException(SR.net_connections_no_create_overrides); - - try - { - _initializing = true; - - Stream stream = CreateStream(); - if (stream == null) throw new InvalidOperationException(SR.net_connections_createstream_null); - - return new DuplexStreamPipe(stream); - } - finally - { - _initializing = false; - } - } - - /// - /// Creates a connection for a . - /// - /// The connection's . - /// If false, the will be disposed of once the connection has been closed. - /// The connection's . - /// The connection's . - /// The connection's . - /// A new . - public static Connection FromStream(Stream stream, bool leaveOpen = false, IConnectionProperties? properties = null, EndPoint? localEndPoint = null, EndPoint? remoteEndPoint = null) - { - if (stream == null) throw new ArgumentNullException(nameof(stream)); - return new ConnectionFromStream(stream, leaveOpen, properties, localEndPoint, remoteEndPoint); - } - - /// - /// Creates a connection for an . - /// - /// The connection's . - /// If false and the implements or , it will be disposed of once the connection has been closed. - /// The connection's . - /// The connection's . - /// The connection's . - /// A new . - public static Connection FromPipe(IDuplexPipe pipe, bool leaveOpen = false, IConnectionProperties? properties = null, EndPoint? localEndPoint = null, EndPoint? remoteEndPoint = null) - { - if (pipe == null) throw new ArgumentNullException(nameof(pipe)); - return new ConnectionFromPipe(pipe, leaveOpen, properties, localEndPoint, remoteEndPoint); - } - - private sealed class ConnectionFromStream : Connection, IConnectionProperties - { - private Stream? _originalStream; - private IConnectionProperties? _properties; - private readonly bool _leaveOpen; - - public override IConnectionProperties ConnectionProperties => _properties ?? this; - - public override EndPoint? LocalEndPoint { get; } - - public override EndPoint? RemoteEndPoint { get; } - - public ConnectionFromStream(Stream stream, bool leaveOpen, IConnectionProperties? properties, EndPoint? localEndPoint, EndPoint? remoteEndPoint) - { - _originalStream = stream; - _leaveOpen = leaveOpen; - _properties = properties; - LocalEndPoint = localEndPoint; - RemoteEndPoint = remoteEndPoint; - } - - protected override Stream CreateStream() => _originalStream ?? throw new ObjectDisposedException(nameof(Connection)); - - protected override async ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) - { - if (_originalStream == null) - { - return; - } - - if (method == ConnectionCloseMethod.GracefulShutdown) - { - await _originalStream.FlushAsync(cancellationToken).ConfigureAwait(false); - } - - if (!_leaveOpen) - { - await _originalStream.DisposeAsync().ConfigureAwait(false); - } - - _originalStream = null; - } - - bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) - { - property = null; - return false; - } - } - - private sealed class ConnectionFromPipe : Connection, IConnectionProperties - { - private IDuplexPipe? _originalPipe; - private IConnectionProperties? _properties; - private readonly bool _leaveOpen; - - public override IConnectionProperties ConnectionProperties => _properties ?? this; - - public override EndPoint? LocalEndPoint { get; } - - public override EndPoint? RemoteEndPoint { get; } - - public ConnectionFromPipe(IDuplexPipe pipe, bool leaveOpen, IConnectionProperties? properties, EndPoint? localEndPoint, EndPoint? remoteEndPoint) - { - _originalPipe = pipe; - _leaveOpen = leaveOpen; - _properties = properties; - LocalEndPoint = localEndPoint; - RemoteEndPoint = remoteEndPoint; - } - - protected override IDuplexPipe CreatePipe() => _originalPipe ?? throw new ObjectDisposedException(nameof(Connection)); - - protected override async ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) - { - if (_originalPipe == null) - { - return; - } - - Exception? inputException, outputException; - - if (method == ConnectionCloseMethod.GracefulShutdown) - { - // Flush happens implicitly from CompleteAsync(null), so only flush here if we need cancellation. - if (cancellationToken.CanBeCanceled) - { - FlushResult r = await _originalPipe.Output.FlushAsync(cancellationToken).ConfigureAwait(false); - if (r.IsCanceled) cancellationToken.ThrowIfCancellationRequested(); - } - - inputException = null; - outputException = null; - } - else - { - inputException = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection))); - outputException = ExceptionDispatchInfo.SetCurrentStackTrace(new ObjectDisposedException(nameof(Connection))); - } - - await _originalPipe.Input.CompleteAsync(inputException).ConfigureAwait(false); - await _originalPipe.Output.CompleteAsync(outputException).ConfigureAwait(false); - - if (!_leaveOpen) - { - switch (_originalPipe) - { - case IAsyncDisposable d: - await d.DisposeAsync().ConfigureAwait(false); - break; - case IDisposable d: - d.Dispose(); - break; - } - } - - _originalPipe = null; - } - - bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) - { - property = null; - return false; - } - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionBase.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionBase.cs deleted file mode 100644 index 027431babe2a8..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionBase.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - /// - /// Provides base functionality shared between singular (e.g. TCP) and multiplexed (e.g. QUIC) connections. - /// - public abstract class ConnectionBase : IDisposable, IAsyncDisposable - { - private bool _disposed; - - /// - /// Properties exposed by this connection. - /// - public abstract IConnectionProperties ConnectionProperties { get; } - - /// - /// The local endpoint of this connection, if any. - /// - public abstract EndPoint? LocalEndPoint { get; } - - /// - /// The remote endpoint of this connection, if any. - /// - public abstract EndPoint? RemoteEndPoint { get; } - - /// - /// Closes the connection. - /// - /// The method to use when closing the connection. - /// A cancellation token for the asynchronous operation. - /// A for the asynchronous operation. - public async ValueTask CloseAsync(ConnectionCloseMethod method = ConnectionCloseMethod.GracefulShutdown, CancellationToken cancellationToken = default) - { - if (!_disposed) - { - await CloseAsyncCore(method, cancellationToken).ConfigureAwait(false); - _disposed = true; - } - GC.SuppressFinalize(this); - } - - /// - /// Closes the connection. - /// - /// The method to use when closing the connection. - /// A cancellation token for the asynchronous operation. - /// A for the asynchronous operation. - protected abstract ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken); - - /// - /// Disposes of the connection. - /// - /// - /// This is equivalent to calling with the method , and calling GetAwaiter().GetResult() on the resulting task. - /// To increase likelihood of synchronous completion, call directly with the method . - /// - public void Dispose() - { - ValueTask t = CloseAsync(ConnectionCloseMethod.GracefulShutdown, CancellationToken.None); - - if (t.IsCompleted) t.GetAwaiter().GetResult(); - else t.AsTask().GetAwaiter().GetResult(); - } - - /// - /// Disposes of the connection. - /// - /// A for the asynchronous operation. - /// This is equivalent to calling with the method . - public ValueTask DisposeAsync() - { - return CloseAsync(ConnectionCloseMethod.GracefulShutdown, CancellationToken.None); - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionCloseMethod.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionCloseMethod.cs deleted file mode 100644 index 6b5a0792f4a46..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionCloseMethod.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Net.Connections -{ - /// - /// Methods for closing a connection. - /// - public enum ConnectionCloseMethod - { - /// - /// The connection should be flushed and closed. - /// - GracefulShutdown, - - /// - /// The connection should be aborted gracefully, performing any I/O needed to notify the other side of the connection that it has been aborted. - /// - Abort, - - /// - /// The connection should be aborted immediately, avoiding any I/O needed to notify the other side of the connection that it has been aborted. - /// - Immediate - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionExtensions.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionExtensions.cs deleted file mode 100644 index 6850247f36067..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionExtensions.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - /// - /// Extension methods for working with the System.Net.Connections types. - /// - public static class ConnectionExtensions - { - /// - /// Retrieves a Type-based property from an , if it exists. - /// - /// The type of the property to retrieve. - /// The connection properties to retrieve a property from. - /// If contains a property of type , receives the property. Otherwise, default. - /// If contains a property of type , true. Otherwise, false. - public static bool TryGet(this IConnectionProperties properties, [MaybeNullWhen(false)] out T property) - { - if (properties == null) throw new ArgumentNullException(nameof(properties)); - - if (properties.TryGet(typeof(T), out object? obj) && obj is T propertyValue) - { - property = propertyValue; - return true; - } - else - { - property = default; - return false; - } - } - - /// - /// Creates a connection-level filter on top of a . - /// - /// The factory to be filtered. - /// The connection-level filter to apply on top of . - /// A new filtered . - public static ConnectionFactory Filter(this ConnectionFactory factory, Func> filter) - { - if (factory == null) throw new ArgumentNullException(nameof(factory)); - if (filter == null) throw new ArgumentNullException(nameof(filter)); - return new ConnectionFilteringFactory(factory, filter); - } - - private sealed class ConnectionFilteringFactory : ConnectionFactory - { - private readonly ConnectionFactory _baseFactory; - private readonly Func> _filter; - - public ConnectionFilteringFactory(ConnectionFactory baseFactory, Func> filter) - { - _baseFactory = baseFactory; - _filter = filter; - } - - public override async ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default) - { - Connection con = await _baseFactory.ConnectAsync(endPoint, options, cancellationToken).ConfigureAwait(false); - try - { - return await _filter(con, options, cancellationToken).ConfigureAwait(false); - } - catch - { - await con.CloseAsync(ConnectionCloseMethod.Abort, cancellationToken).ConfigureAwait(false); - throw; - } - } - - protected override void Dispose(bool disposing) - { - if (disposing) _baseFactory.Dispose(); - } - - protected override ValueTask DisposeAsyncCore() - { - return _baseFactory.DisposeAsync(); - } - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionFactory.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionFactory.cs deleted file mode 100644 index 812f78a6ae6ed..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionFactory.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - /// - /// A factory for opening outgoing connections. - /// - public abstract class ConnectionFactory : IAsyncDisposable, IDisposable - { - /// - /// Opens a new . - /// - /// The to connect to, if any. - /// Options used to create the connection, if any. - /// A token used to cancel the asynchronous operation. - /// A for the . - public abstract ValueTask ConnectAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default); - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public async ValueTask DisposeAsync() - { - await DisposeAsyncCore().ConfigureAwait(false); - GC.SuppressFinalize(this); - } - - /// - /// Disposes the . - /// - /// If true, the is being disposed. If false, the is being finalized. - protected virtual void Dispose(bool disposing) - { - } - - /// - /// Asynchronously disposes the . - /// - /// A representing the asynchronous dispose operation. - protected virtual ValueTask DisposeAsyncCore() - { - Dispose(true); - return default; - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListener.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListener.cs deleted file mode 100644 index e01b92a9dc5f0..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListener.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - /// - /// A listener to accept incoming connections. - /// - public abstract class ConnectionListener : IAsyncDisposable, IDisposable - { - /// - /// Properties exposed by this listener. - /// - public abstract IConnectionProperties ListenerProperties { get; } - - /// - /// The local endpoint of this connection, if any. - /// - public abstract EndPoint? LocalEndPoint { get; } - - /// - /// Accepts an incoming connection. - /// - /// Options used to create the connection, if any. - /// A token used to cancel the asynchronous operation. - /// A for the . - public abstract ValueTask AcceptAsync(IConnectionProperties? options = null, CancellationToken cancellationToken = default); - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public async ValueTask DisposeAsync() - { - await DisposeAsyncCore().ConfigureAwait(false); - GC.SuppressFinalize(this); - } - - /// - /// Disposes the . - /// - /// If true, the is being disposed. If false, the is being finalized. - protected virtual void Dispose(bool disposing) - { - } - - /// - /// Asynchronously disposes the . - /// - /// A representing the asynchronous dispose operation. - protected virtual ValueTask DisposeAsyncCore() - { - Dispose(true); - return default; - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs deleted file mode 100644 index 7e6339d9d6778..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/ConnectionListenerFactory.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - /// - /// A factory for creating connection listeners, to accept incoming connections. - /// - public abstract class ConnectionListenerFactory : IAsyncDisposable, IDisposable - { - public abstract ValueTask ListenAsync(EndPoint? endPoint, IConnectionProperties? options = null, CancellationToken cancellationToken = default); - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public async ValueTask DisposeAsync() - { - await DisposeAsyncCore().ConfigureAwait(false); - GC.SuppressFinalize(this); - } - - /// - /// Disposes the . - /// - /// If true, the is being disposed. If false, the is being finalized. - protected virtual void Dispose(bool disposing) - { - } - - /// - /// Asynchronously disposes the . - /// - /// A representing the asynchronous dispose operation. - protected virtual ValueTask DisposeAsyncCore() - { - Dispose(true); - return default; - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexPipeStream.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexPipeStream.cs deleted file mode 100644 index 3319c972b5828..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexPipeStream.cs +++ /dev/null @@ -1,166 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Buffers; -using System.IO; -using System.IO.Pipelines; -using System.Runtime.ExceptionServices; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - internal sealed class DuplexPipeStream : Stream - { - private readonly PipeReader _reader; - private readonly PipeWriter _writer; - - public override bool CanRead => true; - public override bool CanSeek => false; - public override bool CanWrite => true; - public override long Length => throw new NotSupportedException(); - public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } - - public DuplexPipeStream(IDuplexPipe pipe) - { - _reader = pipe.Input; - _writer = pipe.Output; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _reader.Complete(); - _writer.Complete(); - } - base.Dispose(disposing); - } - - public override async ValueTask DisposeAsync() - { - await _reader.CompleteAsync().ConfigureAwait(false); - await _writer.CompleteAsync().ConfigureAwait(false); - } - - public override void Flush() - { - FlushAsync().GetAwaiter().GetResult(); - } - - public override async Task FlushAsync(CancellationToken cancellationToken) - { - FlushResult r = await _writer.FlushAsync(cancellationToken).ConfigureAwait(false); - if (r.IsCanceled) throw new OperationCanceledException(cancellationToken); - } - - public override int Read(byte[] buffer, int offset, int count) - { - if (buffer == null) throw new ArgumentNullException(nameof(buffer)); - - ValueTask t = ReadAsync(buffer.AsMemory(offset, count)); - return - t.IsCompleted ? t.GetAwaiter().GetResult() : - t.AsTask().GetAwaiter().GetResult(); - } - - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - if (buffer == null) return Task.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new ArgumentNullException(nameof(buffer)))); - return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); - } - - public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) - { - ReadResult result = await _reader.ReadAsync(cancellationToken).ConfigureAwait(false); - - if (result.IsCanceled) - { - throw new OperationCanceledException(); - } - - ReadOnlySequence sequence = result.Buffer; - long bufferLength = sequence.Length; - SequencePosition consumed = sequence.Start; - - try - { - if (bufferLength != 0) - { - int actual = (int)Math.Min(bufferLength, buffer.Length); - - ReadOnlySequence slice = actual == bufferLength ? sequence : sequence.Slice(0, actual); - consumed = slice.End; - slice.CopyTo(buffer.Span); - - return actual; - } - - if (result.IsCompleted) - { - return 0; - } - } - finally - { - _reader.AdvanceTo(consumed); - } - - // This is a buggy PipeReader implementation that returns 0 byte reads even though the PipeReader - // isn't completed or canceled. - throw new InvalidOperationException(SR.net_connections_zero_byte_pipe_read); - } - - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) - { - return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); - } - - public override int EndRead(IAsyncResult asyncResult) - { - return TaskToApm.End(asyncResult); - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); - } - - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); - } - - public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) - { - FlushResult r = await _writer.WriteAsync(buffer, cancellationToken).ConfigureAwait(false); - if (r.IsCanceled) throw new OperationCanceledException(cancellationToken); - } - - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) - { - return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); - } - - public override void EndWrite(IAsyncResult asyncResult) - { - TaskToApm.End(asyncResult); - } - - public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) - { - return _reader.CopyToAsync(destination, cancellationToken); - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexStreamPipe.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexStreamPipe.cs deleted file mode 100644 index 7b620c2b8bf15..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/DuplexStreamPipe.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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; } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/IConnectionProperties.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/IConnectionProperties.cs deleted file mode 100644 index ce89dd97a216b..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/IConnectionProperties.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; - -namespace System.Net.Connections -{ - /// - /// A container for connection properties. - /// - public interface IConnectionProperties - { - /// - /// Retrieves a connection property, if it exists. - /// - /// The key of the property to retrieve. - /// If the property was found, retrieves the property. Otherwise, null. - /// If the property was found, true. Otherwise, false. - bool TryGet(Type propertyKey, [NotNullWhen(true)] out object? property); - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/Sockets/SocketConnection.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/Sockets/SocketConnection.cs deleted file mode 100644 index 2eb3e6bca9063..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/Sockets/SocketConnection.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.IO.Pipelines; -using System.Net.Sockets; -using System.Runtime.ExceptionServices; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections -{ - internal sealed class SocketConnection : Connection, IConnectionProperties - { - private readonly Socket _socket; - private Stream? _stream; - - public override EndPoint? RemoteEndPoint => _socket.RemoteEndPoint; - public override EndPoint? LocalEndPoint => _socket.LocalEndPoint; - public override IConnectionProperties ConnectionProperties => this; - - public SocketConnection(Socket socket) - { - _socket = socket; - } - - protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - { - return ValueTask.FromCanceled(cancellationToken); - } - - try - { - if (method != ConnectionCloseMethod.GracefulShutdown) - { - // Dispose must be called first in order to cause a connection reset, - // as NetworkStream.Dispose() will call Shutdown(Both). - _socket.Dispose(); - } - - // Since CreatePipe() calls CreateStream(), so _stream should be present even in the pipe case: - _stream?.Dispose(); - } - catch (SocketException socketException) - { - return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(NetworkErrorHelper.MapSocketException(socketException))); - } - catch (Exception ex) - { - return ValueTask.FromException(ex); - } - - return default; - } - - bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property) - { - if (propertyKey == typeof(Socket)) - { - property = _socket; - return true; - } - - property = null; - return false; - } - - protected override Stream CreateStream() => _stream ??= new NetworkStream(_socket, true); - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/Connections/Sockets/SocketsConnectionFactory.cs b/src/libraries/System.Net.Connections/src/System/Net/Connections/Sockets/SocketsConnectionFactory.cs deleted file mode 100644 index 732ad9447828a..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/Connections/Sockets/SocketsConnectionFactory.cs +++ /dev/null @@ -1,117 +0,0 @@ -// 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 -{ - /// - /// A to establish socket-based connections. - /// - /// - /// When constructed with , this factory will create connections with enabled. - /// In case of IPv6 sockets is also enabled. - /// - public class SocketsConnectionFactory : ConnectionFactory - { - private readonly AddressFamily _addressFamily; - private readonly SocketType _socketType; - private readonly ProtocolType _protocolType; - - /// - /// Initializes a new instance of the class. - /// - /// The to forward to the socket. - /// The to forward to the socket. - /// The to forward to the socket. - public SocketsConnectionFactory( - AddressFamily addressFamily, - SocketType socketType, - ProtocolType protocolType) - { - _addressFamily = addressFamily; - _socketType = socketType; - _protocolType = protocolType; - } - - /// - /// Initializes a new instance of the class - /// that will forward to the Socket constructor. - /// - /// The to forward to the socket. - /// The to forward to the socket. - /// The created socket will be an IPv6 socket with enabled. - public SocketsConnectionFactory(SocketType socketType, ProtocolType protocolType) - : this(AddressFamily.InterNetworkV6, socketType, protocolType) - { - } - - /// - /// When is . - public override async ValueTask 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 - { - await socket.ConnectAsync(endPoint, cancellationToken).ConfigureAwait(false); - return new SocketConnection(socket); - } - catch (SocketException socketException) - { - socket.Dispose(); - throw NetworkErrorHelper.MapSocketException(socketException); - } - catch - { - socket.Dispose(); - throw; - } - } - - /// - /// Creates the socket that shall be used with the connection. - /// - /// The to forward to the socket. - /// The to forward to the socket. - /// The to forward to the socket. - /// The this socket will be connected to. - /// Properties, if any, that might change how the socket is initialized. - /// A new unconnected . - /// - /// In case of TCP sockets, the default implementation of this method will create a socket with enabled. - /// In case of IPv6 sockets is also be enabled. - /// - 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; - } - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/NetworkError.cs b/src/libraries/System.Net.Connections/src/System/Net/NetworkError.cs deleted file mode 100644 index 5d1099a3c044e..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/NetworkError.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Net -{ - /// Defines a set of error codes for use with . - public enum NetworkError : int - { - /// A network error has occurred. - /// - /// This value indicates a non-generic, implementation-specific error. - /// Details could be obtained from 's inner exception. - /// - Other = 0, - - /// The requested EndPoint is already in use. - EndPointInUse, - - /// No such host is known. - HostNotFound, - - /// The connection attempt has timed out. - TimedOut, - - /// No connection could be made because the remote host actively refused it. - ConnectionRefused, - - /// The operation was aborted by the user. - OperationAborted, - - /// The connection was aborted by the local host. - ConnectionAborted, - - /// The connection was forcibly closed by the remote host. - ConnectionReset, - } -} diff --git a/src/libraries/System.Net.Connections/src/System/Net/NetworkException.cs b/src/libraries/System.Net.Connections/src/System/Net/NetworkException.cs deleted file mode 100644 index ef99bd835c3a5..0000000000000 --- a/src/libraries/System.Net.Connections/src/System/Net/NetworkException.cs +++ /dev/null @@ -1,44 +0,0 @@ -// 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.Runtime.Serialization; - -namespace System.Net -{ - /// Provides socket exceptions to the application. - [Serializable] - public class NetworkException : IOException - { - /// Creates a new instance of the class with the specified error code. - public NetworkException(NetworkError error, Exception? innerException = null) - : this(GetExceptionMessage(error), error, innerException) {} - - /// Creates a new instance of the class with the specified error code and message. - public NetworkException(string message, NetworkError error, Exception? innerException = null) - : base(message, innerException) - { - NetworkError = error; - } - - /// Creates a new instance of the from serialized data. - protected NetworkException(SerializationInfo serializationInfo, StreamingContext streamingContext) - : base(serializationInfo, streamingContext) - { - NetworkError = (NetworkError)serializationInfo.GetInt32("NetworkError"); - } - - /// Populates the serialization data for this object. - public override void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext) - { - base.GetObjectData(serializationInfo, streamingContext); - serializationInfo.AddValue("NetworkError", (int)NetworkError); - } - - /// Returns the specific kind of error. - public NetworkError NetworkError { get; } - - // TODO: Better exception messages - private static string GetExceptionMessage(NetworkError error) => $"A network error occurred: {error}"; - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionBaseTest.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionBaseTest.cs deleted file mode 100644 index 66cc4a2352bc6..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionBaseTest.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading.Tasks; -using Xunit; - -namespace System.Net.Connections.Tests -{ - public class ConnectionBaseTest - { - [Fact] - public void Dispose_CallsClose_Success() - { - ConnectionCloseMethod? method = null; - - var con = new MockConnection(); - con.OnCloseAsyncCore = (m, t) => - { - method = m; - return default(ValueTask); - }; - - con.Dispose(); - - Assert.Equal(ConnectionCloseMethod.GracefulShutdown, method); - } - - [Fact] - public async Task DisposeAsync_CallsClose_Success() - { - ConnectionCloseMethod? method = null; - - var con = new MockConnection(); - con.OnCloseAsyncCore = (m, t) => - { - method = m; - return default(ValueTask); - }; - - await con.DisposeAsync(); - - Assert.Equal(ConnectionCloseMethod.GracefulShutdown, method); - } - - [Fact] - public void Dispose_CalledOnce_Success() - { - int callCount = 0; - - var con = new MockConnection(); - con.OnCloseAsyncCore = delegate - { - ++callCount; - return default(ValueTask); - }; - - con.Dispose(); - con.Dispose(); - - Assert.Equal(1, callCount); - } - - [Fact] - public async Task DisposeAsync_CalledOnce_Success() - { - int callCount = 0; - - var con = new MockConnection(); - con.OnCloseAsyncCore = delegate - { - ++callCount; - return default(ValueTask); - }; - - await con.DisposeAsync(); - await con.DisposeAsync(); - - Assert.Equal(1, callCount); - } - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionTest.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionTest.cs deleted file mode 100644 index ad16e45fc6cf3..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionTest.cs +++ /dev/null @@ -1,264 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Buffers; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.IO.Pipelines; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace System.Net.Connections.Tests -{ - public class ConnectionTest - { - [Fact] - public void CreateStream_CalledOnce_Success() - { - int callCount = 0; - - var con = new MockConnection(); - con.OnCreateStream = () => - { - ++callCount; - return new MemoryStream(); - }; - - _ = con.Stream; - _ = con.Stream; - - Assert.Equal(1, callCount); - } - - [Fact] - public void CreatePipe_CalledOnce_Success() - { - int callCount = 0; - - var con = new MockConnection(); - con.OnCreatePipe = () => - { - ++callCount; - return new MockPipe(); - }; - - _ = con.Pipe; - _ = con.Pipe; - - Assert.Equal(1, callCount); - } - - [Fact] - public void AccessStream_AccessPipe_Fail() - { - var con = new MockConnection(); - con.OnCreateStream = () => new MemoryStream(); - - _ = con.Stream; - Assert.Throws(() => _ = con.Pipe); - } - - [Fact] - public void AccessPipe_AccessStream_Fail() - { - var con = new MockConnection(); - con.OnCreatePipe = () => new MockPipe(); - - _ = con.Pipe; - Assert.Throws(() => _ = con.Stream); - } - - [Fact] - public void AccessStream_NoOverloads_Fail() - { - var con = new ConnectionWithoutStreamOrPipe(); - Assert.Throws(() => _ = con.Stream); - } - - [Fact] - public void AccessPipe_NoOverloads_Fail() - { - var con = new ConnectionWithoutStreamOrPipe(); - Assert.Throws(() => _ = con.Pipe); - } - - [Fact] - public async Task WrappedStream_Success() - { - var bytesA = Encoding.ASCII.GetBytes("foo"); - var bytesB = Encoding.ASCII.GetBytes("bar"); - - var stream = new MemoryStream(); - stream.Write(bytesA); - stream.Position = 0; - - var con = new MockConnection(); - con.OnCreateStream = () => stream; - - IDuplexPipe pipe = con.Pipe; - - ReadResult res = await pipe.Input.ReadAsync(); - Assert.Equal(bytesA, res.Buffer.ToArray()); - - await pipe.Output.WriteAsync(bytesB); - Assert.Equal(bytesA.Concat(bytesB).ToArray(), stream.ToArray()); - } - - [Fact] - public async Task WrappedPipe_Success() - { - var bytesA = Encoding.ASCII.GetBytes("foo"); - var bytesB = Encoding.ASCII.GetBytes("bar"); - - var stream = new MemoryStream(); - stream.Write(bytesA); - stream.Position = 0; - - var pipe = new MockPipe - { - Input = PipeReader.Create(stream), - Output = PipeWriter.Create(stream) - }; - - var con = new MockConnection(); - con.OnCreatePipe = () => pipe; - - Stream s = con.Stream; - - var readBuffer = new byte[4]; - int len = await s.ReadAsync(readBuffer); - Assert.Equal(3, len); - Assert.Equal(bytesA, readBuffer.AsSpan(0, len).ToArray()); - - await s.WriteAsync(bytesB); - Assert.Equal(bytesA.Concat(bytesB).ToArray(), stream.ToArray()); - } - - [Theory] - [InlineData(ConnectionCloseMethod.GracefulShutdown, true)] - [InlineData(ConnectionCloseMethod.Abort, false)] - [InlineData(ConnectionCloseMethod.Immediate, false)] - public async Task FromStream_CloseMethod_Flushed(ConnectionCloseMethod method, bool shouldFlush) - { - bool streamFlushed = false; - - var stream = new MockStream - { - OnFlushAsync = _ => { streamFlushed = true; return Task.CompletedTask; } - }; - - var con = Connection.FromStream(stream, leaveOpen: true); - - await con.CloseAsync(method); - Assert.Equal(shouldFlush, streamFlushed); - } - - [Theory] - [InlineData(ConnectionCloseMethod.GracefulShutdown, true)] - [InlineData(ConnectionCloseMethod.Abort, false)] - [InlineData(ConnectionCloseMethod.Immediate, false)] - public async Task FromPipe_CloseMethod_Flushed(ConnectionCloseMethod method, bool shouldFlush) - { - bool pipeFlushed = false; - - var pipe = new MockPipe - { - Input = new MockPipeReader() - { - OnCompleteAsync = _ => default - }, - Output = new MockPipeWriter() - { - OnFlushAsync = _ => { pipeFlushed = true; return default; }, - OnCompleteAsync = _ => default - } - }; - - var con = Connection.FromPipe(pipe); - - await con.CloseAsync(method, new CancellationTokenSource().Token); - Assert.Equal(shouldFlush, pipeFlushed); - } - - [Theory] - [InlineData(true, false)] - [InlineData(false, true)] - public async Task FromStream_LeaveOpen_StreamDisposed(bool leaveOpen, bool shouldDispose) - { - bool streamDisposed = false; - - var stream = new MockStream(); - stream.OnDisposeAsync = delegate { streamDisposed = true; return default; }; - - var con = Connection.FromStream(stream, leaveOpen); - - await con.CloseAsync(ConnectionCloseMethod.Immediate); - Assert.Equal(shouldDispose, streamDisposed); - } - - [Theory] - [InlineData(true, false)] - [InlineData(false, true)] - public async Task FromPipe_LeaveOpen_PipeDisposed(bool leaveOpen, bool shouldDispose) - { - bool pipeDisposed = false; - - var pipe = new MockPipe - { - OnDisposeAsync = () => { pipeDisposed = true; return default; }, - Input = new MockPipeReader() - { - OnCompleteAsync = _ => default - }, - Output = new MockPipeWriter() - { - OnFlushAsync = _ => default, - OnCompleteAsync = _ => default - } - }; - - var con = Connection.FromPipe(pipe, leaveOpen); - - await con.CloseAsync(ConnectionCloseMethod.Immediate); - Assert.Equal(shouldDispose, pipeDisposed); - } - - [Fact] - public void FromStream_PropertiesInitialized() - { - var properties = new DummyConnectionProperties(); - var localEndPoint = new IPEndPoint(IPAddress.Any, 1); - var remoteEndPoint = new IPEndPoint(IPAddress.Any, 2); - - Connection c = Connection.FromStream(new MockStream(), leaveOpen: false, properties, localEndPoint, remoteEndPoint); - Assert.Same(properties, c.ConnectionProperties); - Assert.Same(localEndPoint, c.LocalEndPoint); - Assert.Same(remoteEndPoint, c.RemoteEndPoint); - } - - [Fact] - public void FromPipe_PropertiesInitialized() - { - var properties = new DummyConnectionProperties(); - var localEndPoint = new IPEndPoint(IPAddress.Any, 1); - var remoteEndPoint = new IPEndPoint(IPAddress.Any, 2); - - Connection c = Connection.FromPipe(new MockPipe(), leaveOpen: false, properties, localEndPoint, remoteEndPoint); - Assert.Same(properties, c.ConnectionProperties); - Assert.Same(localEndPoint, c.LocalEndPoint); - Assert.Same(remoteEndPoint, c.RemoteEndPoint); - } - - private sealed class DummyConnectionProperties : IConnectionProperties - { - public bool TryGet(Type propertyKey, [NotNullWhen(true)] out object property) - { - throw new NotImplementedException(); - } - } - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionWithoutStreamOrPipe.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionWithoutStreamOrPipe.cs deleted file mode 100644 index 16e52387b1d6a..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/ConnectionWithoutStreamOrPipe.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections.Tests -{ - internal class ConnectionWithoutStreamOrPipe : Connection - { - public override IConnectionProperties ConnectionProperties => throw new NotImplementedException(); - - public override EndPoint LocalEndPoint => throw new NotImplementedException(); - - public override EndPoint RemoteEndPoint => throw new NotImplementedException(); - - protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockConnection.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockConnection.cs deleted file mode 100644 index f1acf758fef8b..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockConnection.cs +++ /dev/null @@ -1,33 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections.Tests -{ - internal class MockConnection : Connection - { - public Func OnConnectionProperties { get; set; } - public Func OnLocalEndPoint { get; set; } - public Func OnRemoteEndPoint { get; set; } - public Func OnCloseAsyncCore { get; set; } - public Func OnCreatePipe { get; set; } - public Func OnCreateStream { get; set; } - - public override IConnectionProperties ConnectionProperties => OnConnectionProperties(); - - public override EndPoint LocalEndPoint => OnLocalEndPoint(); - - public override EndPoint RemoteEndPoint => OnRemoteEndPoint(); - - protected override ValueTask CloseAsyncCore(ConnectionCloseMethod method, CancellationToken cancellationToken) => - OnCloseAsyncCore(method, cancellationToken); - - protected override IDuplexPipe CreatePipe() => OnCreatePipe != null ? OnCreatePipe() : base.CreatePipe(); - - protected override Stream CreateStream() => OnCreateStream != null ? OnCreateStream() : base.CreateStream(); - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipe.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipe.cs deleted file mode 100644 index 6abbb9a7cc622..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipe.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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.Pipelines; -using System.Threading.Tasks; - -namespace System.Net.Connections.Tests -{ - internal class MockPipe : IDuplexPipe, IAsyncDisposable - { - public Func OnDisposeAsync { get; set; } - public PipeReader Input { get; set; } - - public PipeWriter Output { get; set; } - - public ValueTask DisposeAsync() - { - return OnDisposeAsync?.Invoke() ?? default; - } - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeReader.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeReader.cs deleted file mode 100644 index 2413bf10a77df..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeReader.cs +++ /dev/null @@ -1,44 +0,0 @@ -// 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.Pipelines; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections.Tests -{ - internal class MockPipeReader : PipeReader - { - public Action OnAdvanceTo { get; set; } - public Action OnCancelPendingRead { get; set; } - public Action OnComplete { get; set; } - public Func OnCompleteAsync { get; set; } - public Func> OnReadAsync { get; set; } - public Func OnTryRead { get; set; } - - public override void AdvanceTo(SequencePosition consumed) - => OnAdvanceTo(consumed, consumed); - - public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) - => OnAdvanceTo(consumed, examined); - - public override void CancelPendingRead() - => OnCancelPendingRead(); - - public override void Complete(Exception exception = null) - => OnComplete(exception); - - public override ValueTask ReadAsync(CancellationToken cancellationToken = default) - => OnReadAsync(cancellationToken); - - public override bool TryRead(out ReadResult result) - { - ReadResult? r = OnTryRead(); - result = r.GetValueOrDefault(); - return r.HasValue; - } - - public override ValueTask CompleteAsync(Exception exception = null) - => OnCompleteAsync(exception); - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeWriter.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeWriter.cs deleted file mode 100644 index 7c35e19a0ae51..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockPipeWriter.cs +++ /dev/null @@ -1,40 +0,0 @@ -// 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.Pipelines; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections.Tests -{ - internal class MockPipeWriter : PipeWriter - { - public Action OnAdvance { get; set; } - public Action OnCancelPendingFlush { get; set; } - public Action OnComplete { get; set; } - public Func OnCompleteAsync { get; set; } - public Func> OnFlushAsync { get; set; } - public Func> OnGetMemory { get; set; } - - public override void Advance(int bytes) - => OnAdvance(bytes); - - public override void CancelPendingFlush() - => OnCancelPendingFlush(); - - public override void Complete(Exception exception = null) - => OnComplete(exception); - - public override ValueTask CompleteAsync(Exception exception = null) - => OnCompleteAsync(exception); - - public override ValueTask FlushAsync(CancellationToken cancellationToken = default) - => OnFlushAsync(cancellationToken); - - public override Memory GetMemory(int sizeHint = 0) - => OnGetMemory(sizeHint); - - public override Span GetSpan(int sizeHint = 0) - => GetMemory(sizeHint).Span; - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockStream.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockStream.cs deleted file mode 100644 index 50dbc31ab11c7..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/MockStream.cs +++ /dev/null @@ -1,107 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; - -namespace System.Net.Connections.Tests -{ - internal class MockStream : Stream - { - public Func, CancellationToken, ValueTask> OnReadAsync { get; set; } - public Func, CancellationToken, ValueTask> OnWriteAsync { get; set; } - public Func OnFlushAsync { get; set; } - public Func OnDisposeAsync { get; set; } - - public override bool CanRead => true; - - public override bool CanSeek => false; - - public override bool CanWrite => true; - - public override long Length => throw new NotImplementedException(); - - public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - protected override void Dispose(bool disposing) - { - if (disposing) DisposeAsync().AsTask().GetAwaiter().GetResult(); - } - - public override ValueTask DisposeAsync() - { - return OnDisposeAsync(); - } - - public override void Flush() - { - FlushAsync().GetAwaiter().GetResult(); - } - - public override Task FlushAsync(CancellationToken cancellationToken) - { - return OnFlushAsync(cancellationToken); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return ReadAsync(buffer, offset, count).GetAwaiter().GetResult(); - } - - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); - } - - public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) - { - return OnReadAsync(buffer, cancellationToken); - } - - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); - } - - public override int EndRead(IAsyncResult asyncResult) - { - return TaskToApm.End(asyncResult); - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotImplementedException(); - } - - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - WriteAsync(buffer, offset, count).GetAwaiter().GetResult(); - } - - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); - } - - public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) - { - return OnWriteAsync(buffer, cancellationToken); - } - - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); - } - - public override void EndWrite(IAsyncResult asyncResult) - { - TaskToApm.End(asyncResult); - } - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/Sockets/SocketsConnectionFactoryTests.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/Sockets/SocketsConnectionFactoryTests.cs deleted file mode 100644 index 683f1b970eb91..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/Sockets/SocketsConnectionFactoryTests.cs +++ /dev/null @@ -1,400 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Buffers; -using System.Collections.Concurrent; -using System.IO; -using System.IO.Pipelines; -using System.Net.Connections; -using System.Net.Sockets; -using System.Net.Sockets.Tests; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace System.Net.Connections.Tests -{ - [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime))] - public class SocketsConnectionFactoryTests - { - public static TheoryData GetConnectData() - { - var result = new TheoryData() - { - { new IPEndPoint(IPAddress.Loopback, 0), SocketType.Stream, ProtocolType.Tcp }, - { new IPEndPoint(IPAddress.IPv6Loopback, 0), SocketType.Stream, ProtocolType.Tcp }, - }; - - if (Socket.OSSupportsUnixDomainSockets) - { - result.Add(new UnixDomainSocketEndPoint("/replaced/in/test"), SocketType.Stream, ProtocolType.Unspecified); - } - - return result; - } - - // to avoid random names in TheoryData, we replace the path in test code: - private static EndPoint RecreateUdsEndpoint(EndPoint endPoint) - { - if (endPoint is UnixDomainSocketEndPoint) - { - endPoint = new UnixDomainSocketEndPoint($"{Path.GetTempPath()}/{Guid.NewGuid()}"); - } - return endPoint; - } - - private static Socket ValidateSocket(Connection connection, SocketType? socketType = null, ProtocolType? protocolType = null, AddressFamily? addressFamily = null) - { - Assert.True(connection.ConnectionProperties.TryGet(out Socket socket)); - Assert.True(socket.Connected); - if (addressFamily != null) Assert.Equal(addressFamily, socket.AddressFamily); - if (socketType != null) Assert.Equal(socketType, socket.SocketType); - if (protocolType != null) Assert.Equal(protocolType, socket.ProtocolType); - return socket; - } - - [Theory] - [MemberData(nameof(GetConnectData))] - public async Task Constructor3_ConnectAsync_Success_PropagatesConstructorArgumentsToSocket(EndPoint endPoint, SocketType socketType, ProtocolType protocolType) - { - endPoint = RecreateUdsEndpoint(endPoint); - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, endPoint, protocolType); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(endPoint.AddressFamily, socketType, protocolType); - using Connection connection = await factory.ConnectAsync(server.EndPoint); - - ValidateSocket(connection, socketType, protocolType, endPoint.AddressFamily); - } - - [Fact] - public async Task Constructor2_ConnectAsync_Success_CreatesIPv6DualModeSocket() - { - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.IPv6Loopback); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp); - using Connection connection = await factory.ConnectAsync(server.EndPoint); - - Socket socket = ValidateSocket(connection, SocketType.Stream, ProtocolType.Tcp, AddressFamily.InterNetworkV6); - Assert.True(socket.DualMode); - } - - [Fact] - public async Task ConnectAsync_Success_SocketNoDelayIsTrue() - { - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp); - using Connection connection = await factory.ConnectAsync(server.EndPoint); - - connection.ConnectionProperties.TryGet(out Socket socket); - Assert.True(socket.NoDelay); - } - - [Fact] - public void ConnectAsync_NullEndpoint_ThrowsArgumentNullException() - { - using SocketsConnectionFactory factory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp); - Assert.ThrowsAsync(() => factory.ConnectAsync(null).AsTask()); - } - - // TODO: On OSX and Windows7 connection failures seem to fail with unexpected SocketErrors that are mapped to NetworkError.Unknown. This needs an investigation. - // Related: https://github.com/dotnet/runtime/pull/40565 - public static bool PlatformHasReliableConnectionFailures => !PlatformDetection.IsOSX && !PlatformDetection.IsWindows7 && !PlatformDetection.IsFreeBSD; - - [ConditionalFact(nameof(PlatformHasReliableConnectionFailures))] - public async Task ConnectAsync_WhenRefused_ThrowsNetworkException() - { - using Socket notListening = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - int port = notListening.BindToAnonymousPort(IPAddress.Loopback); - var endPoint = new IPEndPoint(IPAddress.Loopback, port); - - using SocketsConnectionFactory factory = new SocketsConnectionFactory(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - NetworkException ex = await Assert.ThrowsAsync(() => factory.ConnectAsync(endPoint).AsTask()); - Assert.Equal(NetworkError.ConnectionRefused, ex.NetworkError); - } - - [OuterLoop] // TimedOut and HostNotFound is slow on Windows - [ConditionalFact(nameof(PlatformHasReliableConnectionFailures))] - public async Task ConnectAsync_WhenHostNotFound_ThrowsNetworkException() - { - using SocketsConnectionFactory factory = new SocketsConnectionFactory(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - // Unassigned as per https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt - int unusedPort = 8; - DnsEndPoint endPoint = new DnsEndPoint(System.Net.Test.Common.Configuration.Sockets.InvalidHost, unusedPort); - - NetworkException ex = await Assert.ThrowsAsync(() => factory.ConnectAsync(endPoint).AsTask()); - Assert.Equal(NetworkError.HostNotFound, ex.NetworkError); - } - - [OuterLoop] // TimedOut and HostNotFound is slow on Windows - [ConditionalFact(nameof(PlatformHasReliableConnectionFailures))] - public async Task ConnectAsync_TimedOut_ThrowsNetworkException() - { - using SocketsConnectionFactory factory = new SocketsConnectionFactory(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - IPEndPoint doesNotExist = new IPEndPoint(IPAddress.Parse("1.2.3.4"), 23); - - NetworkException ex = await Assert.ThrowsAsync(() => factory.ConnectAsync(doesNotExist).AsTask()); - Assert.Equal(NetworkError.TimedOut, ex.NetworkError); - } - - // On Windows, connection timeout takes 21 seconds. Abusing this behavior to test the cancellation logic - [Fact] - [PlatformSpecific(TestPlatforms.Windows)] - public async Task ConnectAsync_WhenCancelled_ThrowsTaskCancelledException() - { - using SocketsConnectionFactory factory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp); - IPEndPoint doesNotExist = new IPEndPoint(IPAddress.Parse("1.2.3.4"), 23); - - CancellationTokenSource cts = new CancellationTokenSource(); - cts.CancelAfter(100); - - OperationCanceledException ex = await Assert.ThrowsAsync(() => factory.ConnectAsync(doesNotExist, cancellationToken: cts.Token).AsTask()); - Assert.Equal(cts.Token, ex.CancellationToken); - } - - [Fact] - public async Task ConnectAsync_WhenCancelledBeforeInvocation_ThrowsTaskCancelledException() - { - using SocketsConnectionFactory factory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp); - IPEndPoint doesNotExist = new IPEndPoint(IPAddress.Parse("1.2.3.4"), 23); - - CancellationToken cancellationToken = new CancellationToken(true); - - OperationCanceledException ex = await Assert.ThrowsAsync(() => factory.ConnectAsync(doesNotExist, cancellationToken: cancellationToken).AsTask()); - Assert.Equal(cancellationToken, ex.CancellationToken); - } - - [Theory] - [MemberData(nameof(GetConnectData))] - public async Task Connection_Stream_ReadWrite_Success(EndPoint endPoint, SocketType socketType, ProtocolType protocolType) - { - endPoint = RecreateUdsEndpoint(endPoint); - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, endPoint, protocolType); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(endPoint.AddressFamily, socketType, protocolType); - - using Connection connection = await factory.ConnectAsync(server.EndPoint); - - Stream stream = connection.Stream; - - byte[] sendData = { 1, 2, 3 }; - byte[] receiveData = new byte[sendData.Length]; - - await stream.WriteAsync(sendData); - await stream.FlushAsync(); - await stream.ReadAsync(receiveData); - - // The test server should echo the data: - Assert.Equal(sendData, receiveData); - } - - [Theory] - [MemberData(nameof(GetConnectData))] - public async Task Connection_EndpointsAreCorrect(EndPoint endPoint, SocketType socketType, ProtocolType protocolType) - { - endPoint = RecreateUdsEndpoint(endPoint); - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, endPoint, protocolType); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(endPoint.AddressFamily, socketType, protocolType); - using Connection connection = await factory.ConnectAsync(server.EndPoint); - - // Checking for .ToString() result, because UnixDomainSocketEndPoint equality doesn't seem to be implemented - Assert.Equal(server.EndPoint.ToString(), connection.RemoteEndPoint.ToString()); - Assert.IsType(endPoint.GetType(), connection.LocalEndPoint); - } - - [Theory] - [MemberData(nameof(GetConnectData))] - public async Task Connection_Pipe_ReadWrite_Success(EndPoint endPoint, SocketType socketType, ProtocolType protocolType) - { - endPoint = RecreateUdsEndpoint(endPoint); - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, endPoint, protocolType); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(endPoint.AddressFamily, socketType, protocolType); - - - using Connection connection = await factory.ConnectAsync(server.EndPoint); - - IDuplexPipe pipe = connection.Pipe; - - byte[] sendData = { 1, 2, 3 }; - using MemoryStream receiveTempStream = new MemoryStream(); - - await pipe.Output.WriteAsync(sendData); - ReadResult rr = await pipe.Input.ReadAsync(); - - // The test server should echo the data: - Assert.True(rr.Buffer.FirstSpan.SequenceEqual(sendData)); - } - - [Theory] - [InlineData(false, false)] - [InlineData(false, true)] - [InlineData(true, false)] - [InlineData(true, true)] - public async Task Connection_Dispose_ClosesSocket(bool disposeAsync, bool usePipe) - { - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - Connection connection = await factory.ConnectAsync(server.EndPoint); - - Stream stream = usePipe ? null : connection.Stream; - if (usePipe) _ = connection.Pipe; - connection.ConnectionProperties.TryGet(out Socket socket); - - if (disposeAsync) await connection.DisposeAsync(); - else connection.Dispose(); - - Assert.False(socket.Connected); - - if (!usePipe) - { - // In this case we can also verify if the stream is disposed - Assert.Throws(() => stream.Write(new byte[1])); - } - } - - [Theory] - [InlineData(true, ConnectionCloseMethod.GracefulShutdown)] - [InlineData(true, ConnectionCloseMethod.Immediate)] - [InlineData(true, ConnectionCloseMethod.Abort)] - [InlineData(false, ConnectionCloseMethod.GracefulShutdown)] - [InlineData(false, ConnectionCloseMethod.Immediate)] - [InlineData(false, ConnectionCloseMethod.Abort)] - public async Task Connection_CloseAsync_ClosesSocket(bool usePipe, ConnectionCloseMethod method) - { - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback); - using SocketsConnectionFactory factory = new SocketsConnectionFactory(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - Connection connection = await factory.ConnectAsync(server.EndPoint); - - Stream stream = null; - if (usePipe) - { - _ = connection.Pipe; - } - else - { - stream = connection.Stream; - } - - connection.ConnectionProperties.TryGet(out Socket socket); - - await connection.CloseAsync(method); - - Assert.Throws(() => socket.Send(new byte[1])); - - if (!usePipe) // No way to observe the stream if we work with the pipe - { - Assert.Throws(() => stream.Write(new byte[1])); - } - } - - // Test scenario based on: - // https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net/ - [Theory(Timeout = 60000)] // Give 1 minute to fail, in case of a hang - [InlineData(30)] - [InlineData(500)] - [OuterLoop("Might run long")] - public async Task Connection_Pipe_ReadWrite_Integration(int totalLines) - { - using SocketsConnectionFactory factory = new SocketsConnectionFactory(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - using SocketTestServer echoServer = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback); - - Socket serverSocket = null; - echoServer.Accepted += s => serverSocket = s; - - using Connection connection = await factory.ConnectAsync(echoServer.EndPoint); - - IDuplexPipe pipe = connection.Pipe; - - ConcurrentQueue linesSent = new ConcurrentQueue(); - Task writerTask = Task.Factory.StartNew(async () => - { - byte[] endl = Encoding.ASCII.GetBytes("\n"); - StringBuilder expectedLine = new StringBuilder(); - - for (int i = 0; i < totalLines; i++) - { - int words = i % 10 + 1; - for (int j = 0; j < words; j++) - { - string word = Guid.NewGuid() + " "; - Encoding.ASCII.GetBytes(word, pipe.Output); - expectedLine.Append(word); - } - linesSent.Enqueue(expectedLine.ToString()); - await pipe.Output.WriteAsync(endl); - expectedLine.Clear(); - } - - await pipe.Output.FlushAsync(); - - // This will also trigger completion on the reader. TODO: Fix - // await pipe.Output.CompleteAsync(); - }, TaskCreationOptions.LongRunning); - - // The test server should echo the data sent to it - - PipeReader reader = pipe.Input; - - int lineIndex = 0; - - void ProcessLine(ReadOnlySequence lineBuffer) - { - string line = Encoding.ASCII.GetString(lineBuffer); - Assert.True(linesSent.TryDequeue(out string expectedLine)); - Assert.Equal(expectedLine, line); - lineIndex++; - - // Received everything, shut down the server, so next read will complete: - if (lineIndex == totalLines) serverSocket.Shutdown(SocketShutdown.Both); - } - - while (true) - { - try - { - ReadResult result = await reader.ReadAsync(); - - ReadOnlySequence buffer = result.Buffer; - SequencePosition? position = null; - - // Stop reading if there's no more data coming - if (result.IsCompleted) - { - break; - } - - do - { - // Look for a EOL in the buffer - position = buffer.PositionOf((byte)'\n'); - - if (position != null) - { - // Process the line - ProcessLine(buffer.Slice(0, position.Value)); - - // Skip the line + the \n character (basically position) - buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); - } - } - while (position != null); - - // Tell the PipeReader how much of the buffer we have consumed - reader.AdvanceTo(buffer.Start, buffer.End); - } - catch (SocketException) - { - // terminate - } - - } - - // Mark the PipeReader as complete - await reader.CompleteAsync(); - await writerTask; - - // TODO: If this is done in the end of writerTask the socket stops working - Assert.Equal(totalLines, lineIndex); - } - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/Sockets/SocketsConnectionFactoryTests_DerivedFactory.cs b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/Sockets/SocketsConnectionFactoryTests_DerivedFactory.cs deleted file mode 100644 index 766d21c988e4f..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/Sockets/SocketsConnectionFactoryTests_DerivedFactory.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.IO.Pipelines; -using System.Net.Connections; -using System.Net.Sockets; -using System.Net.Sockets.Tests; -using System.Threading.Tasks; -using Xunit; - -namespace System.Net.Connections.Tests -{ - [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime))] - public class SocketsConnectionFactoryTests_DerivedFactory - { - private class CustomConnectionOptionsValues - { - public bool NoDelay { get; set; } - - public bool DualMode { get; set; } - } - - private class CustomConnectionOptions : IConnectionProperties - { - public CustomConnectionOptionsValues Values { get; } = new CustomConnectionOptionsValues(); - - public CustomConnectionOptions() - { - } - - public bool TryGet(Type propertyKey, [NotNullWhen(true)] out object property) - { - if (propertyKey == typeof(CustomConnectionOptionsValues)) - { - property = Values; - return true; - } - - property = null; - return false; - } - } - - private sealed class CustomFactory : SocketsConnectionFactory - { - public CustomFactory() : base(SocketType.Stream, ProtocolType.Tcp) - { - } - - protected override Socket CreateSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, EndPoint endPoint, IConnectionProperties options) - { - Socket socket = new Socket(addressFamily, socketType, protocolType); - - if (options.TryGet(out CustomConnectionOptionsValues vals)) - { - socket.NoDelay = vals.NoDelay; - socket.DualMode = vals.DualMode; - } - - return socket; - } - } - - private readonly CustomFactory _factory = new CustomFactory(); - private readonly CustomConnectionOptions _options = new CustomConnectionOptions(); - private readonly IPEndPoint _endPoint = new IPEndPoint(IPAddress.IPv6Loopback, 0); - - [Fact] - public async Task DerivedFactory_CanShimSocket() - { - using var server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, _endPoint); - using Connection connection = await _factory.ConnectAsync(server.EndPoint, _options); - connection.ConnectionProperties.TryGet(out Socket socket); - - Assert.Equal(_options.Values.NoDelay, socket.NoDelay); - Assert.Equal(_options.Values.DualMode, socket.DualMode); - } - } -} diff --git a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj b/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj deleted file mode 100644 index 7ddfadfd04df2..0000000000000 --- a/src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - - $(NetCoreAppCurrent) - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -