From aca669defe728bc2e2c4072a6a79a07e4dac3a5a Mon Sep 17 00:00:00 2001 From: ta264 Date: Thu, 21 Oct 2021 21:04:26 +0100 Subject: [PATCH] Fixed: UI not updating on upgrade (cherry picked from commit d566c1efd42f9a94c524db311e8fa99bc6e0323f) (cherry picked from commit 4b0586bd3d1cca4682dee53cc5af5ef1fa66978e) (cherry picked from commit 5b2affcabbc38d7122b39d3290e2021fdb8afbcc) --- .../IndexHtmlFixture.cs | 17 ++++++++++- .../Extensions/RequestExtensions.cs | 1 + .../Mappers/StaticResourceMapperBase.cs | 2 +- .../Frontend/StaticResourceController.cs | 16 +++++++++- .../Middleware/CacheHeaderMiddleware.cs | 2 +- .../Middleware/CacheableSpecification.cs | 30 +++++++------------ .../Middleware/IfModifiedMiddleware.cs | 2 +- 7 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/NzbDrone.Integration.Test/IndexHtmlFixture.cs b/src/NzbDrone.Integration.Test/IndexHtmlFixture.cs index 8bd1a26fc2..ed732aee87 100644 --- a/src/NzbDrone.Integration.Test/IndexHtmlFixture.cs +++ b/src/NzbDrone.Integration.Test/IndexHtmlFixture.cs @@ -1,4 +1,5 @@ -using System.Net; +using System.Linq; +using System.Net; using FluentAssertions; using NUnit.Framework; @@ -13,5 +14,19 @@ public void should_get_index_html() var text = new WebClient().DownloadString(RootUrl); text.Should().NotBeNullOrWhiteSpace(); } + + [Test] + public void index_should_not_be_cached() + { + var client = new WebClient(); + _ = client.DownloadString(RootUrl); + + var headers = client.ResponseHeaders; + + headers.Get("Cache-Control").Split(',').Select(x => x.Trim()) + .Should().BeEquivalentTo("no-store, no-cache".Split(',').Select(x => x.Trim())); + headers.Get("Pragma").Should().Be("no-cache"); + headers.Get("Expires").Should().Be("-1"); + } } } diff --git a/src/Radarr.Http/Extensions/RequestExtensions.cs b/src/Radarr.Http/Extensions/RequestExtensions.cs index 98db0fa5fb..aab072807f 100644 --- a/src/Radarr.Http/Extensions/RequestExtensions.cs +++ b/src/Radarr.Http/Extensions/RequestExtensions.cs @@ -193,6 +193,7 @@ public static string GetRemoteIP(this HttpRequest request) public static void DisableCache(this IHeaderDictionary headers) { + headers.Remove("Last-Modified"); headers["Cache-Control"] = "no-cache, no-store"; headers["Expires"] = "-1"; headers["Pragma"] = "no-cache"; diff --git a/src/Radarr.Http/Frontend/Mappers/StaticResourceMapperBase.cs b/src/Radarr.Http/Frontend/Mappers/StaticResourceMapperBase.cs index 0f9e2ad7d3..402bce1672 100644 --- a/src/Radarr.Http/Frontend/Mappers/StaticResourceMapperBase.cs +++ b/src/Radarr.Http/Frontend/Mappers/StaticResourceMapperBase.cs @@ -28,7 +28,7 @@ protected StaticResourceMapperBase(IDiskProvider diskProvider, Logger logger) public abstract bool CanHandle(string resourceUrl); - public virtual IActionResult GetResponse(string resourceUrl) + public IActionResult GetResponse(string resourceUrl) { var filePath = Map(resourceUrl); diff --git a/src/Radarr.Http/Frontend/StaticResourceController.cs b/src/Radarr.Http/Frontend/StaticResourceController.cs index f0f0fa087d..bf1b16e009 100644 --- a/src/Radarr.Http/Frontend/StaticResourceController.cs +++ b/src/Radarr.Http/Frontend/StaticResourceController.cs @@ -7,6 +7,7 @@ using NLog; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Configuration; +using Radarr.Http.Extensions; using Radarr.Http.Frontend.Mappers; namespace Radarr.Http.Frontend @@ -36,6 +37,7 @@ public StaticResourceController(IConfigFileProvider configFileProvider, [HttpGet("login")] public IActionResult LoginPage() { + Response.Headers.DisableCache(); return PhysicalFile(_loginPath, "text/html"); } @@ -62,7 +64,19 @@ private IActionResult MapResource(string path) if (mapper != null) { - return mapper.GetResponse(path) ?? NotFound(); + var result = mapper.GetResponse(path); + + if (result != null) + { + if ((result as FileResult)?.ContentType == "text/html") + { + Response.Headers.DisableCache(); + } + + return result; + } + + return NotFound(); } _logger.Warn("Couldn't find handler for {0}", path); diff --git a/src/Radarr.Http/Middleware/CacheHeaderMiddleware.cs b/src/Radarr.Http/Middleware/CacheHeaderMiddleware.cs index 30c3dad5ea..5ed6b0e0d9 100644 --- a/src/Radarr.Http/Middleware/CacheHeaderMiddleware.cs +++ b/src/Radarr.Http/Middleware/CacheHeaderMiddleware.cs @@ -19,7 +19,7 @@ public async Task InvokeAsync(HttpContext context) { if (context.Request.Method != "OPTIONS") { - if (_cacheableSpecification.IsCacheable(context)) + if (_cacheableSpecification.IsCacheable(context.Request)) { context.Response.Headers.EnableCache(); } diff --git a/src/Radarr.Http/Middleware/CacheableSpecification.cs b/src/Radarr.Http/Middleware/CacheableSpecification.cs index 3457c2c7bb..16b83660bb 100644 --- a/src/Radarr.Http/Middleware/CacheableSpecification.cs +++ b/src/Radarr.Http/Middleware/CacheableSpecification.cs @@ -7,26 +7,26 @@ namespace Radarr.Http.Middleware { public interface ICacheableSpecification { - bool IsCacheable(HttpContext context); + bool IsCacheable(HttpRequest request); } public class CacheableSpecification : ICacheableSpecification { - public bool IsCacheable(HttpContext context) + public bool IsCacheable(HttpRequest request) { if (!RuntimeInfo.IsProduction) { return false; } - if (context.Request.Query.ContainsKey("h")) + if (request.Query.ContainsKey("h")) { return true; } - if (context.Request.Path.StartsWithSegments("/api", StringComparison.CurrentCultureIgnoreCase)) + if (request.Path.StartsWithSegments("/api", StringComparison.CurrentCultureIgnoreCase)) { - if (context.Request.Path.ToString().ContainsIgnoreCase("/MediaCover")) + if (request.Path.ToString().ContainsIgnoreCase("/MediaCover")) { return true; } @@ -34,40 +34,32 @@ public bool IsCacheable(HttpContext context) return false; } - if (context.Request.Path.StartsWithSegments("/signalr", StringComparison.CurrentCultureIgnoreCase)) + if (request.Path.StartsWithSegments("/signalr", StringComparison.CurrentCultureIgnoreCase)) { return false; } - if (context.Request.Path.Value?.EndsWith("/index.js") ?? false) + if (request.Path.Value?.EndsWith("/index.js") ?? false) { return false; } - if (context.Request.Path.Value?.EndsWith("/initialize.js") ?? false) + if (request.Path.Value?.EndsWith("/initialize.js") ?? false) { return false; } - if (context.Request.Path.StartsWithSegments("/feed", StringComparison.CurrentCultureIgnoreCase)) + if (request.Path.StartsWithSegments("/feed", StringComparison.CurrentCultureIgnoreCase)) { return false; } - if (context.Request.Path.StartsWithSegments("/log", StringComparison.CurrentCultureIgnoreCase) && - (context.Request.Path.Value?.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase) ?? false)) + if (request.Path.StartsWithSegments("/log", StringComparison.CurrentCultureIgnoreCase) && + (request.Path.Value?.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase) ?? false)) { return false; } - if (context.Response != null) - { - if (context.Response.ContentType?.Contains("text/html") ?? false || context.Response.StatusCode >= 400) - { - return false; - } - } - return true; } } diff --git a/src/Radarr.Http/Middleware/IfModifiedMiddleware.cs b/src/Radarr.Http/Middleware/IfModifiedMiddleware.cs index f1cad09bb4..84f8818efa 100644 --- a/src/Radarr.Http/Middleware/IfModifiedMiddleware.cs +++ b/src/Radarr.Http/Middleware/IfModifiedMiddleware.cs @@ -22,7 +22,7 @@ public IfModifiedMiddleware(RequestDelegate next, ICacheableSpecification cachea public async Task InvokeAsync(HttpContext context) { - if (_cacheableSpecification.IsCacheable(context) && context.Request.Headers["IfModifiedSince"].Any()) + if (_cacheableSpecification.IsCacheable(context.Request) && context.Request.Headers["IfModifiedSince"].Any()) { context.Response.StatusCode = 304; context.Response.Headers.EnableCache();