可以在ASP.NET / IIS 7中有选择地禁用gzip压缩吗?
我使用长期的异步HTTP连接通过AJAX向客户端发送进度更新。 启用压缩时,不会以离散块的forms接收更新(出于显而易见的原因)。 禁用压缩(通过向添加
元素) 确实解决了问题:
但是,这会在站点范围内禁用压缩。 我想保留每个其他控制器和/或操作的压缩,除了这个。 这可能吗? 或者我将不得不用自己的web.config创建一个新的站点/区域? 欢迎任何建议。
PS写入HTTP响应的代码是:
var response = HttpContext.Response; response.Write(s); response.Flush();
@Aristos的回答将适用于WebForms,但在他的帮助下,我已经采用了更符合ASP.NET / MVC方法的解决方案。
创建一个新的filter以提供gzippingfunction:
public class GzipFilter : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); var context = filterContext.HttpContext; if (filterContext.Exception == null && context.Response.Filter != null && !filterContext.ActionDescriptor.IsDefined(typeof(NoGzipAttribute), true)) { string acceptEncoding = context.Request.Headers["Accept-Encoding"].ToLower();; if (acceptEncoding.Contains("gzip")) { context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress); context.Response.AppendHeader("Content-Encoding", "gzip"); } else if (acceptEncoding.Contains("deflate")) { context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress); context.Response.AppendHeader("Content-Encoding", "deflate"); } } } }
创建NoGzip
属性:
public class NoGzipAttribute : Attribute { }
使用web.config阻止IIS7进行gzipping攻击:
...
在Global.asax.cs中注册全局filter:
protected void Application_Start() { ... GlobalFilters.Filters.Add(new GzipFilter()); }
最后,使用NoGzip
属性:
public class MyController : AsyncController { [NoGzip] [NoAsyncTimeout] public void GetProgress(int id) { AsyncManager.OutstandingOperations.Increment(); ... } public ActionResult GetProgressCompleted() { ... } }
PS再一次,非常感谢@Aristos,感谢他的有用的想法和解决方案。
我发现了一种更简单的方法。 您可以选择性地禁用默认的IIS压缩(假设它在您的web.config中启用),而不是有选择地进行自己的压缩。
只需删除请求中的accept-encoding编码标头,IIS就不会压缩页面。
(:)的global.asax.cs
protected void Application_BeginRequest(object sender, EventArgs e) { try { HttpContext.Current.Request.Headers["Accept-Encoding"] = ""; } catch(Exception){} }
你希望什么时候你自己设置gzip压缩,selectivle? 在Application_BeginRequest上检查你想做什么以及什么时候不做压缩。 这是一个示例代码。
protected void Application_BeginRequest(Object sender, EventArgs e) { string cTheFile = HttpContext.Current.Request.Path; string sExtentionOfThisFile = System.IO.Path.GetExtension(cTheFile); if (sExtentionOfThisFile.Equals(".aspx", StringComparison.InvariantCultureIgnoreCase)) { string acceptEncoding = MyCurrentContent.Request.Headers["Accept-Encoding"].ToLower();; if (acceptEncoding.Contains("deflate") || acceptEncoding == "*") { // defalte HttpContext.Current.Response.Filter = new DeflateStream(prevUncompressedStream, CompressionMode.Compress); HttpContext.Current.Response.AppendHeader("Content-Encoding", "deflate"); } else if (acceptEncoding.Contains("gzip")) { // gzip HttpContext.Current.Response.Filter = new GZipStream(prevUncompressedStream, CompressionMode.Compress); HttpContext.Current.Response.AppendHeader("Content-Encoding", "gzip"); } } }