Remove System.Net.Connections and related features (#41648)
authorGeoff Kizer <geoffrek@microsoft.com>
Wed, 2 Sep 2020 02:31:14 +0000 (19:31 -0700)
committerGitHub <noreply@github.com>
Wed, 2 Sep 2020 02:31:14 +0000 (19:31 -0700)
* remove System.Net.Connections and related features

* cleanup csproj changes

* Update src/libraries/pkg/baseline/packageIndex.json

Co-authored-by: Cory Nelson <phrosty@gmail.com>
* Update src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs

Co-authored-by: Cory Nelson <phrosty@gmail.com>
Co-authored-by: Geoffrey Kizer <geoffrek@windows.microsoft.com>
Co-authored-by: Cory Nelson <phrosty@gmail.com>
32 files changed:
src/libraries/NetCoreAppLibrary.props
src/libraries/System.Net.Connections/ref/System.Net.Connections.cs
src/libraries/System.Net.Connections/src/System.Net.Connections.csproj
src/libraries/System.Net.Connections/src/System/Net/NetworkError.cs [moved from src/libraries/System.Net.Primitives/src/System/Net/NetworkError.cs with 100% similarity]
src/libraries/System.Net.Connections/src/System/Net/NetworkException.cs [moved from src/libraries/System.Net.Primitives/src/System/Net/NetworkException.cs with 76% similarity]
src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/Sockets/SocketsConnectionFactoryTests.cs
src/libraries/System.Net.Connections/tests/System.Net.Connections.Tests/System.Net.Connections.Tests.csproj
src/libraries/System.Net.Http/ref/System.Net.Http.cs
src/libraries/System.Net.Http/ref/System.Net.Http.csproj
src/libraries/System.Net.Http/src/System.Net.Http.csproj
src/libraries/System.Net.Http/src/System/Net/Http/BrowserHttpHandler/SocketsHttpHandler.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs [deleted file]
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsConnectionFactory.cs [new file with mode: 0644]
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs
src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Http2.cs
src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs
src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj
src/libraries/System.Net.Primitives/ref/System.Net.Primitives.cs
src/libraries/System.Net.Primitives/src/Resources/Strings.resx
src/libraries/System.Net.Primitives/src/System.Net.Primitives.csproj
src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj
src/libraries/System.Net.Requests/src/System/Net/WebException.cs
src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj
src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs
src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs
src/libraries/pkg/baseline/packageIndex.json

index 0fd6812..0b19bb8 100644 (file)
@@ -48,7 +48,6 @@
       System.IO.FileSystem.Watcher;
       System.IO.IsolatedStorage;
       System.IO.MemoryMappedFiles;
-      System.IO.Pipelines;
       System.IO.Pipes;
       System.IO.Pipes.AccessControl;
       System.IO.UnmanagedMemoryStream;
@@ -57,7 +56,6 @@
       System.Linq.Parallel;
       System.Linq.Queryable;
       System.Memory;
-      System.Net.Connections;
       System.Net.Http;
       System.Net.Http.Json;
       System.Net.HttpListener;
index 1e8e72c..feca258 100644 (file)
@@ -79,3 +79,24 @@ namespace System.Net.Connections
         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; } }
+    }
+}
index cf6682f..055eaef 100644 (file)
@@ -6,6 +6,8 @@
   <ItemGroup>
     <Compile Include="$(CommonPath)System\Net\NetworkErrorHelper.cs" Link="Common\System\Net\NetworkErrorHelper.cs" />
     <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
+    <Compile Include="System\Net\NetworkError.cs" />
+    <Compile Include="System\Net\NetworkException.cs" />
     <Compile Include="System\Net\Connections\ConnectionBase.cs" />
     <Compile Include="System\Net\Connections\ConnectionCloseMethod.cs" />
     <Compile Include="System\Net\Connections\ConnectionExtensions.cs" />
     <Compile Include="System\Net\Connections\Sockets\SocketsConnectionFactory.cs" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\System.IO.Pipelines\ref\System.IO.Pipelines.csproj" />
     <Reference Include="System.Runtime" />
     <Reference Include="System.Memory" />
     <Reference Include="System.Net.Primitives" />
     <Reference Include="System.Net.Sockets" />
     <Reference Include="System.Threading" />
     <Reference Include="System.Threading.Tasks" />
-    <Reference Include="System.IO.Pipelines" />
     <Reference Include="Microsoft.Win32.Primitives" />
   </ItemGroup>
 </Project>
@@ -38,16 +38,7 @@ namespace System.Net
         /// <summary>Returns the specific kind of error.</summary>
         public NetworkError NetworkError { get; }
 
-        private static string GetExceptionMessage(NetworkError error) => error switch
-        {
-            NetworkError.EndPointInUse => SR.networkerror_addressinuse,
-            NetworkError.TimedOut => SR.networkerror_timedout,
-            NetworkError.HostNotFound => SR.networkerror_hostnotfound,
-            NetworkError.ConnectionRefused => SR.networkerror_connectionrefused,
-            NetworkError.ConnectionAborted => SR.networkerror_connectionaborted,
-            NetworkError.ConnectionReset => SR.networkerror_connectionreset,
-            NetworkError.OperationAborted => SR.networkerror_operationaborted,
-            _ => SR.networkerror_other
-        };
+        // TODO: Better exception messages
+        private static string GetExceptionMessage(NetworkError error) => $"A network error occurred: {error}";
     }
 }
index 9215042..683f1b9 100644 (file)
@@ -225,36 +225,6 @@ namespace System.Net.Connections.Tests
             Assert.True(rr.Buffer.FirstSpan.SequenceEqual(sendData));
         }
 
-        [Fact]
-        public async Task Connection_Stream_FailingOperation_ThowsNetworkException()
-        {
-            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);
-            Stream stream = connection.Stream;
-            socket.Dispose();
-
-            Assert.Throws<NetworkException>(() => stream.Read(new byte[1], 0, 1));
-            Assert.Throws<NetworkException>(() => stream.Write(new byte[1], 0, 1));
-        }
-
-        [Fact]
-        public async Task Connection_Pipe_FailingOperation_ThowsNetworkException()
-        {
-            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);
-            IDuplexPipe pipe = connection.Pipe;
-            socket.Dispose();
-
-            await Assert.ThrowsAsync<NetworkException>(() =>  pipe.Input.ReadAsync().AsTask());
-            await Assert.ThrowsAsync<NetworkException>(() => pipe.Output.WriteAsync(new byte[1]).AsTask());
-        }
-
         [Theory]
         [InlineData(false, false)]
         [InlineData(false, true)]
