Fixed: UI not updating on upgrade

(cherry picked from commit d566c1efd42f9a94c524db311e8fa99bc6e0323f)
(cherry picked from commit 4b0586bd3d1cca4682dee53cc5af5ef1fa66978e)
pull/2397/head
ta264 3 years ago committed by Qstick
parent 2b0da546c9
commit 5b2affcabb

@ -193,6 +193,7 @@ namespace Lidarr.Http.Extensions
public static void DisableCache(this IHeaderDictionary headers) public static void DisableCache(this IHeaderDictionary headers)
{ {
headers.Remove("Last-Modified");
headers["Cache-Control"] = "no-cache, no-store"; headers["Cache-Control"] = "no-cache, no-store";
headers["Expires"] = "-1"; headers["Expires"] = "-1";
headers["Pragma"] = "no-cache"; headers["Pragma"] = "no-cache";

@ -6,6 +6,6 @@ namespace Lidarr.Http.Frontend.Mappers
{ {
string Map(string resourceUrl); string Map(string resourceUrl);
bool CanHandle(string resourceUrl); bool CanHandle(string resourceUrl);
IActionResult GetResponse(string resourceUrl); FileStreamResult GetResponse(string resourceUrl);
} }
} }

@ -28,7 +28,7 @@ namespace Lidarr.Http.Frontend.Mappers
public abstract bool CanHandle(string resourceUrl); public abstract bool CanHandle(string resourceUrl);
public virtual IActionResult GetResponse(string resourceUrl) public FileStreamResult GetResponse(string resourceUrl)
{ {
var filePath = Map(resourceUrl); var filePath = Map(resourceUrl);

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Lidarr.Http.Extensions;
using Lidarr.Http.Frontend.Mappers; using Lidarr.Http.Frontend.Mappers;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Cors;
@ -36,6 +37,7 @@ namespace Lidarr.Http.Frontend
[HttpGet("login")] [HttpGet("login")]
public IActionResult LoginPage() public IActionResult LoginPage()
{ {
Response.Headers.DisableCache();
return PhysicalFile(_loginPath, "text/html"); return PhysicalFile(_loginPath, "text/html");
} }
@ -62,7 +64,19 @@ namespace Lidarr.Http.Frontend
if (mapper != null) if (mapper != null)
{ {
return mapper.GetResponse(path) ?? NotFound(); var result = mapper.GetResponse(path);
if (result != null)
{
if (result.ContentType == "text/html")
{
Response.Headers.DisableCache();
}
return result;
}
return NotFound();
} }
_logger.Warn("Couldn't find handler for {0}", path); _logger.Warn("Couldn't find handler for {0}", path);

@ -19,7 +19,7 @@ namespace Lidarr.Http.Middleware
{ {
if (context.Request.Method != "OPTIONS") if (context.Request.Method != "OPTIONS")
{ {
if (_cacheableSpecification.IsCacheable(context)) if (_cacheableSpecification.IsCacheable(context.Request))
{ {
context.Response.Headers.EnableCache(); context.Response.Headers.EnableCache();
} }

@ -7,26 +7,26 @@ namespace Lidarr.Http.Middleware
{ {
public interface ICacheableSpecification public interface ICacheableSpecification
{ {
bool IsCacheable(HttpContext context); bool IsCacheable(HttpRequest request);
} }
public class CacheableSpecification : ICacheableSpecification public class CacheableSpecification : ICacheableSpecification
{ {
public bool IsCacheable(HttpContext context) public bool IsCacheable(HttpRequest request)
{ {
if (!RuntimeInfo.IsProduction) if (!RuntimeInfo.IsProduction)
{ {
return false; return false;
} }
if (context.Request.Query.ContainsKey("h")) if (request.Query.ContainsKey("h"))
{ {
return true; 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; return true;
} }
@ -34,40 +34,32 @@ namespace Lidarr.Http.Middleware
return false; return false;
} }
if (context.Request.Path.StartsWithSegments("/signalr", StringComparison.CurrentCultureIgnoreCase)) if (request.Path.StartsWithSegments("/signalr", StringComparison.CurrentCultureIgnoreCase))
{ {
return false; return false;
} }
if (context.Request.Path.Value?.EndsWith("/index.js") ?? false) if (request.Path.Value?.EndsWith("/index.js") ?? false)
{ {
return false; return false;
} }
if (context.Request.Path.Value?.EndsWith("/initialize.js") ?? false) if (request.Path.Value?.EndsWith("/initialize.js") ?? false)
{ {
return false; return false;
} }
if (context.Request.Path.StartsWithSegments("/feed", StringComparison.CurrentCultureIgnoreCase)) if (request.Path.StartsWithSegments("/feed", StringComparison.CurrentCultureIgnoreCase))
{ {
return false; return false;
} }
if (context.Request.Path.StartsWithSegments("/log", StringComparison.CurrentCultureIgnoreCase) && if (request.Path.StartsWithSegments("/log", StringComparison.CurrentCultureIgnoreCase) &&
(context.Request.Path.Value?.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase) ?? false)) (request.Path.Value?.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase) ?? false))
{ {
return false; return false;
} }
if (context.Response != null)
{
if (context.Response.ContentType?.Contains("text/html") ?? false || context.Response.StatusCode >= 400)
{
return false;
}
}
return true; return true;
} }
} }

@ -22,7 +22,7 @@ namespace Lidarr.Http.Middleware
public async Task InvokeAsync(HttpContext context) 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.StatusCode = 304;
context.Response.Headers.EnableCache(); context.Response.Headers.EnableCache();

@ -1,4 +1,5 @@
using System.Net; using System.Linq;
using System.Net;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
@ -13,5 +14,19 @@ namespace NzbDrone.Integration.Test
var text = new WebClient().DownloadString(RootUrl); var text = new WebClient().DownloadString(RootUrl);
text.Should().NotBeNullOrWhiteSpace(); 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");
}
} }
} }

Loading…
Cancel
Save