From fdfe8ca656af9debfc67f8d0ea6babcb57ea1524 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 (cherry picked from commit 303fc5d786ccf2ad14c8523fc239696c5d37ea53) Fixes #8079 Closes #8080 --- .../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/Radarr.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 5a11a8e61..93284e477 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 Radarr.dll for entry assembly, we need the actual // executable name (Radarr 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 be17ab714..45616e36b 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 ff2d94c49..6f069235c 100644 --- a/src/NzbDrone.Host/Startup.cs +++ b/src/NzbDrone.Host/Startup.cs @@ -264,6 +264,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/Radarr.Http/Middleware/StartingUpMiddleware.cs b/src/Radarr.Http/Middleware/StartingUpMiddleware.cs new file mode 100644 index 000000000..9a5cb9bf3 --- /dev/null +++ b/src/Radarr.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 Radarr.Http.Extensions; + +namespace Radarr.Http.Middleware +{ + public class StartingUpMiddleware + { + private readonly RequestDelegate _next; + private readonly IRuntimeInfo _runtimeInfo; + private static readonly string MESSAGE = "Radarr 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); + } + } +}