index 6426b8e..7ddfadf 100644 (file)
@@ -30,5 +30,9 @@
     <Compile Include="$(CommonTestPath)System\Net\Sockets\SocketImplementationType.cs" Link="SocketCommon\SocketImplementationType.cs" />
     <Compile Include="$(CommonTestPath)System\Threading\Tasks\TaskTimeoutExtensions.cs" Link="Common\System\Threading\Tasks\TaskTimeoutExtensions.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\System.IO.Pipelines\src\System.IO.Pipelines.csproj" />
+    <ProjectReference Include="..\..\..\System.Net.Connections\src\System.Net.Connections.csproj" />
+  </ItemGroup>
 
 </Project>
index 85997fa..cc6c899 100644 (file)
@@ -331,7 +331,6 @@ namespace System.Net.Http
         public static bool IsSupported { get { throw null; } }
         public bool AllowAutoRedirect { get { throw null; } set { } }
         public System.Net.DecompressionMethods AutomaticDecompression { get { throw null; } set { } }
-        public System.Net.Connections.ConnectionFactory? ConnectionFactory { get { throw null; } set { } }
         public System.TimeSpan ConnectTimeout { get { throw null; } set { } }
         [System.Diagnostics.CodeAnalysis.AllowNullAttribute]
         public System.Net.CookieContainer CookieContainer { get { throw null; } set { } }
@@ -345,7 +344,6 @@ namespace System.Net.Http
         public int MaxConnectionsPerServer { get { throw null; } set { } }
         public int MaxResponseDrainSize { get { throw null; } set { } }
         public int MaxResponseHeadersLength { get { throw null; } set { } }
-        public System.Func<System.Net.Http.HttpRequestMessage, System.Net.Connections.Connection, System.Threading.CancellationToken, System.Threading.Tasks.ValueTask<System.Net.Connections.Connection>>? PlaintextFilter { get { throw null; } set { } }
         public System.TimeSpan PooledConnectionIdleTimeout { get { throw null; } set { } }
         public System.TimeSpan PooledConnectionLifetime { get { throw null; } set { } }
         public bool PreAuthenticate { get { throw null; } set { } }
index 296b6c0..0e6cf82 100644 (file)
@@ -10,7 +10,6 @@
     <ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
     <ProjectReference Include="..\..\System.Net.Primitives\ref\System.Net.Primitives.csproj" />
     <ProjectReference Include="..\..\System.Net.Sockets\ref\System.Net.Sockets.csproj" />
-    <ProjectReference Include="..\..\System.Net.Connections\ref\System.Net.Connections.csproj" />
     <ProjectReference Include="..\..\System.Net.Security\ref\System.Net.Security.csproj" />
     <ProjectReference Include="..\..\System.Security.Cryptography.X509Certificates\ref\System.Security.Cryptography.X509Certificates.csproj" />
     <ProjectReference Include="..\..\System.Text.Encoding\ref\System.Text.Encoding.csproj" />
index 3f2923f..1badaad 100644 (file)
              Link="Common\System\IO\StreamHelpers.CopyValidation.cs" />
     <Compile Include="$(CommonPath)System\Net\Security\SslClientAuthenticationOptionsExtensions.cs"
              Link="Common\System\Net\Security\SslClientAuthenticationOptionsExtensions.cs" />
-    <Compile Include="$(CommonPath)System\Net\NetworkErrorHelper.cs"
-             Link="Common\System\Net\NetworkErrorHelper.cs" />
     <Compile Include="$(CommonPath)System\IO\DelegatingStream.cs"
              Link="Common\System\IO\DelegatingStream.cs" />
     <Compile Include="$(CommonPath)System\IO\ReadOnlyMemoryStream.cs"
     <Compile Include="System\Net\Http\SocketsHttpHandler\MultiProxy.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\RawConnectionStream.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\RedirectHandler.cs" />
+    <Compile Include="System\Net\Http\SocketsHttpHandler\SocketsConnectionFactory.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\SocketsHttpHandler.cs" />
     <Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.cs" />
-    <Compile Include="System\Net\Http\SocketsHttpHandler\DnsEndPointWithProperties.cs" />
     <Compile Include="$(CommonPath)System\Net\NTAuthentication.Common.cs"
              Link="Common\System\Net\NTAuthentication.Common.cs" />
     <Compile Include="$(CommonPath)System\Net\ContextFlagsPal.cs"
     <Reference Include="System.Diagnostics.DiagnosticSource" />
     <Reference Include="System.Diagnostics.Tracing" />
     <Reference Include="System.IO.Compression" />
-    <Reference Include="System.IO.Pipelines" />
     <Reference Include="System.Memory" />
-    <Reference Include="System.Net.Connections" />
     <Reference Include="System.Net.NameResolution" />
     <Reference Include="System.Net.NetworkInformation" />
     <Reference Include="System.Net.Primitives" />
index 214f562..1d7ae3a 100644 (file)
@@ -6,7 +6,6 @@ using System.Net.Security;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Diagnostics.CodeAnalysis;
-using System.Net.Connections;
 
 namespace System.Net.Http
 {
@@ -149,18 +148,6 @@ namespace System.Net.Http
             set => throw new PlatformNotSupportedException();
         }
 
-        public ConnectionFactory? ConnectionFactory
-        {
-            get => throw new PlatformNotSupportedException();
-            set => throw new PlatformNotSupportedException();
-        }
-
-        public Func<HttpRequestMessage, Connection, CancellationToken, ValueTask<Connection>>? PlaintextFilter
-        {
-            get => throw new PlatformNotSupportedException();
-            set => throw new PlatformNotSupportedException();
-        }
-
         public IDictionary<string, object?> Properties => throw new PlatformNotSupportedException();
 
         public HeaderEncodingSelector<HttpRequestMessage>? RequestHeaderEncodingSelector
index 726b8ba..931b888 100644 (file)
@@ -3,12 +3,9 @@
 
 using System.Diagnostics;
 using System.IO;
-using System.IO.Pipelines;
-using System.Net.Connections;
 using System.Net.Quic;
 using System.Net.Security;
 using System.Net.Sockets;
-using System.Runtime.ExceptionServices;
 using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Threading.Tasks;
@@ -34,11 +31,11 @@ namespace System.Net.Http
             }
         }
 
-        public static async ValueTask<Connection> ConnectAsync(ConnectionFactory factory, DnsEndPoint endPoint, IConnectionProperties? options, CancellationToken cancellationToken)
+        public static async ValueTask<Stream> ConnectAsync(SocketsConnectionFactory factory, DnsEndPoint endPoint, CancellationToken cancellationToken)
         {
             try
             {
-                return await factory.ConnectAsync(endPoint, options, cancellationToken).ConfigureAwait(false);
+                return await factory.ConnectAsync(endPoint, cancellationToken).ConfigureAwait(false);
             }
             catch (OperationCanceledException ex) when (ex.CancellationToken == cancellationToken)
             {
@@ -50,7 +47,7 @@ namespace System.Net.Http
             }
         }
 
