From 5747713f9953b8828fb9ce3eec75a4d841c0f594 Mon Sep 17 00:00:00 2001 From: "Namhyeon, Go" Date: Sun, 7 Dec 2025 00:23:51 +0900 Subject: [PATCH] ntroduce separate HttpClient instances for raw and compressed HTTP transfer modes Added two HttpClient instances to distinguish between legacy (no Accept-Encoding) and modern compressed HTTP transfer behaviors. - LegacyHttp: Sends no Accept-Encoding header. Used when requesting .dll.gz files, ensuring that the server delivers the file exactly as-is without applying HTTP-level compression. - Http: Enables AutomaticDecompression and advertises Accept-Encoding (gzip, deflate). When the server supports HTTP content compression, even a regular .dll file can be transmitted in compressed form and transparently decompressed by the client. This separation prevents ambiguities between: - File-level compression (.dll.gz) - Transport-level compression (Content-Encoding: gzip/deflate) and ensures predictable behavior when downloading assemblies depending on server capabilities. --- .../WelsonJS.Launcher/AssemblyLoader.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/WelsonJS.Toolkit/WelsonJS.Launcher/AssemblyLoader.cs b/WelsonJS.Toolkit/WelsonJS.Launcher/AssemblyLoader.cs index 8d0873c..1a52248 100644 --- a/WelsonJS.Toolkit/WelsonJS.Launcher/AssemblyLoader.cs +++ b/WelsonJS.Toolkit/WelsonJS.Launcher/AssemblyLoader.cs @@ -1,6 +1,6 @@ // AssemblyLoader.cs // SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors +// SPDX-FileCopyrightText: Namhyeon Go , 2025 Catswords OSS and WelsonJS Contributors // https://github.com/gnh1201/welsonjs // using System; @@ -36,10 +36,23 @@ namespace WelsonJS.Launcher private static bool _registered; private static readonly string LoaderNamespace = typeof(AssemblyLoader).Namespace ?? "WelsonJS.Launcher"; - private static readonly HttpClient Http = new HttpClient + private static readonly HttpClientHandler LegacyHttpHandler = new HttpClientHandler(); + private static readonly HttpClientHandler HttpHandler = new HttpClientHandler { - Timeout = TimeSpan.FromSeconds(300) // 5 minutes + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; + private static readonly HttpClient LegacyHttp = CreateClient(LegacyHttpHandler); // No the Accept-Encoding (e.g., gzip, deflate) header + private static readonly HttpClient Http = CreateClient(HttpHandler); // With the Accept-Encoding (e.g., gzip, deflate) header + + private static HttpClient CreateClient(HttpMessageHandler handler) + { + var client = new HttpClient(handler, disposeHandler: false) + { + Timeout = TimeSpan.FromSeconds(300) // 5 minutes + }; + + return client; + } // -------------------- kernel32 native loading -------------------- @@ -327,9 +340,9 @@ namespace WelsonJS.Launcher bool isDll = url.EndsWith(".dll", StringComparison.OrdinalIgnoreCase); // *.dll.gz bool downloaded = false; - if (isDll && TryDownloadGzipToFile(gzUrl, dest)) + if (isDll && TryDownloadCompressedFile(gzUrl, dest)) { - Logger.Info("Downloaded and decompressed gzip file to: {0}", dest); + Logger.Info("Downloaded and decompressed file to: {0}", dest); downloaded = true; } @@ -365,13 +378,13 @@ namespace WelsonJS.Launcher } - private static bool TryDownloadGzipToFile(string gzUrl, string dest) + private static bool TryDownloadCompressedFile(string gzUrl, string dest) { string tempFile = dest + ".tmp"; try { - using (var res = Http.GetAsync(gzUrl).GetAwaiter().GetResult()) + using (var res = LegacyHttp.GetAsync(gzUrl).GetAwaiter().GetResult()) { if (res.StatusCode == HttpStatusCode.NotFound) return false;