public void ProcessRequest(HttpContext context) { string filePath = context.Request.PhysicalPath; bool isCssFile = filePath.EndsWith(".css", StringComparison.OrdinalIgnoreCase); if (File.Exists(filePath) == false) { throw new HttpException(404, string.Format("文件{0}不存在。", filePath)); } LazyFileInfo fileinfo = new LazyFileInfo(filePath); // 设置输出缓存头 context.Response.Cache.SetCacheability(HttpCacheability.Public); // 如果请求的URL包含查询字符串,就认为是包含了版本参数,此时设置缓存时间为【一年】 if (isCssFile == false && context.Request.QueryString.Count > 0) { context.Response.AppendHeader("X-StaticFileHandler", "1year"); context.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(24 * 60 * 60 * 365)); context.Response.Cache.SetExpires(DateTime.Now.AddYears(1)); } else { int duration = GetDuration(fileinfo); context.Response.AppendHeader("X-StaticFileHandler", duration.ToString()); context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(duration)); //context.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(duration)); // 上面的代码不起作用,只能用下面的方法来处理了。 context.Response.Cache.AppendCacheExtension("max-age=" + duration.ToString()); } // 设置响应内容标头 string contentType = (string)s_mineTable[fileinfo.Extension]; if (contentType == null) { contentType = GetMimeType(fileinfo); s_mineTable[fileinfo.Extension] = contentType; } context.Response.ContentType = contentType; if (isCssFile) { OutputCssFile(context); } else { // 输出文件内容 context.Response.TransmitFile(filePath); } }
private int GetDuration(LazyFileInfo file) { if (s_durationTable == null) { return(s_CacheDuration); } object val = s_durationTable[file.Extension]; if (val == null) { return(s_CacheDuration); } return((int)val); }
private string GetMimeType(LazyFileInfo file) { string mimeType = "application/octet-stream"; if (string.IsNullOrEmpty(file.Extension)) { return(mimeType); } using (RegistryKey regKey = Registry.ClassesRoot.OpenSubKey(file.Extension.ToLower())) { if (regKey != null) { object regValue = regKey.GetValue("Content Type"); if (regValue != null) { mimeType = regValue.ToString(); } } } return(mimeType); }
/// <summary> /// 处理请求,输出文件内容以及设置缓存响应头 /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { Init(); string filePath = context.Request.PhysicalPath; bool isCssFile = filePath.EndsWith(".css", StringComparison.OrdinalIgnoreCase); if (RetryFile.Exists(filePath) == false) { new Http404Result().Ouput(context); return; } LazyFileInfo fileinfo = new LazyFileInfo(filePath); //string etagHeader = context.Request.Headers["If-None-Match"]; //if( string.IsNullOrEmpty(etagHeader) == false ) { // // 如果文件没有修改,就返回304响应 // if( fileinfo.LastWriteTime.Ticks.ToString() == etagHeader ) { // context.Response.StatusCode = 304; // context.Response.End(); // return; // } //} // 说明:Etag响应头在有些场景下会不起使用,例如VS自带的WEB服务器,或者Windows身份认证中。 // 因此现在采用SetLastModified + "If-Modified-Since" 的方式来识别304请求。 // 如果加了版本号,就表示需要长期缓存的文件,此时当文件没有修改时,用304来结束请求。 if (isCssFile == false && // CSS文件不能用304来响应,否则图片永远不能刷新 context.Request.QueryString.Count > 0) { string modifiedSince = context.Request.Headers["If-Modified-Since"]; if (string.IsNullOrEmpty(modifiedSince) == false) { DateTime dt; if (DateTime.TryParse(modifiedSince, out dt)) { // 因为要排除毫秒,所以判断是否小于1秒 if ((fileinfo.LastWriteTime - dt).TotalSeconds < 1.0) { context.Response.StatusCode = 304; context.Response.End(); return; } } } } // 设置输出缓存头 context.Response.Cache.SetCacheability(HttpCacheability.Public); // 如果请求的URL包含查询字符串,就认为是包含了版本参数,此时设置缓存时间为【一年】 if (isCssFile == false && // 注意:这里仍然要排除CSS文件 context.Request.QueryString.Count > 0) { context.Response.AppendHeader("X-StaticFileHandler", "1year"); context.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(24 * 60 * 60 * 365)); context.Response.Cache.SetExpires(DateTime.Now.AddYears(1)); } else { int duration = GetDuration(fileinfo); context.Response.AppendHeader("X-StaticFileHandler", duration.ToString()); context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(duration)); //context.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(duration)); // 上面的代码不起作用,只能用下面的方法来处理了。 context.Response.Cache.AppendCacheExtension("max-age=" + duration.ToString()); } // 设置HTTP缓存响应头 //context.Response.Cache.SetETag(fileinfo.LastWriteTime.Ticks.ToString()); context.Response.Cache.SetLastModified(fileinfo.LastWriteTime); // 设置响应内容标头 string contentType = (string)s_mineTable[fileinfo.Extension]; if (contentType == null) { contentType = GetMimeType(fileinfo); s_mineTable[fileinfo.Extension] = contentType; } context.Response.ContentType = contentType; // 输出文件内容 if (isCssFile) { OutputCssFile(context); } else { context.Response.TransmitFile(filePath); } }