From 1e0e8adc77443ea65da5ade0add38c0864d71f41 Mon Sep 17 00:00:00 2001 From: ta264 Date: Wed, 17 Mar 2021 21:30:57 +0000 Subject: [PATCH] More mono cleanup --- .../Http/Dispatchers/ManagedHttpDispatcher.cs | 58 ++-------------- src/NzbDrone.Common/Http/NzbDroneWebClient.cs | 20 ------ .../Checks/MonoDebugCheckFixture.cs | 63 ----------------- .../Checks/MonoNotNetCoreCheckFixture.cs | 42 ------------ .../Checks/MonoVersionCheckFixture.cs | 68 ------------------- .../HealthCheck/Checks/MonoDebugCheck.cs | 47 ------------- .../HealthCheck/Checks/MonoNotNetCoreCheck.cs | 57 ---------------- .../HealthCheck/Checks/MonoTlsCheck.cs | 44 ------------ .../HealthCheck/Checks/MonoVersionCheck.cs | 43 ------------ 9 files changed, 4 insertions(+), 438 deletions(-) delete mode 100644 src/NzbDrone.Common/Http/NzbDroneWebClient.cs delete mode 100644 src/NzbDrone.Core.Test/HealthCheck/Checks/MonoDebugCheckFixture.cs delete mode 100644 src/NzbDrone.Core.Test/HealthCheck/Checks/MonoNotNetCoreCheckFixture.cs delete mode 100644 src/NzbDrone.Core.Test/HealthCheck/Checks/MonoVersionCheckFixture.cs delete mode 100644 src/NzbDrone.Core/HealthCheck/Checks/MonoDebugCheck.cs delete mode 100644 src/NzbDrone.Core/HealthCheck/Checks/MonoNotNetCoreCheck.cs delete mode 100644 src/NzbDrone.Core/HealthCheck/Checks/MonoTlsCheck.cs delete mode 100644 src/NzbDrone.Core/HealthCheck/Checks/MonoVersionCheck.cs diff --git a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs index 95e070deb..cba300e39 100644 --- a/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs +++ b/src/NzbDrone.Common/Http/Dispatchers/ManagedHttpDispatcher.cs @@ -35,19 +35,10 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) { var webRequest = (HttpWebRequest)WebRequest.Create((Uri)request.Url); - if (PlatformInfo.IsMono && request.ResponseStream == null) - { - // On Mono GZipStream/DeflateStream leaks memory if an exception is thrown, use an intermediate buffer in that case. - webRequest.AutomaticDecompression = DecompressionMethods.None; - webRequest.Headers.Add("Accept-Encoding", "gzip"); - } - else - { - // Deflate is not a standard and could break depending on implementation. - // we should just stick with the more compatible Gzip - //http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net - webRequest.AutomaticDecompression = DecompressionMethods.GZip; - } + // Deflate is not a standard and could break depending on implementation. + // we should just stick with the more compatible Gzip + //http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net + webRequest.AutomaticDecompression = DecompressionMethods.GZip; webRequest.Method = request.Method.ToString(); webRequest.UserAgent = _userAgentBuilder.GetUserAgent(request.UseSimplifiedUserAgent); @@ -104,9 +95,6 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) if (httpWebResponse == null) { - // Workaround for mono not closing connections properly in certain situations. - AbortWebRequest(webRequest); - // The default messages for WebException on mono are pretty horrible. if (e.Status == WebExceptionStatus.NameResolutionFailure) { @@ -147,12 +135,6 @@ public HttpResponse GetResponse(HttpRequest request, CookieContainer cookies) else { data = responseStream.ToBytes(); - - if (PlatformInfo.IsMono && httpWebResponse.ContentEncoding == "gzip") - { - data = data.Decompress(); - httpWebResponse.Headers.Remove("Content-Encoding"); - } } } catch (Exception ex) @@ -262,37 +244,5 @@ protected virtual void AddRequestHeaders(HttpWebRequest webRequest, HttpHeader h } } } - - // Workaround for mono not closing connections properly on timeouts - private void AbortWebRequest(HttpWebRequest webRequest) - { - // First affected version was mono 5.16 - if (OsInfo.IsNotWindows && _platformInfo.Version >= new Version(5, 16)) - { - try - { - var currentOperationInfo = webRequest.GetType().GetField("currentOperation", BindingFlags.NonPublic | BindingFlags.Instance); - var currentOperation = currentOperationInfo.GetValue(webRequest); - - if (currentOperation != null) - { - var responseStreamInfo = currentOperation.GetType().GetField("responseStream", BindingFlags.NonPublic | BindingFlags.Instance); - var responseStream = responseStreamInfo.GetValue(currentOperation) as Stream; - - // Note that responseStream will likely be null once mono fixes it. - responseStream?.Dispose(); - } - } - catch (Exception ex) - { - // This can fail randomly on future mono versions that have been changed/fixed. Log to sentry and ignore. - _logger.Trace() - .Exception(ex) - .Message("Unable to dispose responseStream on mono {0}", _platformInfo.Version) - .WriteSentryWarn("MonoCloseWaitPatchFailed", ex.Message) - .Write(); - } - } - } } } diff --git a/src/NzbDrone.Common/Http/NzbDroneWebClient.cs b/src/NzbDrone.Common/Http/NzbDroneWebClient.cs deleted file mode 100644 index ccd369bb7..000000000 --- a/src/NzbDrone.Common/Http/NzbDroneWebClient.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Net; - -namespace NzbDrone.Common.Http -{ - public class NzbDroneWebClient : WebClient - { - protected override WebRequest GetWebRequest(Uri address) - { - var request = base.GetWebRequest(address); - if (request is HttpWebRequest) - { - ((HttpWebRequest)request).KeepAlive = false; - ((HttpWebRequest)request).ServicePoint.Expect100Continue = false; - } - - return request; - } - } -} diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoDebugCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoDebugCheckFixture.cs deleted file mode 100644 index 087501f7f..000000000 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoDebugCheckFixture.cs +++ /dev/null @@ -1,63 +0,0 @@ -using NUnit.Framework; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Core.HealthCheck.Checks; -using NzbDrone.Core.Test.Framework; -using NzbDrone.Test.Common; -using static NzbDrone.Core.HealthCheck.Checks.MonoDebugCheck; - -namespace NzbDrone.Core.Test.HealthCheck.Checks -{ - [TestFixture] - public class MonoDebugCheckFixture : CoreTest - { - private void GivenHasStackFrame(bool hasStackFrame) - { - Mocker.GetMock() - .Setup(f => f.HasStackFrameInfo()) - .Returns(hasStackFrame); - } - - [Test] - public void should_return_ok_if_not_mono() - { - if (PlatformInfo.IsMono) - { - throw new IgnoreException("non mono specific test"); - } - - Subject.Check().ShouldBeOk(); - } - - [Test] - public void should_return_ok_if_not_debug() - { - MonoOnly(); - - GivenHasStackFrame(false); - - Subject.Check().ShouldBeOk(); - } - - [Test] - public void should_log_warning_if_not_debug() - { - MonoOnly(); - - GivenHasStackFrame(false); - - Subject.Check(); - - ExceptionVerification.ExpectedWarns(1); - } - - [Test] - public void should_return_ok_if_debug() - { - MonoOnly(); - - GivenHasStackFrame(true); - - Subject.Check().ShouldBeOk(); - } - } -} diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoNotNetCoreCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoNotNetCoreCheckFixture.cs deleted file mode 100644 index 991040b35..000000000 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoNotNetCoreCheckFixture.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections.Generic; -using NUnit.Framework; -using NzbDrone.Common.Processes; -using NzbDrone.Core.HealthCheck.Checks; -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.HealthCheck.Checks -{ - [TestFixture] - public class MonoNotNetCoreCheckFixture : CoreTest - { - [Test] - [Platform(Exclude = "Mono")] - public void should_return_ok_if_net_core() - { - Subject.Check().ShouldBeOk(); - } - - [Test] - [Platform("Mono")] - public void should_log_warning_if_mono() - { - Subject.Check().ShouldBeWarning(); - } - - [Test] - [Platform("Mono")] - public void should_return_ok_if_bsd() - { - Mocker.GetMock() - .Setup(x => x.StartAndCapture("uname", null, null)) - .Returns(new ProcessOutput - { - Lines = new List - { - new ProcessOutputLine(ProcessOutputLevel.Standard, "FreeBSD") - } - }); - Subject.Check().ShouldBeOk(); - } - } -} diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoVersionCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoVersionCheckFixture.cs deleted file mode 100644 index bdcc0caef..000000000 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/MonoVersionCheckFixture.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using NUnit.Framework; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Core.HealthCheck.Checks; -using NzbDrone.Core.Test.Framework; - -namespace NzbDrone.Core.Test.HealthCheck.Checks -{ - [TestFixture] - public class MonoVersionCheckFixture : CoreTest - { - private void GivenOutput(string version) - { - MonoOnly(); - - Mocker.GetMock() - .SetupGet(s => s.Version) - .Returns(new Version(version)); - } - - [TestCase("5.20")] - public void should_return_ok(string version) - { - GivenOutput(version); - - Subject.Check().ShouldBeOk(); - } - - public void should_return_notice(string version) - { - GivenOutput(version); - - Subject.Check().ShouldBeNotice(); - } - - public void should_return_warning(string version) - { - GivenOutput(version); - - Subject.Check().ShouldBeWarning(); - } - - [TestCase("2.10.2")] - [TestCase("2.10.8.1")] - [TestCase("3.0.0.1")] - [TestCase("3.2.0.1")] - [TestCase("3.2.1")] - [TestCase("3.2.7")] - [TestCase("3.6.1")] - [TestCase("3.8")] - [TestCase("3.10")] - [TestCase("4.0.0.0")] - [TestCase("4.2")] - [TestCase("4.4.0")] - [TestCase("4.4.1")] - [TestCase("4.6.2")] - [TestCase("5.4")] - [TestCase("5.8")] - [TestCase("5.16")] - [TestCase("5.18")] - public void should_return_error(string version) - { - GivenOutput(version); - - Subject.Check().ShouldBeError(); - } - } -} diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MonoDebugCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MonoDebugCheck.cs deleted file mode 100644 index 5d9bbce5c..000000000 --- a/src/NzbDrone.Core/HealthCheck/Checks/MonoDebugCheck.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Diagnostics; -using NLog; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Extensions; - -namespace NzbDrone.Core.HealthCheck.Checks -{ - public class MonoDebugCheck : HealthCheckBase - { - private readonly Logger _logger; - private readonly StackFrameHelper _stackFrameHelper; - - public override bool CheckOnSchedule => false; - - public MonoDebugCheck(Logger logger, StackFrameHelper stackFrameHelper) - { - _logger = logger; - _stackFrameHelper = stackFrameHelper; - } - - public class StackFrameHelper - { - public virtual bool HasStackFrameInfo() - { - var stackTrace = new StackTrace(true); - - return stackTrace.FrameCount > 0 && stackTrace.GetFrame(0).GetFileName().IsNotNullOrWhiteSpace(); - } - } - - public override HealthCheck Check() - { - if (!PlatformInfo.IsMono) - { - return new HealthCheck(GetType()); - } - - if (!_stackFrameHelper.HasStackFrameInfo()) - { - _logger.Warn("Mono is not running with --debug switch"); - return new HealthCheck(GetType()); - } - - return new HealthCheck(GetType()); - } - } -} diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MonoNotNetCoreCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MonoNotNetCoreCheck.cs deleted file mode 100644 index ab584dd4a..000000000 --- a/src/NzbDrone.Core/HealthCheck/Checks/MonoNotNetCoreCheck.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Linq; -using System.Runtime.InteropServices; -using NLog; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Processes; - -namespace NzbDrone.Core.HealthCheck.Checks -{ - public class MonoNotNetCoreCheck : HealthCheckBase - { - private static string[] MonoUnames = new string[] { "FreeBSD", "OpenBSD", "MidnightBSD", "NetBSD" }; - private readonly IOsInfo _osInfo; - private readonly IProcessProvider _processProvider; - - public MonoNotNetCoreCheck(IOsInfo osInfo, - IProcessProvider processProvider, - Logger logger) - { - _osInfo = osInfo; - _processProvider = processProvider; - } - - public override HealthCheck Check() - { - if (!PlatformInfo.IsMono) - { - return new HealthCheck(GetType()); - } - - // Don't warn on arm based synology - could be arm5 or something else rubbish - if (_osInfo.Name == "DSM" && RuntimeInformation.ProcessArchitecture == Architecture.Arm) - { - return new HealthCheck(GetType()); - } - - // Don't warn on linux x86 - we don't build x86 net core - if (OsInfo.IsLinux && RuntimeInformation.ProcessArchitecture == Architecture.X86) - { - return new HealthCheck(GetType()); - } - - // Check for BSD - var output = _processProvider.StartAndCapture("uname"); - if (output?.ExitCode == 0 && MonoUnames.Contains(output?.Lines.First().Content)) - { - return new HealthCheck(GetType()); - } - - return new HealthCheck(GetType(), - HealthCheckResult.Warning, - "Please upgrade to the .NET Core version of Readarr", - "#update-to-net-core-version"); - } - - public override bool CheckOnSchedule => false; - } -} diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MonoTlsCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MonoTlsCheck.cs deleted file mode 100644 index ac6dabc37..000000000 --- a/src/NzbDrone.Core/HealthCheck/Checks/MonoTlsCheck.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using NLog; -using NLog.Fluent; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Instrumentation.Extensions; - -namespace NzbDrone.Core.HealthCheck.Checks -{ - public class MonoTlsCheck : HealthCheckBase - { - private readonly IPlatformInfo _platformInfo; - private readonly Logger _logger; - - public MonoTlsCheck(IPlatformInfo platformInfo, Logger logger) - { - _platformInfo = platformInfo; - _logger = logger; - } - - public override HealthCheck Check() - { - if (!PlatformInfo.IsMono) - { - return new HealthCheck(GetType()); - } - - var monoVersion = _platformInfo.Version; - - if (monoVersion >= new Version("5.8.0") && Environment.GetEnvironmentVariable("MONO_TLS_PROVIDER") == "legacy") - { - _logger.Debug() - .Message("Mono version {0} and legacy TLS provider is selected, recommending user to switch to btls.", monoVersion) - .WriteSentryDebug("LegacyTlsProvider", monoVersion.ToString()) - .Write(); - - return new HealthCheck(GetType(), HealthCheckResult.Warning, "Readarr Mono 4.x tls workaround still enabled, consider removing MONO_TLS_PROVIDER=legacy environment option"); - } - - return new HealthCheck(GetType()); - } - - public override bool CheckOnSchedule => false; - } -} diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MonoVersionCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MonoVersionCheck.cs deleted file mode 100644 index 0ce07a9d9..000000000 --- a/src/NzbDrone.Core/HealthCheck/Checks/MonoVersionCheck.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using NLog; -using NzbDrone.Common.EnvironmentInfo; - -namespace NzbDrone.Core.HealthCheck.Checks -{ - public class MonoVersionCheck : HealthCheckBase - { - private readonly IPlatformInfo _platformInfo; - private readonly Logger _logger; - - public MonoVersionCheck(IPlatformInfo platformInfo, Logger logger) - { - _platformInfo = platformInfo; - _logger = logger; - } - - public override HealthCheck Check() - { - if (!PlatformInfo.IsMono) - { - return new HealthCheck(GetType()); - } - - var monoVersion = _platformInfo.Version; - - // Currently best stable Mono version (5.18 gets us .net 4.7.2 support) - var bestVersion = new Version("5.20"); - if (monoVersion >= bestVersion) - { - _logger.Debug("Mono version is {0} or better: {1}", bestVersion, monoVersion); - return new HealthCheck(GetType()); - } - - return new HealthCheck(GetType(), - HealthCheckResult.Error, - $"Currently installed Mono version {monoVersion} is old and unsupported. Please upgrade Mono to version {bestVersion}.", - "#currently_installed_mono_version_is_old_and_unsupported"); - } - - public override bool CheckOnSchedule => false; - } -}