diff --git a/NzbDrone.Api/Extensions/CacheHeaderPipeline.cs b/NzbDrone.Api/Extensions/CacheHeaderPipeline.cs new file mode 100644 index 000000000..69a605d68 --- /dev/null +++ b/NzbDrone.Api/Extensions/CacheHeaderPipeline.cs @@ -0,0 +1,16 @@ +using Nancy; + +namespace NzbDrone.Api.Extensions +{ + public static class CacheHeaderPipeline + { + public static void Handle(NancyContext context) + { + if (context.Response.ContentType.Contains("json")) + { + context.Response.Headers.DisableCache(); + + } + } + } +} \ No newline at end of file diff --git a/NzbDrone.Api/Extensions/ReqResExtensions.cs b/NzbDrone.Api/Extensions/ReqResExtensions.cs index 8139b469b..322217cc4 100644 --- a/NzbDrone.Api/Extensions/ReqResExtensions.cs +++ b/NzbDrone.Api/Extensions/ReqResExtensions.cs @@ -32,24 +32,27 @@ namespace NzbDrone.Api.Extensions public static JsonResponse AsResponse(this TModel model, HttpStatusCode statusCode = HttpStatusCode.OK) { - return new JsonResponse(model, NancySerializer) { StatusCode = statusCode }; + var response = new JsonResponse(model, NancySerializer) { StatusCode = statusCode }; + response.Headers.DisableCache(); + + return response; } public static IDictionary DisableCache(this IDictionary headers) { - headers.Add("Cache-Control", "no-cache, no-store, must-revalidate"); - headers.Add("Pragma", "no-cache"); - headers.Add("Expires", "0"); + headers["Cache-Control"] = "no-cache, no-store, must-revalidate"; + headers["Pragma"] = "no-cache"; + headers["Expires"] = "0"; return headers; } public static IDictionary EnableCache(this IDictionary headers) { - headers.Add("Cache-Control", "max-age=31536000 , public"); - headers.Add("Expires", "Sat, 29 Jun 2020 00:00:00 GMT"); - headers.Add("Last-Modified", "Sat, 29 Jun 2000 00:00:00 GMT"); - headers.Add("Age", "193266"); + headers["Cache-Control"] = "max-age=31536000 , public"; + headers["Expires"] = "Sat, 29 Jun 2020 00:00:00 GMT"; + headers["Last-Modified"] = "Sat, 29 Jun 2000 00:00:00 GMT"; + headers["Age"] = "193266"; return headers; } diff --git a/NzbDrone.Api/NancyBootstrapper.cs b/NzbDrone.Api/NancyBootstrapper.cs index 9df476469..7203469ad 100644 --- a/NzbDrone.Api/NancyBootstrapper.cs +++ b/NzbDrone.Api/NancyBootstrapper.cs @@ -33,6 +33,7 @@ namespace NzbDrone.Api container.Resolve().PublishEvent(new ApplicationStartedEvent()); pipelines.AfterRequest.AddItemToStartOfPipeline(GzipCompressionPipeline.Handle); + pipelines.AfterRequest.AddItemToEndOfPipeline(CacheHeaderPipeline.Handle); ApplicationPipelines.OnError.AddItemToEndOfPipeline(container.Resolve().HandleException); } diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index 6288bd210..78dfd8625 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -106,6 +106,7 @@ + diff --git a/NzbDrone.Integration.Test/Client/ClientBase.cs b/NzbDrone.Integration.Test/Client/ClientBase.cs index 182caab05..8b36d0260 100644 --- a/NzbDrone.Integration.Test/Client/ClientBase.cs +++ b/NzbDrone.Integration.Test/Client/ClientBase.cs @@ -5,6 +5,7 @@ using NLog; using NzbDrone.Api.REST; using NzbDrone.Common.Serializer; using RestSharp; +using System.Linq; namespace NzbDrone.Integration.Test.Client { @@ -99,6 +100,8 @@ namespace NzbDrone.Integration.Test.Client throw response.ErrorException; } + AssertDisableCache(response.Headers); + response.ErrorMessage.Should().BeBlank(); response.StatusCode.Should().Be(statusCode); @@ -106,5 +109,13 @@ namespace NzbDrone.Integration.Test.Client return Json.Deserialize(response.Content); } + + private static void AssertDisableCache(IList headers) + { + headers.Single(c => c.Name == "Cache-Control").Value.Should().Be("no-cache, no-store, must-revalidate"); + headers.Single(c => c.Name == "Pragma").Value.Should().Be("no-cache"); + headers.Single(c => c.Name == "Expires").Value.Should().Be("0"); + } + } } \ No newline at end of file