Restart asp.net response before it is cached with dynamicCompressionBeforeCache

My ASP.NET library sets up a response filter to parse and change the output of HTML pages. This works until the following is included in web.config:

<system.webServer> <urlCompression doDynamicCompression="true" dynamicCompressionBeforeCache="true" /> </system.webServer> 

My response filter is still being called, but what seems to be compressed rather than the original HTML is being passed.

How can I guarantee that my rewriting will happen before the page is stored in the output cache?

Setting dynamicCompressionBeforeCache to false is not an option, as this library is intended for use in other web applications, which may have good reasons for enabling compression.

+7
source share
2 answers

Alexb's answer helped me figure out the solution.

The key understood that my response filter was triggered after the IIS dynamic I / O module. This can be fixed by forcing the filter to start by resetting the response immediately after the request handler is executed.

 public class MyModule : IHttpModule { public void Init(HttpApplication application) { application.BeginRequest += application_BeginRequest; application.PostRequestHandlerExecute += application_PostRequestHandlerExecute; } void application_BeginRequest(object sender, EventArgs e) { // Install response filter var response = ((HttpApplication)sender).Context.Response; response.Filter = new RewritingFilter(response.Filter); } void application_PostRequestHandlerExecute(object sender, EventArgs e) { // Flush immediately after the request handler has finished. // This is Before the output cache compression happens. var response = ((HttpApplication)sender).Context.Response; response.Flush(); } public void Dispose() { } } 
+5
source

According to this blog post , DynamicCompressionModule, which is responsible for handling dynamic compression, starts at the ReleaseRequestState stage (which happens before UpdateRequestCache, when the page is stored in the output cache). Therefore:

  • if you want to process the response before performing dynamic compression, then you should put your filtering code in the HttpModule, which is connected to the PostRequestHandlerExecute event;
  • if you want to handle response caching, it does, but after compression you have to put your filter code in the HttpModule, which fires the PostReleaseRequestState event.

Here is an example of how to do this:

 public class SampleModule : IHttpModule { public void Dispose() { return; } public void Init(HttpApplication context) { context.PostRequestHandlerExecute += new EventHandler(App_OnPostRequestHandlerExecute); context.PostReleaseRequestState += new EventHandler(App_OnPostReleaseRequestState); } private void App_OnPostRequestHandlerExecute(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; HttpResponse response = app.Context.Response; response.Write("<b>Modified!</b>"); } private void App_OnPostReleaseRequestState(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; HttpResponse response = app.Context.Response; //check if the output has been compressed - make sure to actually test if for whatever content encoding you want to deal with if (response.Headers["Content-Encoding"] != null) { //do stuff } else { //do some other stuff } } } 

And then register your module using the web.config file:

 <add name="SampleModule" type="My.ModuleNamespace.SampleModule" /> 
+3
source

All Articles