diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ade708b91..00660228c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## v1.34.3 +### Bugfixes + +- [Core] Oops, `HttpClient` actually sucks (#3960 by: HebaruSan) + ### Internal - [Netkan] Re-sort module properties after merging (#3957 by: HebaruSan) diff --git a/Cmdline/CKAN-cmdline.csproj b/Cmdline/CKAN-cmdline.csproj index 43245ee6e5..12819a8ecd 100644 --- a/Cmdline/CKAN-cmdline.csproj +++ b/Cmdline/CKAN-cmdline.csproj @@ -24,7 +24,7 @@ 512 prompt 4 - IDE1006 + IDE1006,NU1701 PrepareResources;$(CompileDependsOn) diff --git a/Core/Games/KerbalSpaceProgram.cs b/Core/Games/KerbalSpaceProgram.cs index 969e11ae1c..b767fd556a 100644 --- a/Core/Games/KerbalSpaceProgram.cs +++ b/Core/Games/KerbalSpaceProgram.cs @@ -266,34 +266,34 @@ public GameVersion DetectVersion(DirectoryInfo where) public Uri MetadataBugtrackerURL => new Uri("https://github.com/KSP-CKAN/NetKAN/issues/new/choose"); - private string Missions(GameInstance inst) + private static string Missions(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(inst.GameDir(), "Missions")); - private string Ships(GameInstance inst) + private static string Ships(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(inst.GameDir(), "Ships")); - private string ShipsVab(GameInstance inst) + private static string ShipsVab(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(Ships(inst), "VAB")); - private string ShipsSph(GameInstance inst) + private static string ShipsSph(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(Ships(inst), "SPH")); - private string ShipsThumbs(GameInstance inst) + private static string ShipsThumbs(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(Ships(inst), "@thumbs")); - private string ShipsThumbsSPH(GameInstance inst) + private static string ShipsThumbsSPH(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(ShipsThumbs(inst), "SPH")); - private string ShipsThumbsVAB(GameInstance inst) + private static string ShipsThumbsVAB(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(ShipsThumbs(inst), "VAB")); - private string ShipsScript(GameInstance inst) + private static string ShipsScript(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(Ships(inst), "Script")); - private string Tutorial(GameInstance inst) + private static string Tutorial(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(inst.GameDir(), "saves", "training")); - private string Scenarios(GameInstance inst) + private static string Scenarios(GameInstance inst) => CKANPathUtils.NormalizePath(Path.Combine(inst.GameDir(), "saves", "scenarios")); private readonly Dictionary allowedFolders = new Dictionary @@ -343,7 +343,7 @@ private static string KSPDirectory(string steamPath) /// /// args or args minus parameter /// - private string[] filterCmdLineArgs(string[] args, GameVersion installedVersion, GameVersionRange crashyKspRange, string parameter) + private static string[] filterCmdLineArgs(string[] args, GameVersion installedVersion, GameVersionRange crashyKspRange, string parameter) { var installedRange = installedVersion.ToVersionRange(); if (crashyKspRange.IntersectWith(installedRange) != null diff --git a/Core/Net/Net.cs b/Core/Net/Net.cs index 8167c45208..4c0608f487 100644 --- a/Core/Net/Net.cs +++ b/Core/Net/Net.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using System.Net; -using System.Net.Http; using System.Text.RegularExpressions; using System.Threading; @@ -46,27 +45,17 @@ public static class Net /// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag /// public static string CurrentETag(Uri url) - => httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, url), - HttpCompletionOption.ResponseHeadersRead) - .Result - .Headers.ETag.ToString() - .Replace("\"", ""); - - /// - /// "HttpClient is intended to be instantiated once and reused - /// throughout the life of an application. In .NET Core and .NET 5+, - /// HttpClient pools connections inside the handler instance and - /// reuses a connection across multiple requests. If you instantiate - /// an HttpClient class for every request, the number of sockets - /// available under heavy loads will be exhausted. This exhaustion - /// will result in SocketException errors." - /// - public static readonly HttpClient httpClient = new HttpClient(); - public static readonly HttpClient nonRedirectingHttpClient = new HttpClient( - new HttpClientHandler() - { - AllowAutoRedirect = false, - }); + { + // HttpClient apparently is worse than what it was supposed to replace + #pragma warning disable SYSLIB0014 + WebRequest req = WebRequest.Create(url); + #pragma warning restore SYSLIB0014 + req.Method = "HEAD"; + HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); + string val = resp.Headers["ETag"]?.Replace("\"", ""); + resp.Close(); + return val; + } /// /// Downloads the specified url, and stores it in the filename given. @@ -257,10 +246,6 @@ public static Uri ResolveRedirect(Uri url) const int maxRedirects = 6; for (int redirects = 0; redirects <= maxRedirects; ++redirects) { - #if NETFRAMEWORK - - // HttpClient doesn't handle redirects well on Mono, but net7.0 considers WebClient obsolete - var rwClient = new RedirectWebClient(); using (rwClient.OpenRead(url)) { } var location = rwClient.ResponseHeaders["Location"]; @@ -281,37 +266,6 @@ public static Uri ResolveRedirect(Uri url) { throw new Kraken(string.Format(Properties.Resources.NetInvalidLocation, location)); } - - #else - - var req = new HttpRequestMessage(HttpMethod.Head, url); - req.Headers.UserAgent.Clear(); - req.Headers.UserAgent.ParseAdd(UserAgentString); - using (var response = nonRedirectingHttpClient.SendAsync( - req, HttpCompletionOption.ResponseHeadersRead).Result) - { - if (response.Headers.Location == null) - { - return url; - } - - var location = response.Headers.Location.ToString(); - if (Uri.IsWellFormedUriString(location, UriKind.Absolute)) - { - url = response.Headers.Location; - } - else if (Uri.IsWellFormedUriString(location, UriKind.Relative)) - { - url = new Uri(url, response.Headers.Location); - log.DebugFormat("Relative URL {0} is absolute URL {1}", location, url); - } - else - { - throw new Kraken(string.Format(Properties.Resources.NetInvalidLocation, location)); - } - } - - #endif } return null; } diff --git a/Core/Net/RedirectWebClient.cs b/Core/Net/RedirectWebClient.cs index 661252fc10..3c279ce8e9 100644 --- a/Core/Net/RedirectWebClient.cs +++ b/Core/Net/RedirectWebClient.cs @@ -1,8 +1,8 @@ -#if NETFRAMEWORK - using System; using System.Net; +#pragma warning disable SYSLIB0014 + namespace CKAN { // HttpClient doesn't handle redirects well on Mono, but net7.0 considers WebClient obsolete @@ -23,5 +23,3 @@ protected override WebRequest GetWebRequest(Uri address) } } } - -#endif diff --git a/GUI/Main/MainRepo.cs b/GUI/Main/MainRepo.cs index 0b7f26a849..1bc1cf473f 100644 --- a/GUI/Main/MainRepo.cs +++ b/GUI/Main/MainRepo.cs @@ -202,7 +202,22 @@ private void PostUpdateRepo(object sender, RunWorkerCompletedEventArgs e) EnableMainWindow(); break; + case AggregateException exc: + foreach (var inner in exc.InnerExceptions + .SelectMany(inner => + inner.TraverseNodes(ex => ex.InnerException) + .Reverse())) + { + log.Error(inner.Message, inner); + currentUser.RaiseMessage(inner.Message); + } + AddStatusMessage(Properties.Resources.MainRepoFailed); + Wait.Finish(); + EnableMainWindow(); + break; + case Exception exc: + log.Error(exc.Message, exc); currentUser.RaiseMessage(exc.Message); AddStatusMessage(Properties.Resources.MainRepoFailed); Wait.Finish(); diff --git a/Netkan/CKAN-netkan.csproj b/Netkan/CKAN-netkan.csproj index ea5bc06ffd..dcc9be7eca 100644 --- a/Netkan/CKAN-netkan.csproj +++ b/Netkan/CKAN-netkan.csproj @@ -23,7 +23,7 @@ 512 prompt 4 - IDE1006 + IDE1006,NU1701 diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index ee48db95c3..0cedf0cc1c 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -18,7 +18,7 @@ Debug;Release;NoGUI false 7.3 - IDE1006 + IDE1006,NU1701 net48;net7.0;net7.0-windows $(TargetFramework.Replace("-windows", "")) $(DefaultItemExcludes);AutoUpdate\**;GUI\**