From 303fc5d786ccf2ad14c8523fc239696c5d37ea53 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 4 Feb 2023 00:03:32 -0800 Subject: [PATCH] New: Return static response to requests while app is starting Closes #5402 --- .../EnvironmentInfo/IRuntimeInfo.cs | 1 + .../EnvironmentInfo/RuntimeInfo.cs | 2 + src/NzbDrone.Host/AppLifetime.cs | 1 + src/NzbDrone.Host/Startup.cs | 1 + .../Middleware/StartingUpMiddleware.cs | 43 +++++++++++++++++++ 5 files changed, 48 insertions(+) create mode 100644 src/Sonarr.Http/Middleware/StartingUpMiddleware.cs diff --git a/src/NzbDrone.Common/EnvironmentInfo/IRuntimeInfo.cs b/src/NzbDrone.Common/EnvironmentInfo/IRuntimeInfo.cs index a8e4bd9ad..f74ac685a 100644 --- a/src/NzbDrone.Common/EnvironmentInfo/IRuntimeInfo.cs +++ b/src/NzbDrone.Common/EnvironmentInfo/IRuntimeInfo.cs @@ -9,6 +9,7 @@ namespace NzbDrone.Common.EnvironmentInfo bool IsAdmin { get; } bool IsWindowsService { get; } bool IsWindowsTray { get; } + bool IsStarting { get; set; } bool IsExiting { get; set; } bool IsTray { get; } RuntimeMode Mode { get; } diff --git a/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs b/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs index 88ab4e4d2..daa2cc449 100644 --- a/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs +++ b/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs @@ -19,6 +19,7 @@ namespace NzbDrone.Common.EnvironmentInfo _logger = logger; IsWindowsService = hostLifetime is WindowsServiceLifetime; + IsStarting = true; // net6.0 will return Sonarr.dll for entry assembly, we need the actual // executable name (Sonarr on linux). On mono this will return the location of @@ -82,6 +83,7 @@ namespace NzbDrone.Common.EnvironmentInfo public bool IsWindowsService { get; private set; } + public bool IsStarting { get; set; } public bool IsExiting { get; set; } public bool IsTray { diff --git a/src/NzbDrone.Host/AppLifetime.cs b/src/NzbDrone.Host/AppLifetime.cs index a1c684f95..946ad1970 100644 --- a/src/NzbDrone.Host/AppLifetime.cs +++ b/src/NzbDrone.Host/AppLifetime.cs @@ -56,6 +56,7 @@ namespace NzbDrone.Host private void OnAppStarted() { + _runtimeInfo.IsStarting = false; _runtimeInfo.IsExiting = false; if (!_startupContext.Flags.Contains(StartupContext.NO_BROWSER) diff --git a/src/NzbDrone.Host/Startup.cs b/src/NzbDrone.Host/Startup.cs index 4121329a6..4226a5e4c 100644 --- a/src/NzbDrone.Host/Startup.cs +++ b/src/NzbDrone.Host/Startup.cs @@ -251,6 +251,7 @@ namespace NzbDrone.Host app.UseMiddleware(); app.UseMiddleware(configFileProvider.UrlBase); + app.UseMiddleware(); app.UseMiddleware(); app.UseMiddleware(); app.UseMiddleware(new List { "/api/v3/command" }); diff --git a/src/Sonarr.Http/Middleware/StartingUpMiddleware.cs b/src/Sonarr.Http/Middleware/StartingUpMiddleware.cs new file mode 100644 index 000000000..e26f48d10 --- /dev/null +++ b/src/Sonarr.Http/Middleware/StartingUpMiddleware.cs @@ -0,0 +1,43 @@ +using System.Buffers; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Lifecycle; +using NzbDrone.Core.Messaging.Events; +using Sonarr.Http.Extensions; + +namespace Sonarr.Http.Middleware +{ + public class StartingUpMiddleware + { + private readonly RequestDelegate _next; + private readonly IRuntimeInfo _runtimeInfo; + private static readonly string MESSAGE = "Sonarr is starting up, please try again later"; + + public StartingUpMiddleware(RequestDelegate next, IRuntimeInfo runtimeInfo) + { + _next = next; + _runtimeInfo = runtimeInfo; + } + + public async Task InvokeAsync(HttpContext context) + { + if (_runtimeInfo.IsStarting) + { + var isJson = context.Request.IsApiRequest(); + var message = isJson ? STJson.ToJson(new { ErrorMessage = MESSAGE }) : MESSAGE; + var bytes = Encoding.UTF8.GetBytes(message); + + context.Response.StatusCode = 503; + context.Response.ContentType = isJson ? "application/json" : "text/plain"; + await context.Response.Body.WriteAsync(bytes, 0, bytes.Length); + + return; + } + + await _next(context); + } + } +}