HTTP Headers - content expiration solution

Discussion in 'ASP.NET 2.0' started by pkuijt, Nov 29, 2006.

  1. When transfering a website to DiscountASP I wanted to configure content expiration:
    what you can specify in IIS Manager, Default Web Site Properties, HTTP Headers tab

    I could not find anything related to this subject on the forum.

    Content expiration influences when a client decides to ask the server for a file, as long
    as it has not expired the client will not ask again, thus preventing a lot of round trips
    to the server. The files may already be cached, but this expiration also prevents the
    round trip with a 304 answer from the server, on my website this had a huge effect,
    I am on the other side of the world a traceroute has 156ms. Use content expiration for
    static files: e.g. *.gif, *.js etc.

    This solution assumes you have a wildcard application mapping for your website:
    IIS Manager, Default Web Site Properties, Home Directory tab, Configuration
    (you need a tech support ticket to get this configured on DiscountASP)

    The wildcard mapping lets you 'see' all files, I was a little afraid for performance
    effects of the wildcard mapping, but that seems no problem at all. Web.config
    determines what file extensions are really handled.

    The solution involves writing a derived class for DefaultHttpHandler. I did override
    BeginProcessRequest(), where I used HttpCachePolicy.AppendCacheExtension()
    to specify the expiration parameter. The parameter is initialized from web.config.
    Refer to the MSDN library and RFC docs what you can specify there.

    Hereby the code for the handler with web.config text.
    This is not tested very well, I just wrote this, and checked the
    Http headers (with Fiddler, the Http debugging proxy) for the Cache-Control
    response header, and I saw that it worked. One could imagine extending this
    solution to support other member methods of HttpCachePolicy.

    I thought I share this,

    Peter

    ps I would have attached a compiled dll file but I get an error while uploading:
    * You cannot upload files that use MIME type : application/octet-stream.


    c# code to be compiled into a Cache.dll file
    -------------------------------------
    using System;
    using System.Collections.Specialized;
    using System.Configuration;
    using System.Web;
    // web.config example with two file types cached *.gif, *.js
    //
    // <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    // <configSections>
    // ...
    // <section name="Cache" type="System.Configuration.NameValueSectionHandler" />
    // ...
    // </configSections>
    // ...
    // <system.web>
    // <httpHandlers>
    // <remove verb="*" path="*.gif"/>
    // <add verb="*" path="*.gif" type="Cache.CacheHttpHandler,Cache" validate="true"/>
    // <remove verb="*" path="*.js"/>
    // <add verb="*" path="*.js" type="Cache.CacheHttpHandler,Cache" validate="true"/>
    // ...
    // </httpHandlers>
    // ...
    // </system.web>
    // ...
    // <!-- config section for Cache -->
    // <Cache>
    // <add key="AppendCacheExtension" value="post-check=3600,pre-check=36000"/>
    // </Cache>
    // ...
    // </configuration>

    namespace Cache {
    /// <summary>
    /// uses HttpCachePolicy.AppendCacheExtension() to write a Cache Control HTTP Header
    /// </summary>
    public class CacheHttpHandler : DefaultHttpHandler {
    private string cacheExtensionString = null;
    public override IAsyncResult BeginProcessRequest(HttpContext context,
    AsyncCallback callback, object state) {
    if (string.IsNullOrEmpty(cacheExtensionString)) {
    NameValueCollection collection =
    (NameValueCollection)ConfigurationManager.GetSection("Cache");
    cacheExtensionString = collection["AppendCacheExtension"];
    }
    context.Response.Cache.AppendCacheExtension(cacheExtensionString);
    return base.BeginProcessRequest(context, callback, state);
    }
    // Enables pooling when set to true
    public override bool IsReusable { get { return true; } }
    }
    }
     

Share This Page