« Previous Next »

Thread: Response object and non ASP.NET output

Last post 06-26-2006 6:55 PM by anilr. 8 replies.

Average Rating Rate It (5)

RSS

Page 1 of 1 (9 items)

Sort Posts:

  • 06-18-2006, 2:11 AM

    • rstrahl
    • Top 150 Contributor
    • Joined on 08-20-2003, 1:08 PM
    • Paia, Hawaii
    • Posts 45

    Response object and non ASP.NET output

    This may be a silly question, but how do we access the IIS output stream from a managed module as opposed to the ASP.NET output stream?

    In one of my apps I have a dead simple module that writes a message at the bottom of each page in PostRequestHandlerExecute(). If I run this in the Integrated Pipeline this code works fine with any managed code pages/requests as I would expect.

    However, if I fire against say a static HTML document, the message is not written.

    In debugging I can see that the code gets hit but it doesn't do anything

    private void application_PostRequestHandlerExecute(object sender, EventArgs e)

    {

          HttpApplication app = (HttpApplication) sender;

         

          // *** Must make sure we don't add this to data responses!!!

          if (app.Context.Response.ContentType.ToLower() == "text/html")

                app.Context.Response.Write(SharewareMessage);

    }

    Now I suppose that when I access a static page here I won't have a Response object that is writing output to the core IIS output stream and that's why this isn't working.

    So, how would I do this with non-managed content?

    +++ Rick ---

    Rick Strahl [MVP]
    West Wind Technologies
    Making waves on the Web
    www.west-wind.com/weblog
  • 06-18-2006, 2:40 AM In reply to

    • rstrahl
    • Top 150 Contributor
    • Joined on 08-20-2003, 1:08 PM
    • Paia, Hawaii
    • Posts 45

    Re: Response object and non ASP.NET output

    Ok, after reading another message here I found the workaround of removing the Content-Length header, which worked - sort of.

    Problem is that IIS automatically GZips the content, so the output is generated with GZip and my output is not generated with it. End result my added content doesn't display.

    Only workaround I see at the moment is to remove the static compression module.

    Is there a way to force the handler not to use Compression for this request? And the trick of removing the Content-Encoding Header here unfortunately doesn't work.

    It would seem that Compression should occur as one of the very last steps in pipeline processing so that other module content can update pages and still receive compression (or alternately IIS deciding not to compress a page that has dynamic content).

    As a side note - it would also be really nice if you could set some sort of path filter similar to handler path filters to allow control operation of a module. In this scenario it'd be nice to apply filtering to what gets compressed. I see this can be done with the HttpCompression section in ApplicationHost, but that looks like a hairy section to touch and is probably a global setting which is not appropriate.         

     

    +++ Rick ---

    Rick Strahl [MVP]
    West Wind Technologies
    Making waves on the Web
    www.west-wind.com/weblog
  • 06-18-2006, 1:57 PM In reply to

    • mvolo
    • Top 25 Contributor
    • Joined on 09-17-2003, 1:48 PM
    • Philadelphia, PA
    • Posts 584

    Re: Response object and non ASP.NET output

    Just like you observe, this is a limitation of using static compression.  Static compression essentially precompresses static files on disk, and serves the compressed content.  This prevents you from being able to simply append or filter the response output unless you are able to deal with the compression output properly (I am not even sure its possible, but I dont know much about the compression algorithm we use so it may be).

    One trick here is to use dynamic compression instead, which is applied as the content is sent so that any response manipulations you perform prior to it are included correctly.  This would allow both appending to the response in PostRequestHandlerExecute and later events, as well as preprocessing the entire response in the HttpResponse.Filter stream.

    You can turn off static compression by using the urlCompression configuration section, which allows both dynamic and static compression to be turned on/off per url.  This should be sufficient if all you want to do is turn off static compression for static files in your app, but if you want to only turn it off for .html files and not .jpg files, you may want something more finegrained.  You can then use the <httpCompression>/<staticTypes> collection in applicationHost.config to turn it off for particular content types, but only globally in applicationHost.config (affecting all apps on the machine). 

    If this is still not enough, let me know and I'll see if there is a way to programatically prevent static compression on each request based on your determination.

    Thanks,

    This posting is provided "AS IS" with no warranties, and confers no rights.
  • 06-19-2006, 1:28 AM In reply to

    • rstrahl
    • Top 150 Contributor
    • Joined on 08-20-2003, 1:08 PM
    • Paia, Hawaii
    • Posts 45

    Re: Response object and non ASP.NET output

    Hi Mike,

    For turning off compression altogether the easiest seems to be to just remove the module in the local application no?

    It looks ApplicationHost.config has settings that determine what gets compressed in the httpCompression section. I tried copying those settings to the local web.config but ASP.NET was not happy with that <g>.

    In relation to this, I'm wondering how this works at this point.

    How does this sort of static file processing work in light of caching - specifically kernal caching? Doesn't this mean, that every static file request now has to hit the pipeline IF any modules are hooked up?

    +++ Rick ---

    Rick Strahl [MVP]
    West Wind Technologies
    Making waves on the Web
    www.west-wind.com/weblog
  • 06-19-2006, 12:23 PM In reply to

    • mvolo
    • Top 25 Contributor
    • Joined on 09-17-2003, 1:48 PM
    • Philadelphia, PA
    • Posts 584

    Re: Response object and non ASP.NET output

    With the <urlCompression> section you get the benefit of turning off static compression per url, if you wish.  Otherwise, you can remove the module.  In contrast, the <httpCompression> section that has the mimetypes compressible and other settings is global only, so you can only set it in applicationHost.config for your entire machine ...

    You are right on about kernel caching - you only turn that on when the final output of the first request to the page is acceptable to be sent to the client on subsequent requests without any IIS (or any user mode) processing whatsoever - no logging, security filtering, rewriting, etc.  That is the tradeoff of the typically several hundred percent throughput boost you get with kernel caching :)

    This posting is provided "AS IS" with no warranties, and confers no rights.
  • 06-20-2006, 3:35 PM In reply to

    • anilr
    • Top 10 Contributor
    • Joined on 05-23-2006, 6:13 PM
    • Redmond, WA
    • Posts 2,247

    Re: Response object and non ASP.NET output

    Also, you can disable compression for specific requests by subscribing to BeginRequest and deleting the Accept-Encoding request header (there are new APIs in HttpRequest to edit request headers).

    As for kernel-caching, currently, there is no way for managed modules to disable kernel caching of a response - something we need to think about and get back to you about - you can however disable it using config using the system.webServer/caching/enableKernelCache attribute.

    - Anil

    Anil Ruia
    Senior Software Design Engineer
    IIS Core Server
  • 06-20-2006, 4:25 PM In reply to

    • rstrahl
    • Top 150 Contributor
    • Joined on 08-20-2003, 1:08 PM
    • Paia, Hawaii
    • Posts 45

    Re: Response object and non ASP.NET output

    Anil,

    Kernel caching requires some pretty stringent rules (specific headers etc.)... do the same rules still apply in IIS 7? If so it'd be relatively easy to bugger up a kernel caching request if necessary.

    After some more thought I think it's perfectly reasonable for requests that are cached not fire into the pipeline. Once cached there's no more control over the output - I think it's the only way to keep this powerful feature doing what it does well <g>...

    However, I think it would be really nice if there was an easier way to specify that you want - or don't want to kernel cache a request.

    Especially in ASP.NET - you can specify page caching, but there's no guarantee of how that caching occurs.

    Speaking of which how does the internal ASP.NET Cache deal with this same situation? If ASP.NET is caching the request, is it still firing module events? I would suspect the same rules should be applied - once cached no further 'modication' of content should be possible (other than clearing the cache entry).

    +++ Rick ---

    Rick Strahl [MVP]
    West Wind Technologies
    Making waves on the Web
    www.west-wind.com/weblog
  • 06-21-2006, 1:04 PM In reply to

    • mvolo
    • Top 25 Contributor
    • Joined on 09-17-2003, 1:48 PM
    • Philadelphia, PA
    • Posts 584

    Re: Response object and non ASP.NET output

    The ASP.NET output cache (and the new IIS user mode output cache) are both modules in the IIS pipeline.  They work right about so:

    (request comes in)

    ...
    -ResolveRequestCache: Output cache module checks if this request has a cached response based on the url, and previously saved vary settings.  If it does, it writes the response and short-circuits the request.  Go to directly Log, do not pass ExecuteRequestHandler, do not collect 200 dollars.
    ...
    -ExecuteRequestHandler: your page / handler executes and writes to response ...
                                          it also sets the desired cache settings into the Response.Cache (HttpCachePolicy)
    ...
    -UpdateRequestCache: Output cache module saves the response in the cache if it is eligible based on your settings
    ...
    -Log
    -End
    (done)

    So you can still do some preprocessing of cache hit requests prior to ResolveRequestCache, and you can do some post-processing in PreSendRequestHeaders and Log/End.  But, the majority of state-getting, and response building expensiveness is skipped when the response is sent from the cache like the doctor ordered.

    Mike

    This posting is provided "AS IS" with no warranties, and confers no rights.
  • 06-26-2006, 6:55 PM In reply to

    • anilr
    • Top 10 Contributor
    • Joined on 05-23-2006, 6:13 PM
    • Redmond, WA
    • Posts 2,247

    Re: Response object and non ASP.NET output

    Control of IIS output caching and kernel caching from a managed module is definitely something that would be desirable - this is currently a limitation in IIS7 integrated pipeline - we will hopefully be able to remove this limitation in the longhorn server timeframe.

     

    Anil Ruia
    Senior Software Design Engineer
    IIS Core Server
Page 1 of 1 (9 items)