System.IO.FileSystem.Watcher;
System.IO.IsolatedStorage;
System.IO.MemoryMappedFiles;
- System.IO.Pipelines;
System.IO.Pipes;
System.IO.Pipes.AccessControl;
System.IO.UnmanagedMemoryStream;
System.Linq.Parallel;
System.Linq.Queryable;
System.Memory;
- System.Net.Connections;
System.Net.Http;
System.Net.Http.Json;
System.Net.HttpListener;
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; } }
+ }
+}
<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>
/// <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}";
}
}
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)]
<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>
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 { } }
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 { } }
<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" />
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" />
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
-using System.Net.Connections;
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
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;
}
}
- 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)
{
}
}
- 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();
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)
{
+++ /dev/null
-// 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;
- }
- }
-}
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;
{
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;
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);
GC.SuppressFinalize(this);
// Do shutdown.
- _connection.Dispose();
+ _stream.Dispose();
_connectionWindow.Dispose();
_concurrentStreams.Dispose();
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;
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;
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];
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.
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;
}
// Try to establish an HTTP2 connection
- Connection? connection = null;
+ Stream? stream = null;
SslStream? sslStream = null;
TransportContext? transportContext = null;
HttpResponseMessage? failureResponse;
- (connection, transportContext, failureResponse) =
+ (stream, transportContext, failureResponse) =
await ConnectAsync(request, async, cancellationToken).ConfigureAwait(false);
if (failureResponse != null)
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);
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);
if (canUse)
{
- return (ConstructHttp11Connection(connection!, transportContext), true, null);
+ return (ConstructHttp11Connection(stream!, transportContext), true, null);
}
else
{
Trace("Discarding downgraded HTTP/1.1 connection because connection limit is exceeded");
}
- await connection!.CloseAsync(ConnectionCloseMethod.GracefulShutdown, cancellationToken).ConfigureAwait(false);
+ stream!.Dispose();
}
}
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.
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.
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
{
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)
return (null, failureResponse);
}
- return (ConstructHttp11Connection(connection!, transportContext), null);
+ return (ConstructHttp11Connection(stream!, transportContext), null);
}
private SslClientAuthenticationOptions GetSslOptionsForRequest(HttpRequestMessage request)
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.
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>
// 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;
internal bool _enableMultipleHttp2Connections;
- internal ConnectionFactory? _connectionFactory;
- internal Func<HttpRequestMessage, Connection, CancellationToken, ValueTask<Connection>>? _plaintextFilter;
-
internal IDictionary<string, object?>? _properties;
public HttpConnectionSettings()
_requestHeaderEncodingSelector = _requestHeaderEncodingSelector,
_responseHeaderEncodingSelector = _responseHeaderEncodingSelector,
_enableMultipleHttp2Connections = _enableMultipleHttp2Connections,
- _connectionFactory = _connectionFactory,
- _plaintextFilter = _plaintextFilter
};
}
--- /dev/null
+// 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;
+ }
+ }
+}
using System.Collections.Generic;
using System.Diagnostics;
-using System.Net.Connections;
using System.Net.Security;
using System.Threading;
using System.Threading.Tasks;
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?>());
// 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;
}
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;
}
}
- 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) { }
<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'">
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
{
<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>
<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" />
<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" />
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:
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 -->
// 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;
}
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);
}
}
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;
}
}
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);
}
}
_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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
}
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);
}
}
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);
}
}
}
Debug.Assert(saea.BufferList == null);
saea.SetBuffer(buffer);
saea.SocketFlags = socketFlags;
- saea.WrapExceptionsInNetworkExceptions = fromNetworkStream;
+ saea.WrapExceptionsForNetworkStream = fromNetworkStream;
return saea.ReceiveAsync(this, cancellationToken);
}
Debug.Assert(saea.BufferList == null);
saea.SetBuffer(MemoryMarshal.AsMemory(buffer));
saea.SocketFlags = socketFlags;
- saea.WrapExceptionsInNetworkExceptions = false;
+ saea.WrapExceptionsForNetworkStream = false;
return saea.SendAsync(this, cancellationToken);
}
Debug.Assert(saea.BufferList == null);
saea.SetBuffer(MemoryMarshal.AsMemory(buffer));
saea.SocketFlags = socketFlags;
- saea.WrapExceptionsInNetworkExceptions = true;
+ saea.WrapExceptionsForNetworkStream = true;
return saea.SendAsyncForNetworkStream(this, cancellationToken);
}
_isReadForCaching = isReceiveForCaching;
}
- public bool WrapExceptionsInNetworkExceptions { get; set; }
+ public bool WrapExceptionsForNetworkStream { get; set; }
private void Release()
{
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;
}
}
}
[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))
using (Socket server = await acceptTask)
{
server.Blocking = false;
- Assert.Throws<NetworkException>(() => new NetworkStream(server));
+ Assert.Throws<IOException>(() => new NetworkStream(server));
}
}
}
}
else if (ownsSocket)
{
- Assert.IsType<NetworkException>(e);
+ Assert.IsType<IOException>(e);
}
else
{
{
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); });
}
}
}
{
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;
});
}
[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;
});
// 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
"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
+}