-        public static Connection Connect(string host, int port, CancellationToken cancellationToken)
+        public static Stream Connect(string host, int port, CancellationToken cancellationToken)
         {
             // For synchronous connections, we can just create a socket and make the connection.
             cancellationToken.ThrowIfCancellationRequested();
@@ -63,17 +60,7 @@ namespace System.Net.Http
                     socket.Connect(new DnsEndPoint(host, port));
                 }
 
-                // Since we only do GracefulShutdown in SocketsHttpHandler code, Connection.FromStream() should match SocketConnection's behavior:
-                return Connection.FromStream(new NetworkStream(socket, ownsSocket: true), localEndPoint: socket.LocalEndPoint, remoteEndPoint: socket.RemoteEndPoint);
-            }
-            catch (SocketException se)
-            {
-                socket.Dispose();
-
-                // SocketConnectionFactory wraps SocketException in NetworkException. Do the same here.
-                NetworkException ne = NetworkErrorHelper.MapSocketException(se);
-
-                throw CreateWrappedException(ne, host, port, cancellationToken);
+                return new NetworkStream(socket, ownsSocket: true);
             }
             catch (Exception e)
             {
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/DnsEndPointWithProperties.cs
deleted file mode 100644 (file)
index ef4ee0b..0000000
+++ /dev/null
@@ -1,31 +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.Net.Connections;
-
-namespace System.Net.Http
-{
-    // Passed to a connection factory, merges allocations for the DnsEndPoint and connection properties.
-    internal sealed class DnsEndPointWithProperties : DnsEndPoint, IConnectionProperties
-    {
-        private readonly HttpRequestMessage _initialRequest;
-
-        public DnsEndPointWithProperties(string host, int port, HttpRequestMessage initialRequest) : base(host, port)
-        {
-            _initialRequest = initialRequest;
-        }
-
-        bool IConnectionProperties.TryGet(Type propertyKey, [NotNullWhen(true)] out object? property)
-        {
-            if (propertyKey == typeof(HttpRequestMessage))
-            {
-                property = _initialRequest;
-                return true;
-            }
-
-            property = null;
-            return false;
-        }
-    }
-}
index e4e7171..be457ef 100644 (file)
@@ -7,7 +7,6 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.IO;
-using System.Net.Connections;
 using System.Net.Http.Headers;
 using System.Net.Http.HPack;
 using System.Net.Security;
@@ -24,7 +23,6 @@ namespace System.Net.Http
     {
         private readonly HttpConnectionPool _pool;
         private readonly Stream _stream;
-        private readonly Connection _connection;
 
         // NOTE: These are mutable structs; do not make these readonly.
         private ArrayBuffer _incomingBuffer;
@@ -119,11 +117,10 @@ namespace System.Net.Http
         private long _keepAlivePingTimeoutTimestamp;
         private volatile KeepAliveState _keepAliveState;
 
-        public Http2Connection(HttpConnectionPool pool, Connection connection)
+        public Http2Connection(HttpConnectionPool pool, Stream stream)
         {
             _pool = pool;
-            _stream = connection.Stream;
-            _connection = connection;
+            _stream = stream;
             _incomingBuffer = new ArrayBuffer(InitialConnectionBufferSize);
             _outgoingBuffer = new ArrayBuffer(InitialConnectionBufferSize);
 
@@ -1703,7 +1700,7 @@ namespace System.Net.Http
             GC.SuppressFinalize(this);
 
             // Do shutdown.
-            _connection.Dispose();
+            _stream.Dispose();
 
             _connectionWindow.Dispose();
             _concurrentStreams.Dispose();
index f2bff59..47056c0 100644 (file)
@@ -10,7 +10,6 @@ using System.IO;
 using System.Net.Http.Headers;
 using System.Net.Security;
 using System.Net.Sockets;
-using System.Net.Connections;
 using System.Runtime.CompilerServices;
 using System.Text;
 using System.Threading;
@@ -46,7 +45,6 @@ namespace System.Net.Http
         private readonly HttpConnectionPool _pool;
         private readonly Socket? _socket; // used for polling; _stream should be used for all reading/writing. _stream owns disposal.
         private readonly Stream _stream;
-        private readonly Connection _connection;
         private readonly TransportContext? _transportContext;
         private readonly WeakReference<HttpConnection> _weakThisRef;
 
@@ -73,16 +71,19 @@ namespace System.Net.Http
 
         public HttpConnection(
             HttpConnectionPool pool,
-            Connection connection,
+            Stream stream,
             TransportContext? transportContext)
         {
             Debug.Assert(pool != null);
-            Debug.Assert(connection != null);
+            Debug.Assert(stream != null);
 
             _pool = pool;
-            connection.ConnectionProperties.TryGet(out _socket); // may be null in cases where we couldn't easily get the underlying socket
-            _stream = connection.Stream;
-            _connection = connection;
+            _stream = stream;
+            if (stream is NetworkStream networkStream)
+            {
+                _socket = networkStream.Socket;
+            }
+
             _transportContext = transportContext;
 
             _writeBuffer = new byte[InitialWriteBufferSize];
@@ -123,7 +124,7 @@ namespace System.Net.Http
                 if (disposing)
                 {
                     GC.SuppressFinalize(this);
-                    _connection.Dispose();
+                    _stream.Dispose();
 
                     // Eat any exceptions from the read-ahead task.  We don't need to log, as we expect
                     // failures from this task due to closing the connection while a read is in progress.
index fdfbaf9..df4332c 100644 (file)
@@ -6,7 +6,6 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO;
-using System.Net.Connections;
 using System.Net.Http.Headers;
 using System.Net.Http.HPack;
 using System.Net.Http.QPack;
@@ -577,7 +576,7 @@ namespace System.Net.Http
             }
 
             // Try to establish an HTTP2 connection
-            Connection? connection = null;
+            Stream? stream = null;
             SslStream? sslStream = null;
             TransportContext? transportContext = null;
 
@@ -601,7 +600,7 @@ namespace System.Net.Http
 
                     HttpResponseMessage? failureResponse;
 
-                    (connection, transportContext, failureResponse) =
+                    (stream, transportContext, failureResponse) =
                         await ConnectAsync(request, async, cancellationToken).ConfigureAwait(false);
 
                     if (failureResponse != null)
@@ -609,18 +608,13 @@ namespace System.Net.Http
                         return (null, true, failureResponse);
                     }
 
-                    Debug.Assert(connection != null);
+                    Debug.Assert(stream != null);
 
-                    sslStream = connection.Stream as SslStream;
-
-                    if (Settings._plaintextFilter != null)
-                    {
-                        connection = await Settings._plaintextFilter(request, connection, cancellationToken).ConfigureAwait(false);
-                    }
+                    sslStream = stream as SslStream;
 
                     if (_kind == HttpConnectionKind.Http)
                     {
-                        http2Connection = new Http2Connection(this, connection);
+                        http2Connection = new Http2Connection(this, stream);
                         await http2Connection.SetupAsync().ConfigureAwait(false);
 
                         AddHttp2Connection(http2Connection);
@@ -644,7 +638,7 @@ namespace System.Net.Http
                             throw new HttpRequestException(SR.Format(SR.net_ssl_http2_requires_tls12, sslStream.SslProtocol));
                         }
 
-                        http2Connection = new Http2Connection(this, connection);
+                        http2Connection = new Http2Connection(this, stream);
                         await http2Connection.SetupAsync().ConfigureAwait(false);
 
                         AddHttp2Connection(http2Connection);
@@ -701,7 +695,7 @@ namespace System.Net.Http
 
                 if (canUse)
                 {
-                    return (ConstructHttp11Connection(connection!, transportContext), true, null);
+                    return (ConstructHttp11Connection(stream!, transportContext), true, null);
                 }
                 else
                 {
@@ -710,7 +704,7 @@ namespace System.Net.Http
                         Trace("Discarding downgraded HTTP/1.1 connection because connection limit is exceeded");
                     }
 
-                    await connection!.CloseAsync(ConnectionCloseMethod.GracefulShutdown, cancellationToken).ConfigureAwait(false);
+                    stream!.Dispose();
                 }
             }
 
@@ -1233,7 +1227,7 @@ namespace System.Net.Http
             return SendWithProxyAuthAsync(request, async, doRequestAuth, cancellationToken);
         }
 
