/// <summary> /// This will make the browser and server keep the output /// in its cache and thereby improve performance. /// See http://en.wikipedia.org/wiki/HTTP_ETag /// </summary> /// <param name="path"> /// The combined path to the items. /// </param> /// <param name="context"> /// the <see cref="T:System.Web.HttpContext">HttpContext</see> object that provides /// references to the intrinsic server objects /// </param> /// <param name="responseType"> /// The HTTP MIME type to to send. /// </param> /// <param name="futureExpire"> /// Whether the response headers should be set to expire in the future. /// </param> /// <param name="fileMonitors"> /// The file Monitors. /// </param> protected void SetHeaders(string path, HttpContext context, ResponseType responseType, bool futureExpire, IList <string> fileMonitors) { // Generate a hash from the combined last write times of any monitors and // the path. StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(path); if (fileMonitors != null) { foreach (string fileMonitor in fileMonitors) { FileInfo fileInfo = new FileInfo(fileMonitor); stringBuilder.AppendFormat("{0}", fileInfo.LastWriteTimeUtc); } } int hash = stringBuilder.ToString().GetHashCode(); HttpResponse response = context.Response; HttpCachePolicy cache = response.Cache; response.ContentType = responseType.ToDescription(); cache.VaryByHeaders["Accept-Encoding"] = true; if (futureExpire) { int maxCacheDays = CruncherConfiguration.Instance.MaxCacheDays; cache.SetExpires(DateTime.UtcNow.AddDays(maxCacheDays)); cache.SetMaxAge(new TimeSpan(maxCacheDays, 0, 0, 0)); if (fileMonitors != null) { response.AddFileDependencies(fileMonitors.ToArray()); cache.SetLastModifiedFromFileDependencies(); } cache.SetValidUntilExpires(false); } else { cache.SetExpires(DateTime.UtcNow.AddDays(-1)); cache.SetMaxAge(new TimeSpan(0, 0, 0, 0)); } cache.SetRevalidation(HttpCacheRevalidation.AllCaches); string etag = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", hash); string incomingEtag = context.Request.Headers["If-None-Match"]; cache.SetETag(etag); cache.SetCacheability(HttpCacheability.Public); if (string.Compare(incomingEtag, etag, StringComparison.Ordinal) != 0) { return; } response.Clear(); response.StatusCode = (int)HttpStatusCode.NotModified; response.SuppressContent = true; }