I know its missing a point of having Sitecore CMS, however we need to put a site behind Azure CDN. We do not care about personalization, analytics etc. Is there any out of box way to set cache-control header to public, max age and ETag for 'everything', instead of just static files, media etc. Is there a processor I can extend to achieve this? Sitecore version 8.2 on VM. Any help appreciated. Thanks.
2 Answers
In App_Config/Sitecore.config there is a processor defined for setting browsercaching <processor type="Sitecore.Pipelines.RenderLayout.BrowserCaching, Sitecore.Kernel" />
You can take a look at its implementation in sitecore.kernel.dll
and you could add your own custom implementation by overriding it
public override void Process(RenderLayoutArgs args)
{
Assert.ArgumentNotNull((object) args, nameof (args));
Profiler.StartOperation("Update browser caching headers.");
PageContext page = Context.Page;
if (page == null || page.Page == null)
return;
BrowserCaching.SetCacheHeaders(page.Page);
if (Context.Item != null)
BrowserCaching.SetUpdateHeaders(Context.Item, page.Page);
Profiler.EndOperation();
}
Cristi answer pointed me to right direction, however at the end I extended GetPageRenderingProcessor.
public class CustomBrowserCaching : GetPageRenderingProcessor
{
public override void Process(GetPageRenderingArgs args)
{
//Item currentItem;
Assert.ArgumentNotNull((object)args, nameof(args));
Profiler.StartOperation("Update browser caching headers.");
HttpContext context = HttpContext.Current;
Item currentItem = PageContext.CurrentOrNull.Item;
if (context == null) return;
SetCacheHeaders(currentItem, context);
if (currentItem != null)
SetUpdateHeaders(currentItem, context);
Profiler.EndOperation();
}
private static void SetUpdateHeaders(Item currentItem, HttpContext context)
{
DateTime date = currentItem.Statistics.Updated;
if (date > DateTime.UtcNow)
{
date = DateTime.UtcNow;
}
context.Response.Cache.SetLastModified(date);
}
private static void SetCacheHeaders(Item item, HttpContext context)
{
if (Context.Site == null)
return;
context.Response.Cache.SetCacheability(HttpCacheability.Public);
var ts = new TimeSpan(24, 0, 0);
context.Response.Cache.SetMaxAge(ts);
context.Response.Cache.SetExpires(DateTime.Now.AddYears(1));
var date = item.Statistics.Updated;
if (date > DateTime.Now)
{
date = DateTime.Now;
}
context.Response.Cache.SetLastModified(date);
context.Response.Cache.SetETag(item.Statistics.Revision);
}
}
Patched these configs:
<setting name="DisableBrowserCaching">
<patch:attribute name="value">false</patch:attribute>
</setting>
<setting name="MediaResponse.Cacheability">
<patch:attribute name="value">Public</patch:attribute>
</setting>
Attached added config to zzz folder:
<mvc.getPageRendering>
<processor patch:after="*[@type='Sitecore.Mvc.Pipelines.Response.GetPageRendering.GetLayoutRendering, Sitecore.Mvc']" type="Your.Namespace.CustomBrowserCaching, Your.Assembly.Name">
</processor>
</mvc.getPageRendering>
Many of this has been taken from here https://www.flux-digital.com/blog/disabling-private-cache-sitecore-pages-not-working-sitecore-8-1-8-2/ .