async public Task FilterAsync(HttpRequest Request, HttpResponse Response) { var FilePath = Request.Url.Path; if (Path.GetExtension(FilePath) == "") { if (Directory.Exists(FilePath)) { FilePath = Url.Normalize(FilePath + "/index.html"); } } //var CacheKey = FilePath.ToLowerInvariant(); //var CacheKey = FilePath; var CachedResult = await Cache.GetAsync(FilePath, async () => { var Extension = Path.GetExtension(FilePath); if (ExtensionHandlersAsync.ContainsKey(Extension)) { try { return await ExtensionHandlersAsync[Extension](new HandlerStruct(this) { FileSystem = VirtualFileSystem, FilePath = FilePath, }); } catch (FileNotFoundException) { throw (new HttpException(HttpCode.NOT_FOUND_404)); } } if (Cache.Enabled) { await Console.Out.WriteLineAsync(String.Format("Caching '{0}'", FilePath)); } var FileInfo = await VirtualFileSystem.GetFileInfoAsync(FilePath); if (FileInfo.Exists) { bool ShouldCacheInMemory = FileInfo.Length <= CacheSizeThresold; string ETag = null; byte[] Data = null; if (ShouldCacheInMemory) { Data = await VirtualFileSystem.ReadAsBytesAsync(FilePath); ETag = BitConverter.ToString(MD5.Create().ComputeHash(Data)); } return new ResultStruct() { RealFilePath = FilePath, ContentType = MimeType.GetFromPath(FilePath), FileInfo = FileInfo, ETag = ETag, Data = Data, Exists = true, }; } else { throw (new HttpException(HttpCode.NOT_FOUND_404)); } }); Response.Headers["Content-Type"] = CachedResult.ContentType; if (CachedResult.ETag != null) { Response.Headers["ETag"] = CachedResult.ETag; } Response.Headers["Date"] = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture); Response.Headers["Last-Modified"] = CachedResult.FileInfo.LastWriteTimeUtc.ToString("R", CultureInfo.InvariantCulture); Response.Headers["Cache-Control"] = "max-age=2419200, private"; Response.Headers["Expires"] = "Wed, 11 Apr 2022 18:23:41 GMT"; // Check ETag if (Request.Headers["If-None-Match"] != "") { if (Request.Headers["If-None-Match"] == CachedResult.ETag) { throw(new HttpException(HttpCode.NOT_MODIFIED_304)); } } // Check Last-Modified if (Request.Headers["If-Modified-Since"] != "") { var RequestIfModifiedSince = DateTime.ParseExact(Request.Headers["If-Modified-Since"], "R", CultureInfo.InvariantCulture); if (RequestIfModifiedSince == CachedResult.FileInfo.LastWriteTimeUtc) { throw(new HttpException(HttpCode.NOT_MODIFIED_304)); } } Response.Buffering = true; Response.ChunkedTransferEncoding = false; /* Cache-Control:max-age=2419200, private Connection:keep-alive Date:Wed, 14 Mar 2012 14:52:54 GMT Expires:Wed, 11 Apr 2012 14:52:54 GMT Last-Modified:Wed, 11 Jan 2012 13:52:46 GMT */ Response.Headers["Content-Length"] = CachedResult.FileInfo.Length.ToString(); // Cached byte[] if (CachedResult.Data != null) { await Response.WriteAsync(CachedResult.Data); } // No cached byte[], stream the file else { Response.Buffering = false; //Response.ChunkedTransferEncoding = true; await Response.StreamFileASync(CachedResult.RealFilePath); } }