diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs index 1e89bfc19de7f3..3553e0890552ad 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SocketsHttpHandler.cs @@ -18,6 +18,7 @@ public sealed class SocketsHttpHandler : HttpMessageHandler { private readonly HttpConnectionSettings _settings = new HttpConnectionSettings(); private HttpMessageHandlerStage? _handler; + private Func? _decompressionHandlerFactory; private bool _disposed; private void CheckDisposedOrStarted() @@ -62,6 +63,7 @@ public DecompressionMethods AutomaticDecompression set { CheckDisposedOrStarted(); + EnsureDecompressionHandlerFactory(); _settings._automaticDecompression = value; } } @@ -511,7 +513,8 @@ private HttpMessageHandlerStage SetupHandlerChain() if (settings._automaticDecompression != DecompressionMethods.None) { - handler = new DecompressionHandler(settings._automaticDecompression, handler); + Debug.Assert(_decompressionHandlerFactory is not null); + handler = _decompressionHandlerFactory(settings, handler); } // Ensure a single handler is used for all requests. @@ -523,6 +526,13 @@ private HttpMessageHandlerStage SetupHandlerChain() return _handler; } + // Allows for DecompressionHandler (and its compression dependencies) to be trimmed when + // AutomaticDecompression is not being used. + private void EnsureDecompressionHandlerFactory() + { + _decompressionHandlerFactory ??= (settings, handler) => new DecompressionHandler(settings._automaticDecompression, handler); + } + protected internal override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { diff --git a/src/libraries/System.Net.Http/tests/TrimmingTests/DecompressionHandlerTrimmedTest.cs b/src/libraries/System.Net.Http/tests/TrimmingTests/DecompressionHandlerTrimmedTest.cs new file mode 100644 index 00000000000000..56df6f10052c7a --- /dev/null +++ b/src/libraries/System.Net.Http/tests/TrimmingTests/DecompressionHandlerTrimmedTest.cs @@ -0,0 +1,37 @@ +// 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.Runtime.Versioning; +using System.Threading.Tasks; + +class Program +{ + static async Task Main(string[] args) + { + using HttpClient client = new(); + + // send a request, but ignore its result + try + { + await client.GetAsync("https://www.microsoft.com"); + } + catch { } + + Type decompressionHandler = GetHttpType("System.Net.Http.DecompressionHandler"); + + // DecompressionHandler should have been trimmed since AutomaticDecompression was not used + if (decompressionHandler is not null) + { + return -1; + } + + return 100; + } + + // The intention of this method is to ensure the trimmer doesn't preserve the Type. + private static Type GetHttpType(string name) => + typeof(HttpClient).Assembly.GetType(name, throwOnError: false); +} 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 index d1de6e68e349b5..ca55774a5ac45d 100644 --- 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 @@ -2,6 +2,7 @@ + browser-wasm