public void Set(string key, CacheItem cacheItem) { _workContext.HttpContext.Cache.Add( key, cacheItem, null, cacheItem.ValidUntilUtc, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null); }
public void Set(string key, CacheItem cacheItem) { var record = _repository.Table.FirstOrDefault(x => x.CacheKey == key); if (record == null) { record = new CacheItemRecord(); Convert(cacheItem, record); _repository.Create(record); return; } Convert(cacheItem, record); }
private void Convert(CacheItem cacheItem, CacheItemRecord record) { record.CacheKey = cacheItem.CacheKey; record.CachedOnUtc = cacheItem.CachedOnUtc; record.ContentType = cacheItem.ContentType; record.InvariantCacheKey = cacheItem.InvariantCacheKey; record.Output = cacheItem.Output; record.QueryString = cacheItem.QueryString; record.StatusCode = cacheItem.StatusCode; record.Tags = String.Join(";", cacheItem.Tags); record.Tenant = cacheItem.Tenant; record.Url = cacheItem.Url; record.ValidUntilUtc = cacheItem.ValidUntilUtc; }
private CacheItem Convert(CacheItemRecord record) { var cacheItem = new CacheItem(); cacheItem.CacheKey = record.CacheKey; cacheItem.CachedOnUtc = record.CachedOnUtc; cacheItem.ContentType = record.ContentType; cacheItem.InvariantCacheKey = record.InvariantCacheKey; cacheItem.Output = record.Output; cacheItem.QueryString = record.QueryString; cacheItem.StatusCode = record.StatusCode; cacheItem.Tags = record.Tags.Split(';'); cacheItem.Tenant = record.Tenant; cacheItem.Url = record.Url; cacheItem.ValidUntilUtc = record.ValidUntilUtc; return cacheItem; }
/// <summary> /// Define valid cache control values /// </summary> private void ApplyCacheControl(CacheItem cacheItem, HttpResponseBase response, string content) { if (_maxAge > 0) { var maxAge = new TimeSpan(0, 0, 0, _maxAge); //cacheItem.ValidUntilUtc - _clock.UtcNow; if (maxAge.TotalMilliseconds < 0) { maxAge = TimeSpan.FromSeconds(0); } response.Cache.SetCacheability(HttpCacheability.Public); response.Cache.SetMaxAge(maxAge); } response.Cache.SetETag(content.GetHashCode().ToString(CultureInfo.InvariantCulture)); response.Cache.SetOmitVaryStar(true); // different tenants with the same urls have different entries response.Cache.VaryByHeaders["HOST"] = true; // Set the Vary: Accept-Encoding response header. // This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed. // The correct version of the resource is delivered based on the client request header. // This is a good choice for applications that are singly homed and depend on public proxies for user locality. response.Cache.VaryByHeaders["Accept-Encoding"] = true; // create a unique cache per browser, in case a Theme is rendered differently (e.g., mobile) // c.f. http://msdn.microsoft.com/en-us/library/aa478965.aspx // c.f. http://stackoverflow.com/questions/6007287/outputcache-varybyheader-user-agent-or-varybycustom-browser response.Cache.SetVaryByCustom("browser"); // enabling this would create an entry for each different browser sub-version // response.Cache.VaryByHeaders.UserAgent = true; }
public void OnResultExecuted(ResultExecutedContext filterContext) { var response = filterContext.HttpContext.Response; // save the result only if the content can be intercepted if (_filter == null) return; // only for ViewResult right now, as we don't want to handle redirects, HttpNotFound, ... if (filterContext.Result as ViewResultBase == null) { Logger.Debug("Ignoring none ViewResult response"); return; } // check if there is a specific rule not to cache the whole route var configurations = _cacheService.GetRouteConfigurations(); var route = filterContext.Controller.ControllerContext.RouteData.Route; var key = _cacheService.GetRouteDescriptorKey(filterContext.HttpContext, route); var configuration = configurations.FirstOrDefault(c => c.RouteKey == key); // do not cache ? if (configuration != null && configuration.Duration == 0) { return; } // ignored url ? if (IsIgnoredUrl(filterContext.RequestContext.HttpContext.Request.AppRelativeCurrentExecutionFilePath, _ignoredUrls)) { return; } // get contents response.Flush(); var output = _filter.GetContents(response.ContentEncoding); if (String.IsNullOrWhiteSpace(output)) { return; } var tokenIndex = output.IndexOf(AntiforgeryTag, StringComparison.Ordinal); // substitute antiforgery token by a beacon if (tokenIndex != -1) { var tokenEnd = output.IndexOf(">", tokenIndex, StringComparison.Ordinal); var sb = new StringBuilder(); sb.Append(output.Substring(0, tokenIndex)); sb.Append(AntiforgeryBeacon); sb.Append(output.Substring(tokenEnd + 1)); output = sb.ToString(); } // default duration of specific one ? var cacheDuration = configuration != null && configuration.Duration.HasValue ? configuration.Duration.Value : _cacheDuration; // include each of the content item ids as tags for the cache entry var contentItemIds = _displayedContentItemHandler.GetDisplayed().Select(x => x.ToString(CultureInfo.InvariantCulture)).ToArray(); var cacheItem = new CacheItem { ContentType = response.ContentType, StatusCode = response.StatusCode, CachedOnUtc = _now, ValidUntilUtc = _now.AddSeconds(cacheDuration), QueryString = filterContext.HttpContext.Request.Url.Query, Output = output, CacheKey = _cacheKey, InvariantCacheKey = _invariantCacheKey, Tenant = _shellSettings.Name, Url = filterContext.HttpContext.Request.Url.AbsolutePath, Tags = new[] { _invariantCacheKey }.Union(contentItemIds).ToArray() }; ApplyCacheControl(cacheItem, response, output); Logger.Debug("Cache item added: " + cacheItem.CacheKey); // remove old cache data _cacheService.RemoveByTag(_invariantCacheKey); // add data to cache _cacheStorageProvider.Set(_cacheKey, cacheItem); // add to the tags index foreach (var tag in cacheItem.Tags) { _tagCache.Tag(tag, _cacheKey); } }
public void OnResultExecuted(ResultExecutedContext filterContext) { var response = filterContext.HttpContext.Response; // save the result only if the content can be intercepted if (_filter == null) return; // only for ViewResult right now, as we don't want to handle redirects, HttpNotFound, ... if (filterContext.Result as ViewResultBase == null) { Logger.Debug("Ignoring none ViewResult response"); return; } // check if there is a specific rule not to cache the whole route var configurations = _cacheService.GetRouteConfigurations(); var route = filterContext.Controller.ControllerContext.RouteData.Route; var key = _cacheService.GetRouteDescriptorKey(filterContext.HttpContext, route); var configuration = configurations.FirstOrDefault(c => c.RouteKey == key); // do not cache ? if (configuration != null && configuration.Duration == 0) { return; } // ignored url ? if (IsIgnoredUrl(filterContext.RequestContext.HttpContext.Request.AppRelativeCurrentExecutionFilePath, _ignoredUrls)) { return; } // get contents response.Flush(); var output = _filter.GetContents(response.ContentEncoding); if (String.IsNullOrWhiteSpace(output)) { return; } var tokenIndex = output.IndexOf(AntiforgeryTag, StringComparison.Ordinal); // substitute antiforgery token by a beacon if (tokenIndex != -1) { var tokenEnd = output.IndexOf(">", tokenIndex, StringComparison.Ordinal); var sb = new StringBuilder(); sb.Append(output.Substring(0, tokenIndex)); sb.Append(AntiforgeryBeacon); sb.Append(output.Substring(tokenEnd + 1)); output = sb.ToString(); } // default duration of specific one ? var cacheDuration = configuration != null && configuration.Duration.HasValue ? configuration.Duration.Value : _cacheDuration; var cacheItem = new CacheItem { ContentType = response.ContentType, StatusCode = response.StatusCode, CachedOnUtc = _now, ValidUntilUtc = _now.AddSeconds(cacheDuration), QueryString = filterContext.HttpContext.Request.Url.Query, Output = output, CacheKey = _cacheKey, InvariantCacheKey = _invariantCacheKey, Tenant = _shellSettings.Name, Url = filterContext.HttpContext.Request.Url.AbsolutePath }; ApplyCacheControl(cacheItem, response, output); Logger.Debug("Cache item added: " + cacheItem.CacheKey); // remove old cache data RemoveFromCache(filterContext.HttpContext, item => item.InvariantCacheKey.Equals(_invariantCacheKey, StringComparison.OrdinalIgnoreCase)); // add data to cache filterContext.HttpContext.Cache.Add( _cacheKey, cacheItem, null, cacheItem.ValidUntilUtc, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null); }