-        private async ValueTask<(Connection?, TransportContext?, HttpResponseMessage?)> ConnectAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
+        private async ValueTask<(Stream?, TransportContext?, HttpResponseMessage?)> ConnectAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
         {
             // If a non-infinite connect timeout has been set, create and use a new CancellationToken that will be canceled
             // when either the original token is canceled or a connect timeout occurs.
@@ -1247,24 +1241,24 @@ namespace System.Net.Http
 
             try
             {
-                Connection? connection = null;
+                Stream? stream = null;
                 switch (_kind)
                 {
                     case HttpConnectionKind.Http:
                     case HttpConnectionKind.Https:
                     case HttpConnectionKind.ProxyConnect:
                         Debug.Assert(_originAuthority != null);
-                        connection = await ConnectToTcpHostAsync(_originAuthority.IdnHost, _originAuthority.Port, request, async, cancellationToken).ConfigureAwait(false);
+                        stream = await ConnectToTcpHostAsync(_originAuthority.IdnHost, _originAuthority.Port, request, async, cancellationToken).ConfigureAwait(false);
                         break;
 
                     case HttpConnectionKind.Proxy:
-                        connection = await ConnectToTcpHostAsync(_proxyUri!.IdnHost, _proxyUri.Port, request, async, cancellationToken).ConfigureAwait(false);
+                        stream = await ConnectToTcpHostAsync(_proxyUri!.IdnHost, _proxyUri.Port, request, async, cancellationToken).ConfigureAwait(false);
                         break;
 
                     case HttpConnectionKind.ProxyTunnel:
                     case HttpConnectionKind.SslProxyTunnel:
                         HttpResponseMessage? response;
-                        (connection, response) = await EstablishProxyTunnel(async, request.HasHeaders ? request.Headers : null, cancellationToken).ConfigureAwait(false);
+                        (stream, response) = await EstablishProxyTunnel(async, request.HasHeaders ? request.Headers : null, cancellationToken).ConfigureAwait(false);
                         if (response != null)
                         {
                             // Return non-success response from proxy.
@@ -1274,17 +1268,17 @@ namespace System.Net.Http
                         break;
                 }
 
-                Debug.Assert(connection != null);
+                Debug.Assert(stream != null);
 
                 TransportContext? transportContext = null;
                 if (IsSecure)
                 {
-                    SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(GetSslOptionsForRequest(request), request, async, connection.Stream, cancellationToken).ConfigureAwait(false);
-                    connection = Connection.FromStream(sslStream, leaveOpen: false, connection.ConnectionProperties, connection.LocalEndPoint, connection.RemoteEndPoint);
+                    SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(GetSslOptionsForRequest(request), request, async, stream, cancellationToken).ConfigureAwait(false);
                     transportContext = sslStream.TransportContext;
+                    stream = sslStream;
                 }
 
-                return (connection, transportContext, null);
+                return (stream, transportContext, null);
             }
             finally
             {
@@ -1294,37 +1288,31 @@ namespace System.Net.Http
 
         private static readonly SocketsConnectionFactory s_defaultConnectionFactory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp);
 
-        private ValueTask<Connection> ConnectToTcpHostAsync(string host, int port, HttpRequestMessage initialRequest, bool async, CancellationToken cancellationToken)
+        private ValueTask<Stream> ConnectToTcpHostAsync(string host, int port, HttpRequestMessage initialRequest, bool async, CancellationToken cancellationToken)
         {
             if (async)
             {
-                ConnectionFactory connectionFactory = Settings._connectionFactory ?? s_defaultConnectionFactory;
+                SocketsConnectionFactory connectionFactory = s_defaultConnectionFactory;
 
-                var endPoint = new DnsEndPointWithProperties(host, port, initialRequest);
-                return ConnectHelper.ConnectAsync(connectionFactory, endPoint, endPoint, cancellationToken);
+                var endPoint = new DnsEndPoint(host, port);
+                return ConnectHelper.ConnectAsync(connectionFactory, endPoint, cancellationToken);
             }
 
             // Synchronous path.
 
-            if (Settings._connectionFactory != null)
-            {
-                // connection factories only support async.
-                throw new HttpRequestException();
-            }
-
             try
             {
-                return new ValueTask<Connection>(ConnectHelper.Connect(host, port, cancellationToken));
+                return new ValueTask<Stream>(ConnectHelper.Connect(host, port, cancellationToken));
             }
             catch (Exception ex)
             {
-                return ValueTask.FromException<Connection>(ex);
+                return ValueTask.FromException<Stream>(ex);
             }
         }
 
         internal async ValueTask<(HttpConnection?, HttpResponseMessage?)> CreateHttp11ConnectionAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
         {
-            (Connection? connection, TransportContext? transportContext, HttpResponseMessage? failureResponse) =
+            (Stream? stream, TransportContext? transportContext, HttpResponseMessage? failureResponse) =
                 await ConnectAsync(request, async, cancellationToken).ConfigureAwait(false);
 
             if (failureResponse != null)
@@ -1332,7 +1320,7 @@ namespace System.Net.Http
                 return (null, failureResponse);
             }
 
-            return (ConstructHttp11Connection(connection!, transportContext), null);
+            return (ConstructHttp11Connection(stream!, transportContext), null);
         }
 
         private SslClientAuthenticationOptions GetSslOptionsForRequest(HttpRequestMessage request)
@@ -1352,13 +1340,13 @@ namespace System.Net.Http
             return _sslOptionsHttp11!;
         }
 
