/// <summary> /// Get a fileHanderCacheItem for the requested file. /// </summary> /// <param name="entityStoredWithCompressionType">The compression type to use for the file.</param> /// <param name="entityCacheItem">The fileHandlerCacheItem </param> /// <returns>Returns true if a fileHandlerCacheItem can be created; otherwise false.</returns> public bool TryGetFileHandlerCacheItem(ResponseCompressionType entityStoredWithCompressionType, out EntityCacheItem entityCacheItem) { entityCacheItem = null; // If the response bytes are already cached, then deliver the bytes directly from cache var cacheKey = EmbeddedResourceEntityResponderType + ":" + entityStoredWithCompressionType + ":" + ResourcePath; var cachedValue = CacheManager.Get <EntityCacheItem>(cacheKey); if (cachedValue != null) { entityCacheItem = cachedValue; } else { //File does not exist if (!DoesEntityExists) { return(false); } //File too large to send if (ResourceSize > MaxFileSizeToServe) { return(false); } var etag = string.Empty; var lastModifiedFileTime = ResourceLastModified; //When a browser sets the If-Modified-Since field to 13-1-2010 10:30:58, another DateTime instance is created, but this one has a Ticks value of 633989754580000000 //But the time from the file system is accurate to a tick. So it might be 633989754586086250. var lastModified = new DateTime(lastModifiedFileTime.Year, lastModifiedFileTime.Month, lastModifiedFileTime.Day, lastModifiedFileTime.Hour, lastModifiedFileTime.Minute, lastModifiedFileTime.Second); var contentType = MimeTyper.GetMimeType(ResourceExtension); var contentLength = ResourceSize; //ETAG is always calculated from uncompressed entity data switch (MimeSetting.EtagMethod) { case EtagMethodType.MD5: using (var resourceStream = _assembly.GetManifestResourceStream(ResourcePath)) { etag = Hasher.CalculateMd5Etag(resourceStream); } break; case EtagMethodType.LastModified: etag = lastModified.ToString("r"); break; default: throw new Exception("Unknown etag method generation"); } entityCacheItem = new EntityCacheItem { Etag = etag, LastModified = lastModified, ContentLength = contentLength, ContentType = contentType, CompressionType = ResponseCompressionType.None }; if (MimeSetting.ServeFromMemory && (contentLength <= MimeSetting.MaxMemorySize)) { // When not compressed, buffer is the size of the file but when compressed, // initial buffer size is one third of the file size. Assuming, compression // will give us less than 1/3rd of the size using (var memoryStream = new MemoryStream( entityStoredWithCompressionType == ResponseCompressionType.None ? Convert.ToInt32(ResourceSize) : Convert.ToInt32((double)ResourceSize / 3))) { GetEntityData(entityStoredWithCompressionType, memoryStream); var entityData = memoryStream.ToArray(); var entityDataLength = entityData.LongLength; entityCacheItem.EntityData = entityData; entityCacheItem.ContentLength = entityDataLength; entityCacheItem.CompressionType = entityStoredWithCompressionType; } } //Put fileHandlerCacheItem into cache with 30 min sliding expiration, also if file changes then remove fileHandlerCacheItem from cache CacheManager.Insert( cacheKey, entityCacheItem, null, Cache.NoAbsoluteExpiration, MimeSetting.MemorySlidingExpiration, CacheItemPriority.BelowNormal, null); } return(true); }