From aead34e750cce19f80dbf435935a9484f84c83fd Mon Sep 17 00:00:00 2001 From: Matt Lucas Date: Thu, 16 Apr 2015 15:58:21 -0400 Subject: [PATCH 1/2] Added ability to cache specified HTTP headers. --- src/WebApi.OutputCache.Core/Constants.cs | 1 + .../CacheOutputAttribute.cs | 40 ++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/WebApi.OutputCache.Core/Constants.cs b/src/WebApi.OutputCache.Core/Constants.cs index bc8885c..7a4cc9d 100644 --- a/src/WebApi.OutputCache.Core/Constants.cs +++ b/src/WebApi.OutputCache.Core/Constants.cs @@ -4,5 +4,6 @@ public sealed class Constants { public const string ContentTypeKey = ":response-ct"; public const string EtagKey = ":response-etag"; + public const string Headers = ":headers"; } } diff --git a/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs b/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs index 9742dc7..258f443 100644 --- a/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs +++ b/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs @@ -1,4 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; @@ -61,7 +63,12 @@ public class CacheOutputAttribute : FilterAttribute, IActionFilter /// Class used to generate caching keys /// public Type CacheKeyGenerator { get; set; } - + + /// + /// Comma seperated list of HTTP headers to cache + /// + public string HeadersToInclude { get; set; } + private MediaTypeHeaderValue _responseMediaType; // cache repository @@ -143,6 +150,8 @@ private void OnActionExecuting(HttpActionContext actionContext) if (!_webApiCache.Contains(cachekey)) return; + var responseHeaders = _webApiCache.Get(cachekey + Constants.Headers) as string; + if (actionContext.Request.Headers.IfNoneMatch != null) { var etag = _webApiCache.Get(cachekey + Constants.EtagKey) as string; @@ -152,6 +161,8 @@ private void OnActionExecuting(HttpActionContext actionContext) { var time = CacheTimeQuery.Execute(DateTime.Now); var quickResponse = actionContext.Request.CreateResponse(HttpStatusCode.NotModified); + AddCachedHeaders(quickResponse, cachekey); + if (responseHeaders != null) AddCachedHeaders(quickResponse, responseHeaders); ApplyCacheHeaders(quickResponse, time); actionContext.Response = quickResponse; return; @@ -171,6 +182,8 @@ private void OnActionExecuting(HttpActionContext actionContext) var responseEtag = _webApiCache.Get(cachekey + Constants.EtagKey) as string; if (responseEtag != null) SetEtag(actionContext.Response, responseEtag); + if (responseHeaders != null) AddCachedHeaders(actionContext.Response, responseHeaders); + var cacheTime = CacheTimeQuery.Execute(DateTime.Now); ApplyCacheHeaders(actionContext.Response, cacheTime); } @@ -215,6 +228,16 @@ private async Task OnActionExecuted(HttpActionExecutedContext actionExecutedCont _webApiCache.Add(cachekey + Constants.EtagKey, etag, cacheTime.AbsoluteExpiration, baseKey); + + + if (!String.IsNullOrEmpty(HeadersToInclude)) + { + string headersSerialized = JsonConvert.SerializeObject(actionExecutedContext.Response.Headers.Where(h => HeadersToInclude.Contains(h.Key))); + + _webApiCache.Add(cachekey + Constants.Headers, + headersSerialized, + cacheTime.AbsoluteExpiration, baseKey); + } } } } @@ -251,6 +274,19 @@ private static void SetEtag(HttpResponseMessage message, string etag) } } + protected virtual void AddCachedHeaders(HttpResponseMessage response, string headers) + { + var headersDeserialized = JsonConvert.DeserializeObject>>>(headers); + + foreach (var header in headersDeserialized) + { + foreach (var headerValue in header.Value) + { + response.Headers.Add(header.Key, headerValue); + } + } + } + Task IActionFilter.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func> continuation) { if (actionContext == null) From 65200472ad3fb065c2fb8233311611405c983615 Mon Sep 17 00:00:00 2001 From: Matt Lucas Date: Thu, 23 Apr 2015 10:30:40 -0400 Subject: [PATCH 2/2] Fixed AddCachedHeaders being called on null value. --- src/WebApi.OutputCache.V2/CacheOutputAttribute.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs b/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs index 258f443..87e74eb 100644 --- a/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs +++ b/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs @@ -161,7 +161,6 @@ private void OnActionExecuting(HttpActionContext actionContext) { var time = CacheTimeQuery.Execute(DateTime.Now); var quickResponse = actionContext.Request.CreateResponse(HttpStatusCode.NotModified); - AddCachedHeaders(quickResponse, cachekey); if (responseHeaders != null) AddCachedHeaders(quickResponse, responseHeaders); ApplyCacheHeaders(quickResponse, time); actionContext.Response = quickResponse;