-        private HttpConnection ConstructHttp11Connection(Connection connection, TransportContext? transportContext)
+        private HttpConnection ConstructHttp11Connection(Stream stream, TransportContext? transportContext)
         {
-            return new HttpConnection(this, connection, transportContext);
+            return new HttpConnection(this, stream, transportContext);
         }
 
         // Returns the established stream or an HttpResponseMessage from the proxy indicating failure.
-        private async ValueTask<(Connection?, HttpResponseMessage?)> EstablishProxyTunnel(bool async, HttpRequestHeaders? headers, CancellationToken cancellationToken)
+        private async ValueTask<(Stream?, HttpResponseMessage?)> EstablishProxyTunnel(bool async, HttpRequestHeaders? headers, CancellationToken cancellationToken)
         {
             Debug.Assert(_originAuthority != null);
             // Send a CONNECT request to the proxy server to establish a tunnel.
@@ -1380,9 +1368,7 @@ namespace System.Net.Http
             Stream stream = tunnelResponse.Content.ReadAsStream(cancellationToken);
             EndPoint remoteEndPoint = new DnsEndPoint(_originAuthority.IdnHost, _originAuthority.Port);
 
-            // TODO: the Socket from the response can be funneled into a connection property here.
-
-            return (Connection.FromStream(stream, remoteEndPoint: remoteEndPoint), null);
+            return (stream, null);
         }
 
         /// <summary>Enqueues a waiter to the waiters list.</summary>
index 3eefbd3..177d8bc 100644 (file)
@@ -2,7 +2,6 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Collections.Generic;
-using System.Net.Connections;
 using System.Net.Security;
 using System.Threading;
 using System.Threading.Tasks;
@@ -56,9 +55,6 @@ namespace System.Net.Http
 
         internal bool _enableMultipleHttp2Connections;
 
-        internal ConnectionFactory? _connectionFactory;
-        internal Func<HttpRequestMessage, Connection, CancellationToken, ValueTask<Connection>>? _plaintextFilter;
-
         internal IDictionary<string, object?>? _properties;
 
         public HttpConnectionSettings()
@@ -112,8 +108,6 @@ namespace System.Net.Http
                 _requestHeaderEncodingSelector = _requestHeaderEncodingSelector,
                 _responseHeaderEncodingSelector = _responseHeaderEncodingSelector,
                 _enableMultipleHttp2Connections = _enableMultipleHttp2Connections,
-                _connectionFactory = _connectionFactory,
-                _plaintextFilter = _plaintextFilter
             };
         }
 
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsConnectionFactory.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsConnectionFactory.cs
new file mode 100644 (file)
index 0000000..98c8e89
--- /dev/null
@@ -0,0 +1,106 @@
+// 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.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Net.Http
+{
+    /// <summary>
+    /// A factory 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>
+    internal sealed class SocketsConnectionFactory
+    {
+        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)
+        {
+        }
+
+        public async ValueTask<Stream> ConnectAsync(
+            EndPoint? endPoint,
+            CancellationToken cancellationToken = default)
+        {
+            if (endPoint == null) throw new ArgumentNullException(nameof(endPoint));
+            cancellationToken.ThrowIfCancellationRequested();
+
+            Socket socket = CreateSocket(_addressFamily, _socketType, _protocolType, endPoint);
+
+            try
+            {
+                await socket.ConnectAsync(endPoint, cancellationToken).ConfigureAwait(false);
+                return new NetworkStream(socket, true);
+            }
+            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>
+        /// <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>
+        private Socket CreateSocket(
+            AddressFamily addressFamily,
+            SocketType socketType,
+            ProtocolType protocolType,
+            EndPoint? endPoint)
+        {
+            Socket socket = new Socket(addressFamily, socketType, protocolType);
+
+            if (protocolType == ProtocolType.Tcp)
+            {
+                socket.NoDelay = true;
+            }
+
+            if (addressFamily == AddressFamily.InterNetworkV6)
+            {
+                socket.DualMode = true;
+            }
+
+            return socket;
+        }
+    }
+}
index dbe8388..978e94a 100644 (file)
@@ -3,7 +3,6 @@
 
 using System.Collections.Generic;
 using System.Diagnostics;
-using System.Net.Connections;
 using System.Net.Security;
 using System.Threading;
 using System.Threading.Tasks;
@@ -363,33 +362,6 @@ namespace System.Net.Http
         internal bool SupportsProxy => true;
         internal bool SupportsRedirectConfiguration => true;
 
-        /// <summary>
-        /// When non-null, a custom factory used to open new TCP connections.
-        /// When null, a <see cref="SocketsConnectionFactory"/> will be used.
-        /// </summary>
-        public ConnectionFactory? ConnectionFactory
-        {
-            get => _settings._connectionFactory;
-            set
-            {
-                CheckDisposedOrStarted();
-                _settings._connectionFactory = value;
-            }
-        }
-
-        /// <summary>
-        /// When non-null, a connection filter that is applied prior to any TLS encryption.
-        /// </summary>
-        public Func<HttpRequestMessage, Connection, CancellationToken, ValueTask<Connection>>? PlaintextFilter
-        {
-            get => _settings._plaintextFilter;
-            set
-            {
-                CheckDisposedOrStarted();
-                _settings._plaintextFilter = value;
-            }
-        }
-
         public IDictionary<string, object?> Properties =>
             _settings._properties ?? (_settings._properties = new Dictionary<string, object?>());
 
index cea6609..040558f 100644 (file)
@@ -1740,7 +1740,7 @@ namespace System.Net.Http.Functional.Tests
                     // Send response and close the stream.
                     if (expectRequestFail)
                     {
-                        await Assert.ThrowsAsync<NetworkException>(() => connection.SendDefaultResponseAsync(streamId2));
+                        await Assert.ThrowsAsync<IOException>(() => connection.SendDefaultResponseAsync(streamId2));
                         // As stream is closed we don't want to continue with sending data.
                         return;
                     }
index fa07468..5dc9d3b 100644 (file)
@@ -5,7 +5,6 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
-using System.Net.Connections;
 using System.Net.Quic;
 using System.Net.Security;
 using System.Net.Sockets;
@@ -106,110 +105,6 @@ namespace System.Net.Http.Functional.Tests
         }
     }
 
