From d3372f1940d36c2990d1fbb70b7e28d077949126 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 10 Nov 2022 18:14:51 -0600 Subject: [PATCH] Allow DecompressionHandler to be trimmed when the application isn't using AutomaticDecompression in HttpClient. This allow for the Brotli compression code to be trimmed in a NativeAOT app that uses HttpClient, which is about 1 MB of size savings on Linux. --- .../SocketsHttpHandler/SocketsHttpHandler.cs | 12 +++++- .../DecompressionHandlerTrimmedTest.cs | 37 +++++++++++++++++++ .../System.Net.Http.TrimmingTests.proj | 1 + 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Net.Http/tests/TrimmingTests/DecompressionHandlerTrimmedTest.cs 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 1e89bfc19de7..3553e0890552 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 000000000000..56df6f10052c --- /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 d1de6e68e349..ca55774a5ac4 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