diff --git a/eng/versioning.targets b/eng/versioning.targets index 02a10237e412b8..9c4e3ea8119c73 100644 --- a/eng/versioning.targets +++ b/eng/versioning.targets @@ -59,21 +59,28 @@ <_unsupportedOSPlatforms Include="$(UnsupportedOSPlatforms)" /> + <_supportedOSPlatforms Include="$(SupportedOSPlatforms)" /> - - - + + <_Parameter1>%(_unsupportedOSPlatforms.Identity) + + + + <_Parameter1>%(_supportedOSPlatforms.Identity) + + diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 201d0acd63e5de..d210bf53503281 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -19,7 +19,6 @@ - @@ -662,20 +661,6 @@ - - - PreserveNewest - PreserveNewest - - - PreserveNewest - PreserveNewest - - - PreserveNewest - PreserveNewest - - diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs index f3a58a37164eb3..b26f927d7e4ddf 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs @@ -7,6 +7,7 @@ using System.Net.Quic.Implementations; using System.Net.Security; using System.Net.Sockets; +using System.Runtime.Versioning; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -100,6 +101,10 @@ private static async ValueTask EstablishSslConnectionAsyncCore(bool a return sslStream; } + // TODO: SupportedOSPlatform doesn't work for internal APIs https://github.com/dotnet/runtime/issues/51305 + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + [SupportedOSPlatform("macos")] public static async ValueTask ConnectQuicAsync(QuicImplementationProvider quicImplementationProvider, DnsEndPoint endPoint, SslClientAuthenticationOptions? clientAuthenticationOptions, CancellationToken cancellationToken) { QuicConnection con = new QuicConnection(quicImplementationProvider, endPoint, clientAuthenticationOptions); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs index 6eb28b57543a97..4b1f6ff2d4feed 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using System.Runtime.CompilerServices; +using System.Runtime.Versioning; using System.Net.Quic; using System.IO; using System.Collections.Generic; @@ -13,6 +14,10 @@ namespace System.Net.Http { + // TODO: SupportedOSPlatform doesn't work for internal APIs https://github.com/dotnet/runtime/issues/51305 + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + [SupportedOSPlatform("macos")] internal sealed class Http3Connection : HttpConnectionBase, IDisposable { // TODO: once HTTP/3 is standardized, create APIs for this. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ConnectionException.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ConnectionException.cs index 3f4eb64ad7f064..caa666a0afc285 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ConnectionException.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ConnectionException.cs @@ -2,10 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.Serialization; +using System.Runtime.Versioning; namespace System.Net.Http { [Serializable] + // TODO: SupportedOSPlatform doesn't work for internal APIs https://github.com/dotnet/runtime/issues/51305 + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + [SupportedOSPlatform("macos")] internal sealed class Http3ConnectionException : Http3ProtocolException { public Http3ConnectionException(Http3ErrorCode errorCode) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ProtocolException.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ProtocolException.cs index e03fd4cb5356c9..829c08f2468ae1 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ProtocolException.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3ProtocolException.cs @@ -2,10 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.Serialization; +using System.Runtime.Versioning; namespace System.Net.Http { [Serializable] + // TODO: SupportedOSPlatform doesn't work for internal APIs https://github.com/dotnet/runtime/issues/51305 + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + [SupportedOSPlatform("macos")] internal class Http3ProtocolException : Exception { public Http3ErrorCode ErrorCode { get; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs index 2e6bea241c8254..c48fc862a5014c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs @@ -10,11 +10,16 @@ using System.Threading; using System.Threading.Tasks; using System.Runtime.CompilerServices; +using System.Runtime.Versioning; using System.Net.Http.QPack; using System.Runtime.ExceptionServices; namespace System.Net.Http { + // TODO: SupportedOSPlatform doesn't work for internal APIs https://github.com/dotnet/runtime/issues/51305 + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + [SupportedOSPlatform("macos")] internal sealed class Http3RequestStream : IHttpHeadersHandler, IAsyncDisposable, IDisposable { private readonly HttpRequestMessage _request; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs index aa4f860cc48b9e..a370f4095cabbf 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs @@ -14,6 +14,7 @@ using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using System.Security.Authentication; using System.Text; using System.Threading; @@ -119,7 +120,11 @@ public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionK } _http2Enabled = _poolManager.Settings._maxHttpVersion >= HttpVersion.Version20; - _http3Enabled = _poolManager.Settings._maxHttpVersion >= HttpVersion.Version30 && (_poolManager.Settings._quicImplementationProvider ?? QuicImplementationProviders.Default).IsSupported; + // TODO: Replace with Platform-Guard Assertion Annotations once https://github.com/dotnet/runtime/issues/44922 is finished + if ((OperatingSystem.IsLinux() && !OperatingSystem.IsAndroid()) || OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) + { + _http3Enabled = _poolManager.Settings._maxHttpVersion >= HttpVersion.Version30 && (_poolManager.Settings._quicImplementationProvider ?? QuicImplementationProviders.Default).IsSupported; + } switch (kind) { @@ -240,10 +245,14 @@ public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionK _http3EncodedAuthorityHostHeader = QPackEncoder.EncodeLiteralHeaderFieldWithStaticNameReferenceToArray(H3StaticTable.Authority, hostHeader); } - if (_http3Enabled) + // TODO: Replace with Platform-Guard Assertion Annotations once https://github.com/dotnet/runtime/issues/44922 is finished + if ((OperatingSystem.IsLinux() && !OperatingSystem.IsAndroid()) || OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) { - _sslOptionsHttp3 = ConstructSslOptions(poolManager, sslHostName); - _sslOptionsHttp3.ApplicationProtocols = s_http3ApplicationProtocols; + if (_http3Enabled) + { + _sslOptionsHttp3 = ConstructSslOptions(poolManager, sslHostName); + _sslOptionsHttp3.ApplicationProtocols = s_http3ApplicationProtocols; + } } } @@ -256,10 +265,22 @@ public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionK if (NetEventSource.Log.IsEnabled()) Trace($"{this}"); } - private static readonly List s_http3ApplicationProtocols = new List() { Http3Connection.Http3ApplicationProtocol31, Http3Connection.Http3ApplicationProtocol30, Http3Connection.Http3ApplicationProtocol29 }; + private static readonly List s_http3ApplicationProtocols = CreateHttp3ApplicationProtocols(); private static readonly List s_http2ApplicationProtocols = new List() { SslApplicationProtocol.Http2, SslApplicationProtocol.Http11 }; private static readonly List s_http2OnlyApplicationProtocols = new List() { SslApplicationProtocol.Http2 }; + private static List CreateHttp3ApplicationProtocols() + { + // TODO: Replace with Platform-Guard Assertion Annotations once https://github.com/dotnet/runtime/issues/44922 is finished + if ((OperatingSystem.IsLinux() && !OperatingSystem.IsAndroid()) || OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) + { + // TODO: Once the HTTP/3 versions are part of SslApplicationProtocol, see https://github.com/dotnet/runtime/issues/1293, move this back to field initialization. + return new List() { Http3Connection.Http3ApplicationProtocol31, Http3Connection.Http3ApplicationProtocol30, Http3Connection.Http3ApplicationProtocol29 }; + } + + return null!; + } + private static SslClientAuthenticationOptions ConstructSslOptions(HttpConnectionPoolManager poolManager, string sslHostName) { Debug.Assert(sslHostName != null); @@ -352,24 +373,28 @@ public byte[] Http2AltSvcOriginUri } } - // Either H3 explicitly requested or secured upgraded allowed. - if (_http3Enabled && (request.Version.Major >= 3 || (request.VersionPolicy == HttpVersionPolicy.RequestVersionOrHigher && IsSecure))) + // TODO: Replace with Platform-Guard Assertion Annotations once https://github.com/dotnet/runtime/issues/44922 is finished + if ((OperatingSystem.IsLinux() && !OperatingSystem.IsAndroid()) || OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) { - HttpAuthority? authority = _http3Authority; - // H3 is explicitly requested, assume prenegotiated H3. - if (request.Version.Major >= 3 && request.VersionPolicy != HttpVersionPolicy.RequestVersionOrLower) + // Either H3 explicitly requested or secured upgraded allowed. + if (_http3Enabled && (request.Version.Major >= 3 || (request.VersionPolicy == HttpVersionPolicy.RequestVersionOrHigher && IsSecure))) { - authority = authority ?? _originAuthority; - } - if (authority != null) - { - if (IsAltSvcBlocked(authority)) + HttpAuthority? authority = _http3Authority; + // H3 is explicitly requested, assume prenegotiated H3. + if (request.Version.Major >= 3 && request.VersionPolicy != HttpVersionPolicy.RequestVersionOrLower) { - return ValueTask.FromException<(HttpConnectionBase connection, bool isNewConnection)>( - new HttpRequestException(SR.Format(SR.net_http_requested_version_cannot_establish, request.Version, request.VersionPolicy, 3))); + authority = authority ?? _originAuthority; } + if (authority != null) + { + if (IsAltSvcBlocked(authority)) + { + return ValueTask.FromException<(HttpConnectionBase connection, bool isNewConnection)>( + new HttpRequestException(SR.Format(SR.net_http_requested_version_cannot_establish, request.Version, request.VersionPolicy, 3))); + } - return GetHttp3ConnectionAsync(request, authority, cancellationToken); + return GetHttp3ConnectionAsync(request, authority, cancellationToken); + } } } @@ -719,6 +744,10 @@ private void AddHttp2Connection(Http2Connection newConnection) } } + // TODO: SupportedOSPlatform doesn't work for internal APIs https://github.com/dotnet/runtime/issues/51305 + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + [SupportedOSPlatform("macos")] private async ValueTask<(HttpConnectionBase connection, bool isNewConnection)> GetHttp3ConnectionAsync(HttpRequestMessage request, HttpAuthority authority, CancellationToken cancellationToken) { @@ -891,14 +920,18 @@ public async ValueTask SendWithRetryAsync(HttpRequestMessag HandleAltSvc(altSvcHeaderValues, response.Headers.Age); } - // If an Alt-Svc authority returns 421, it means it can't actually handle the request. - // An authority is supposed to be able to handle ALL requests to the origin, so this is a server bug. - // In this case, we blocklist the authority and retry the request at the origin. - if (response.StatusCode == HttpStatusCode.MisdirectedRequest && connection is Http3Connection h3Connection && h3Connection.Authority != _originAuthority) + // TODO: Replace with Platform-Guard Assertion Annotations once https://github.com/dotnet/runtime/issues/44922 is finished + if ((OperatingSystem.IsLinux() && !OperatingSystem.IsAndroid()) || OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) { - response.Dispose(); - BlocklistAuthority(h3Connection.Authority); - continue; + // If an Alt-Svc authority returns 421, it means it can't actually handle the request. + // An authority is supposed to be able to handle ALL requests to the origin, so this is a server bug. + // In this case, we blocklist the authority and retry the request at the origin. + if (response.StatusCode == HttpStatusCode.MisdirectedRequest && connection is Http3Connection h3Connection && h3Connection.Authority != _originAuthority) + { + response.Dispose(); + BlocklistAuthority(h3Connection.Authority); + continue; + } } return response; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs index 88e70ede696e12..cf81a5d5a2929a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionSettings.cs @@ -6,6 +6,7 @@ using System.IO; using System.Net.Quic; using System.Net.Quic.Implementations; +using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -86,7 +87,7 @@ public HttpConnectionSettings CloneAndNormalize() _cookieContainer = new CookieContainer(); } - return new HttpConnectionSettings() + var settings = new HttpConnectionSettings() { _allowAutoRedirect = _allowAutoRedirect, _automaticDecompression = _automaticDecompression, @@ -118,9 +119,17 @@ public HttpConnectionSettings CloneAndNormalize() _responseHeaderEncodingSelector = _responseHeaderEncodingSelector, _enableMultipleHttp2Connections = _enableMultipleHttp2Connections, _connectCallback = _connectCallback, - _plaintextStreamFilter = _plaintextStreamFilter, - _quicImplementationProvider = _quicImplementationProvider + _plaintextStreamFilter = _plaintextStreamFilter }; + + // TODO: Replace with Platform-Guard Assertion Annotations once https://github.com/dotnet/runtime/issues/44922 is finished + // TODO: Remove if/when QuicImplementationProvider is removed from System.Net.Quic. + if ((OperatingSystem.IsLinux() && !OperatingSystem.IsAndroid()) || OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) + { + settings._quicImplementationProvider = _quicImplementationProvider; + } + + return settings; } private static bool AllowHttp2 @@ -178,6 +187,11 @@ private static bool AllowDraftHttp3 public bool EnableMultipleHttp2Connections => _enableMultipleHttp2Connections; private byte[]? _http3SettingsFrame; + + // TODO: SupportedOSPlatform doesn't work for internal APIs https://github.com/dotnet/runtime/issues/51305 + [SupportedOSPlatform("windows")] + [SupportedOSPlatform("linux")] + [SupportedOSPlatform("macos")] internal byte[] Http3SettingsFrame => _http3SettingsFrame ??= Http3Connection.BuildSettingsFrame(this); } } diff --git a/src/libraries/System.Net.Http/tests/TrimmingTests/HttpClientTest.cs b/src/libraries/System.Net.Http/tests/TrimmingTests/HttpClientTest.cs new file mode 100644 index 00000000000000..c05cac77920e66 --- /dev/null +++ b/src/libraries/System.Net.Http/tests/TrimmingTests/HttpClientTest.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using System.Net.Http; +using System.Threading.Tasks; + +class Program +{ + static async Task Main(string[] args) + { + using var client = new HttpClient(); + using var response = await client.GetAsync("https://www.microsoft.com"); + var result = await response.Content.ReadAsStringAsync(); + Console.WriteLine(result); + + const string quicDll = "System.Net.Quic.dll"; + var quicDllExists = File.Exists(Path.Combine(AppContext.BaseDirectory, quicDll)); + + // TODO: Replace with Platform-Guard Assertion Annotations once https://github.com/dotnet/runtime/issues/44922 is finished + if ((OperatingSystem.IsLinux() && !OperatingSystem.IsAndroid()) || OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) + { + Console.WriteLine($"Expected {quicDll} is {(quicDllExists ? "present - OK" : "missing - BAD")}."); + return quicDllExists ? 100 : -1; + } + else + { + Console.WriteLine($"Unexpected {quicDll} is {(quicDllExists ? "present - BAD" : "missing - OK")}."); + return quicDllExists ? -1 : 100; + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Net.Http/tests/TrimmingTests/System.Net.Http.TrimmingTests.proj b/src/libraries/System.Net.Http/tests/TrimmingTests/System.Net.Http.TrimmingTests.proj new file mode 100644 index 00000000000000..d1de6e68e349b5 --- /dev/null +++ b/src/libraries/System.Net.Http/tests/TrimmingTests/System.Net.Http.TrimmingTests.proj @@ -0,0 +1,11 @@ + + + + + + browser-wasm + + + + + diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpClientHandler.cs b/src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpClientHandler.cs index 808feeae13eab0..595a99685aca90 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpClientHandler.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Fakes/HttpClientHandler.cs @@ -11,112 +11,105 @@ namespace System.Net.Http { public class HttpClientHandler : HttpMessageHandler { + public const string Message = "HTTP stack not implemented"; + #region Properties public virtual bool SupportsAutomaticDecompression { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } } public virtual bool SupportsProxy { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } } public virtual bool SupportsRedirectConfiguration { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } } public bool UseCookies { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public CookieContainer CookieContainer { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public ClientCertificateOption ClientCertificateOptions { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public DecompressionMethods AutomaticDecompression { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public bool UseProxy { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public IWebProxy Proxy { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public bool PreAuthenticate { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public bool UseDefaultCredentials { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public ICredentials Credentials { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public bool AllowAutoRedirect { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public int MaxAutomaticRedirections { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } public long MaxRequestContentBufferSize { - get { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } - set { throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); } + get { throw NotImplemented.ByDesignWithMessage(Message); } + set { throw NotImplemented.ByDesignWithMessage(Message); } } #endregion Properties - #region De/Constructors - - public HttpClientHandler() - { - throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); - } - - #endregion De/Constructors - #region Request Execution protected internal override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - throw NotImplemented.ByDesignWithMessage("HTTP stack not implemented"); + throw NotImplemented.ByDesignWithMessage(Message); } #endregion Request Execution diff --git a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj index 30aeeab7d2b8d6..9476e3c5637021 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/UnitTests/System.Net.Http.Unit.Tests.csproj @@ -42,6 +42,10 @@ Link="ProductionCode\Common\System\Net\UriScheme.cs" /> + + Microsoft true + windows;linux;macos - \ No newline at end of file +