-    public class SocketsHttpHandler_ConnectionFactoryTest : HttpClientHandlerTestBase
-    {
-        public SocketsHttpHandler_ConnectionFactoryTest(ITestOutputHelper output) : base(output) { }
-
-        [Fact]
-        public async Task CustomConnectionFactory_AsyncRequest_Success()
-        {
-            await using ConnectionListenerFactory listenerFactory = new VirtualNetworkConnectionListenerFactory();
-            await using ConnectionListener listener = await listenerFactory.ListenAsync(endPoint: null);
-            await using ConnectionFactory connectionFactory = VirtualNetworkConnectionListenerFactory.GetConnectionFactory(listener);
-
-            var options = new GenericLoopbackOptions();
-
-            Task serverTask = Task.Run(async () =>
-            {
-                await using Connection serverConnection = await listener.AcceptAsync();
-                using GenericLoopbackConnection loopbackConnection = await LoopbackServerFactory.CreateConnectionAsync(socket: null, serverConnection.Stream, options);
-
-                await loopbackConnection.InitializeConnectionAsync();
-
-                HttpRequestData requestData = await loopbackConnection.ReadRequestDataAsync();
-                await loopbackConnection.SendResponseAsync(content: "foo");
-
-                Assert.Equal("/foo", requestData.Path);
-            });
-
-            Task clientTask = Task.Run(async () =>
-            {
-                using HttpClientHandler handler = CreateHttpClientHandler();
-                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
-
-                var socketsHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler);
-                socketsHandler.ConnectionFactory = connectionFactory;
-
-                using HttpClient client = CreateHttpClient(handler);
-
-                string response = await client.GetStringAsync($"{(options.UseSsl ? "https" : "http")}://{Guid.NewGuid():N}.com/foo");
-                Assert.Equal("foo", response);
-            });
-
-            await new[] { serverTask, clientTask }.WhenAllOrAnyFailed(60_000);
-        }
-
-        [Fact]
-        public async Task CustomConnectionFactory_SyncRequest_Fails()
-        {
-            await using ConnectionFactory connectionFactory = new SocketsConnectionFactory(SocketType.Stream, ProtocolType.Tcp);
-            using SocketsHttpHandler handler = new SocketsHttpHandler
-            {
-                ConnectionFactory = connectionFactory
-            };
-
-            using HttpClient client = CreateHttpClient(handler);
-
-            HttpRequestException e = await Assert.ThrowsAnyAsync<HttpRequestException>(() => client.GetStringAsync($"http://{Guid.NewGuid():N}.com/foo"));
-            Assert.IsType<NetworkException>(e.InnerException);
-        }
-
-        class CustomConnectionFactory : SocketsConnectionFactory
-        {
-            public CustomConnectionFactory() : base(SocketType.Stream, ProtocolType.Tcp) { }
-
-            public HttpRequestMessage LastHttpRequestMessage { get; private set; }
-
-            public override ValueTask<Connection> ConnectAsync(EndPoint endPoint, IConnectionProperties options = null, CancellationToken cancellationToken = default)
-            {
-                if (options.TryGet(out HttpRequestMessage message))
-                {
-                    LastHttpRequestMessage = message;
-                }
-
-                return base.ConnectAsync(endPoint, options, cancellationToken);
-            }
-        }
-
-        [Fact]
-        public Task CustomConnectionFactory_ConnectAsync_CanCaptureHttpRequestMessage()
-        {
-            return LoopbackServer.CreateClientAndServerAsync(async uri =>
-            {
-                using var connectionFactory = new CustomConnectionFactory();
-                using var handler = new SocketsHttpHandler()
-                {
-                    ConnectionFactory = connectionFactory
-                };
-                using HttpClient client = CreateHttpClient(handler);
-
-                using var request = new HttpRequestMessage(HttpMethod.Get, uri);
-
-                using HttpResponseMessage response = await client.SendAsync(request);
-                string content = await response.Content.ReadAsStringAsync();
-
-                Assert.Equal("OK", content);
-                Assert.Same(request, connectionFactory.LastHttpRequestMessage);
-            }, server => server.HandleRequestAsync(content: "OK"));
-        }
-    }
-
-    public sealed class SocketsHttpHandler_ConnectionFactoryTest_Http2 : SocketsHttpHandler_ConnectionFactoryTest
-    {
-        public SocketsHttpHandler_ConnectionFactoryTest_Http2(ITestOutputHelper output) : base(output) { }
-        protected override Version UseVersion => HttpVersion.Version20;
-    }
-
     public sealed class SocketsHttpHandler_HttpProtocolTests : HttpProtocolTests
     {
         public SocketsHttpHandler_HttpProtocolTests(ITestOutputHelper output) : base(output) { }
index baea536..75b93f3 100644 (file)
     <Compile Include="Watchdog.cs" />
     <Compile Include="$(CommonTestPath)System\Net\VirtualNetwork\VirtualNetwork.cs" Link="Common\System\Net\VirtualNetwork\VirtualNetwork.cs" />
     <Compile Include="$(CommonTestPath)System\Net\VirtualNetwork\VirtualNetworkStream.cs" Link="Common\System\Net\VirtualNetwork\VirtualNetworkStream.cs" />
-    <Compile Include="$(CommonTestPath)System\Net\VirtualNetwork\VirtualNetworkConnectionListenerFactory.cs" Link="Common\System\Net\VirtualNetwork\VirtualNetworkConnectionListenerFactory.cs" />
   </ItemGroup>
   <!-- Windows specific files -->
   <ItemGroup Condition=" '$(TargetsWindows)' == 'true'">
index 4abc120..899fa7d 100644 (file)
@@ -322,24 +322,6 @@ namespace System.Net
         protected TransportContext() { }
         public abstract System.Security.Authentication.ExtendedProtection.ChannelBinding? GetChannelBinding(System.Security.Authentication.ExtendedProtection.ChannelBindingKind kind);
     }
-    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; } }
-    }
 }
 namespace System.Net.Cache
 {
index 71c6995..d95ea74 100644 (file)
   <data name="bad_endpoint_string" xml:space="preserve">
     <value>An invalid IPEndPoint was specified.</value>
   </data>
-  <data name="networkerror_other" xml:space="preserve">
-    <value>A network error has occured, see InnerException for more details.</value>
-  </data>
-  <data name="networkerror_addressinuse" xml:space="preserve">
-    <value>The requested EndPoint is already in use.</value>
-  </data>
-  <data name="networkerror_connectionrefused" xml:space="preserve">
-    <value>No connection could be made because the remote host actively refused it.</value>
-  </data>
-  <data name="networkerror_hostnotfound" xml:space="preserve">
-    <value>No such host is known.</value>
-  </data>
-  <data name="networkerror_operationaborted" xml:space="preserve">
-    <value>The operation was aborted by the user.</value>
-  </data>
-  <data name="networkerror_connectionaborted" xml:space="preserve">
-    <value>The connection was aborted by the local host.</value>
-  </data>
-  <data name="networkerror_connectionreset" xml:space="preserve">
-    <value>The connection was forcibly closed by the remote host.</value>
-  </data>
-  <data name="networkerror_timedout" xml:space="preserve">
-    <value>The connection attempt has timed out.</value>
-  </data>
 </root>
index 413d76f..07f176a 100644 (file)
@@ -34,8 +34,6 @@
     <Compile Include="System\Net\IWebProxy.cs" />
     <Compile Include="System\Net\NetEventSource.Primitives.cs" />
     <Compile Include="System\Net\NetworkCredential.cs" />
-    <Compile Include="System\Net\NetworkException.cs" />
-    <Compile Include="System\Net\NetworkError.cs" />
     <Compile Include="System\Net\TransportContext.cs" />
     <Compile Include="System\Net\SocketException.cs" />
     <Compile Include="System\Net\SecureProtocols\NegotiateEnumTypes.cs" />
index 215b341..26cd256 100644 (file)
@@ -20,7 +20,6 @@
     <Compile Include="IPEndPointParsing.cs" />
     <Compile Include="IPEndPointTest.cs" />
     <Compile Include="NetworkCredentialTest.cs" />
-    <Compile Include="NetworkExceptionTest.cs" />
     <Compile Include="SocketAddressTest.cs" />
     <Compile Include="LoggingTest.cs" />
     <Compile Include="RequestCachePolicyTest.cs" />
index 9810108..06f2207 100644 (file)
@@ -96,17 +96,18 @@ namespace System.Net
 
         private static WebExceptionStatus GetStatusFromExceptionHelper(HttpRequestException ex)
         {
-            NetworkException? networkException = ex.InnerException as NetworkException;
+            SocketException? socketException = ex.InnerException as SocketException;
 
-            if (networkException is null)
+            if (socketException is null)
             {
                 return WebExceptionStatus.UnknownError;
             }
 
             WebExceptionStatus status;
-            switch (networkException.NetworkError)
+            switch (socketException.SocketErrorCode)
             {
-                case NetworkError.HostNotFound:
+                case SocketError.NoData:
+                case SocketError.HostNotFound:
                     status = WebExceptionStatus.NameResolutionFailure;
                     break;
                 default:
index 4d39c2d..ae0f96d 100644 (file)
@@ -95,8 +95,6 @@
              Link="Common\System\Net\Sockets\ProtocolType.cs" />
     <Compile Include="$(CommonPath)System\Net\Sockets\SocketType.cs"
              Link="Common\System\Net\Sockets\SocketType.cs" />
-    <Compile Include="$(CommonPath)System\Net\NetworkErrorHelper.cs"
-             Link="Common\System\Net\NetworkErrorHelper.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetsWindows)' == 'true'">
     <!-- Windows: CoreCLR -->
index 2eb6a18..7ee46c5 100644 (file)
@@ -50,15 +50,15 @@ namespace System.Net.Sockets
                 // allowing non-blocking sockets could result in non-deterministic failures from those
                 // operations. A developer that requires using NetworkStream with a non-blocking socket can
                 // temporarily flip Socket.Blocking as a workaround.
-                throw GetCustomNetworkException(SR.net_sockets_blocking);
+                throw GetCustomException(SR.net_sockets_blocking);
             }
             if (!socket.Connected)
             {
-                throw GetCustomNetworkException(SR.net_notconnected);
+                throw GetCustomException(SR.net_notconnected);
             }
             if (socket.SocketType != SocketType.Stream)
             {
-                throw GetCustomNetworkException(SR.net_notstream);
+                throw GetCustomException(SR.net_notstream);
             }
 
             _streamSocket = socket;
@@ -243,11 +243,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_readfailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
         }
 
@@ -267,8 +267,8 @@ namespace System.Net.Sockets
             int bytesRead = _streamSocket.Receive(buffer, SocketFlags.None, out SocketError errorCode);
             if (errorCode != SocketError.Success)
             {
-                var exception = new SocketException((int)errorCode);
-                throw NetworkErrorHelper.MapSocketException(exception);
+                var socketException = new SocketException((int)errorCode);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_readfailure, socketException.Message), socketException);
             }
             return bytesRead;
         }
@@ -326,11 +326,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_writefailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
         }
 
@@ -351,8 +351,8 @@ namespace System.Net.Sockets
             _streamSocket.Send(buffer, SocketFlags.None, out SocketError errorCode);
             if (errorCode != SocketError.Success)
             {
-                var exception = new SocketException((int)errorCode);
-                throw NetworkErrorHelper.MapSocketException(exception);
+                var socketException = new SocketException((int)errorCode);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_writefailure, socketException.Message), socketException);
             }
         }
 
@@ -449,11 +449,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_readfailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
         }
 
@@ -481,11 +481,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_readfailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
         }
 
@@ -539,11 +539,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_writefailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
         }
 
@@ -567,11 +567,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_writefailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
         }
 
@@ -623,11 +623,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_readfailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
         }
 
@@ -650,11 +650,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_readfailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
             }
         }
 
@@ -705,11 +705,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_writefailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
         }
 
@@ -731,11 +731,11 @@ namespace System.Net.Sockets
             }
             catch (SocketException socketException)
             {
-                throw NetworkErrorHelper.MapSocketException(socketException);
+                throw GetExceptionFromSocketException(SR.Format(SR.net_io_writefailure, socketException.Message), socketException);
             }
             catch (Exception exception) when (!(exception is OutOfMemoryException))
             {
-                throw GetCustomNetworkException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
+                throw GetCustomException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
             }
         }
 
@@ -793,9 +793,14 @@ namespace System.Net.Sockets
             void ThrowObjectDisposedException() => throw new ObjectDisposedException(GetType().FullName);
         }
 
-        private static NetworkException GetCustomNetworkException(string message, Exception? innerException = null)
+        private static IOException GetExceptionFromSocketException(string message, SocketException innerException)
         {
-            return new NetworkException(message, NetworkError.Other, innerException);
+            return new IOException(message, innerException);
+        }
+
+        private static IOException GetCustomException(string message, Exception? innerException = null)
+        {
+            return new IOException(message, innerException);
         }
     }
 }
index 83b8e3e..5388df7 100644 (file)
@@ -195,7 +195,7 @@ namespace System.Net.Sockets
             Debug.Assert(saea.BufferList == null);
             saea.SetBuffer(buffer);
             saea.SocketFlags = socketFlags;
-            saea.WrapExceptionsInNetworkExceptions = fromNetworkStream;
+            saea.WrapExceptionsForNetworkStream = fromNetworkStream;
             return saea.ReceiveAsync(this, cancellationToken);
         }
 
@@ -278,7 +278,7 @@ namespace System.Net.Sockets
             Debug.Assert(saea.BufferList == null);
             saea.SetBuffer(MemoryMarshal.AsMemory(buffer));
             saea.SocketFlags = socketFlags;
-            saea.WrapExceptionsInNetworkExceptions = false;
+            saea.WrapExceptionsForNetworkStream = false;
             return saea.SendAsync(this, cancellationToken);
         }
 
@@ -296,7 +296,7 @@ namespace System.Net.Sockets
             Debug.Assert(saea.BufferList == null);
             saea.SetBuffer(MemoryMarshal.AsMemory(buffer));
             saea.SocketFlags = socketFlags;
-            saea.WrapExceptionsInNetworkExceptions = true;
+            saea.WrapExceptionsForNetworkStream = true;
             return saea.SendAsyncForNetworkStream(this, cancellationToken);
         }
 
@@ -618,7 +618,7 @@ namespace System.Net.Sockets
                 _isReadForCaching = isReceiveForCaching;
             }
 
-            public bool WrapExceptionsInNetworkExceptions { get; set; }
+            public bool WrapExceptionsForNetworkStream { get; set; }
 
             private void Release()
             {
@@ -926,8 +926,8 @@ namespace System.Net.Sockets
                     e = ExceptionDispatchInfo.SetCurrentStackTrace(e);
                 }
 
-                return WrapExceptionsInNetworkExceptions ?
-                    NetworkErrorHelper.MapSocketException((SocketException)e) :
+                return WrapExceptionsForNetworkStream ?
+                    new IOException(SR.Format(_isReadForCaching ? SR.net_io_readfailure : SR.net_io_writefailure, e.Message), e) :
                     e;
             }
         }
index fb29385..da51240 100644 (file)
@@ -25,25 +25,25 @@ namespace System.Net.Sockets.Tests
         }
 
         [Fact]
-        public void Ctor_NotConnected_ThrowsNetworkException()
+        public void Ctor_NotConnected_Throws()
         {
-            Assert.Throws<NetworkException>(() => new NetworkStream(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)));
+            Assert.Throws<IOException>(() => new NetworkStream(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)));
         }
 
         [Fact]
-        public async Task Ctor_NotStream_ThrowsNetworkException()
+        public async Task Ctor_NotStream_Throws()
         {
             using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
             using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
             {
                 listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
                 await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)listener.LocalEndPoint).Port));
-                Assert.Throws<NetworkException>(() => new NetworkStream(client));
+                Assert.Throws<IOException>(() => new NetworkStream(client));
             }
         }
 
         [Fact]
-        public async Task Ctor_NonBlockingSocket_ThrowsNetworkException()
+        public async Task Ctor_NonBlockingSocket_Throws()
         {
             using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
             using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
@@ -56,7 +56,7 @@ namespace System.Net.Sockets.Tests
                 using (Socket server = await acceptTask)
                 {
                     server.Blocking = false;
-                    Assert.Throws<NetworkException>(() => new NetworkStream(server));
+                    Assert.Throws<IOException>(() => new NetworkStream(server));
                 }
             }
         }
@@ -186,7 +186,7 @@ namespace System.Net.Sockets.Tests
                         }
                         else if (ownsSocket)
                         {
-                            Assert.IsType<NetworkException>(e);
+                            Assert.IsType<IOException>(e);
                         }
                         else
                         {
@@ -317,14 +317,14 @@ namespace System.Net.Sockets.Tests
                 {
                     serverSocket.Dispose();
 
-                    Assert.Throws<NetworkException>(() => server.Read(new byte[1], 0, 1));
-                    Assert.Throws<NetworkException>(() => server.Write(new byte[1], 0, 1));
+                    Assert.Throws<IOException>(() => server.Read(new byte[1], 0, 1));
+                    Assert.Throws<IOException>(() => server.Write(new byte[1], 0, 1));
 
-                    Assert.Throws<NetworkException>(() => server.BeginRead(new byte[1], 0, 1, null, null));
-                    Assert.Throws<NetworkException>(() => server.BeginWrite(new byte[1], 0, 1, null, null));
+                    Assert.Throws<IOException>(() => server.BeginRead(new byte[1], 0, 1, null, null));
+                    Assert.Throws<IOException>(() => server.BeginWrite(new byte[1], 0, 1, null, null));
 
-                    Assert.Throws<NetworkException>(() => { server.ReadAsync(new byte[1], 0, 1); });
-                    Assert.Throws<NetworkException>(() => { server.WriteAsync(new byte[1], 0, 1); });
+                    Assert.Throws<IOException>(() => { server.ReadAsync(new byte[1], 0, 1); });
+                    Assert.Throws<IOException>(() => { server.WriteAsync(new byte[1], 0, 1); });
                 }
             }
         }
@@ -334,8 +334,8 @@ namespace System.Net.Sockets.Tests
         {
             await RunWithConnectedNetworkStreamsAsync((server, _) =>
             {
-                Assert.Throws<NetworkException>(() => server.EndRead(Task.CompletedTask));
-                Assert.Throws<NetworkException>(() => server.EndWrite(Task.CompletedTask));
+                Assert.Throws<IOException>(() => server.EndRead(Task.CompletedTask));
+                Assert.Throws<IOException>(() => server.EndWrite(Task.CompletedTask));
                 return Task.CompletedTask;
             });
         }
@@ -579,14 +579,14 @@ namespace System.Net.Sockets.Tests
 
         [OuterLoop("Timeouts")]
         [Fact]
-        public async Task ReadTimeout_Expires_ThrowsSocketException()
+        public async Task ReadTimeout_Expires_Throws()
         {
             await RunWithConnectedNetworkStreamsAsync((server, client) =>
             {
                 Assert.Equal(-1, server.ReadTimeout);
 
                 server.ReadTimeout = 1;
-                Assert.ThrowsAny<NetworkException>(() => server.Read(new byte[1], 0, 1));
+                Assert.ThrowsAny<IOException>(() => server.Read(new byte[1], 0, 1));
 
                 return Task.CompletedTask;
             });
@@ -713,8 +713,8 @@ namespace System.Net.Sockets.Tests
                 // before that takes effect, it may also complete as aborted.
                 bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
                 Assert.True(
-                    (isWindows && e is NetworkException) ||
-                    (!isWindows && (e == null || e is NetworkException)),
+                    (isWindows && e is IOException) ||
+                    (!isWindows && (e == null || e is IOException)),
                     $"Got unexpected exception: {e?.ToString() ?? "(null)"}");
 
                 // Copying after disposing the stream
index 6457475..49b7804 100644 (file)
         "4.6.0"
       ],
       "BaselineVersion": "6.0.0",
-      "InboxOn": {
-        "net5.0": "5.0.0.0"
-      },
+      "InboxOn": {},
       "AssemblyVersionInPackageVersion": {
         "4.0.0.0": "4.5.0",
         "4.0.0.1": "4.5.2",
       "System.Xml.XDocument"
     ]
   }
-}
\ No newline at end of file
+}