2 // System.Web.Caching.OutputCacheModule
5 // Jackson Harper (jackson@ximian.com)
7 // (C) 2003 Novell, Inc (http://www.novell.com)
12 namespace System.Web.Caching {
14 internal sealed class OutputCacheModule : IHttpModule {
16 public OutputCacheModule ()
20 public void Dispose ()
24 public void Init (HttpApplication app)
26 app.AddOnResolveRequestCacheAsync (
27 new BeginEventHandler (OnBeginRequestCache),
28 new EndEventHandler (OnEndRequestCache));
30 app.AddOnUpdateRequestCacheAsync (
31 new BeginEventHandler (OnBeginUpdateCache),
32 new EndEventHandler (OnEndUpdateCache));
35 IAsyncResult OnBeginRequestCache (object o, EventArgs args, AsyncCallback cb, object data)
37 HttpApplication app = (HttpApplication) o;
38 HttpContext context = app.Context;
40 string vary_key = context.Request.FilePath;
41 CachedVaryBy varyby = context.Cache [vary_key] as CachedVaryBy;
48 key = varyby.CreateKey (vary_key, context);
49 c = context.Cache [key] as CachedRawResponse;
51 if (c != null && context.Timestamp < c.Policy.Expires) {
53 context.Response.ClearContent ();
54 context.Response.BinaryWrite (c.GetData (), 0, c.ContentLength);
56 context.Response.ClearHeaders ();
57 context.Response.SetCachedHeaders (c.Headers);
58 context.Response.StatusCode = c.StatusCode;
59 context.Response.StatusDescription = c.StatusDescription;
61 app.CompleteRequest ();
62 } else if (c != null) {
63 context.Cache.Remove (key);
67 HttpAsyncResult result = new HttpAsyncResult (cb,this);
68 result.Complete (true, o, null);
73 void OnEndRequestCache (IAsyncResult result)
77 IAsyncResult OnBeginUpdateCache (object o, EventArgs args, AsyncCallback cb, object data)
79 HttpApplication app = (HttpApplication) o;
80 HttpContext context = app.Context;
81 HttpAsyncResult result;
83 if (context.Response.IsCached && context.Response.StatusCode == 200)
84 DoCacheInsert (context);
86 result = new HttpAsyncResult (cb, this);
87 result.Complete (true, o, null);
91 void OnEndUpdateCache (IAsyncResult result)
95 private void DoCacheInsert (HttpContext context)
97 string vary_key = context.Request.FilePath;
99 CachedVaryBy varyby = context.Cache [vary_key] as CachedVaryBy;
100 CachedRawResponse prev = null;
103 if (varyby == null) {
104 varyby = new CachedVaryBy (context.Response.Cache);
105 context.Cache.InsertPrivate (vary_key, varyby, null,
106 Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
107 CacheItemPriority.Normal, null);
111 key = varyby.CreateKey (vary_key, context);
114 prev = context.Cache [key] as CachedRawResponse;
116 if (IsExpired (context, prev)) {
117 CachedRawResponse c = context.Response.GetCachedResponse ();
118 string [] files = new string [0];
119 string [] keys = new string [] { vary_key };
121 context.Cache.InsertPrivate (key, c, new CacheDependency (files, keys),
122 context.Response.Cache.Expires,
123 Cache.NoSlidingExpiration,
124 CacheItemPriority.Normal, null);
128 private bool IsExpired (HttpContext context, CachedRawResponse crr)
130 if (crr == null || context.Timestamp > crr.Policy.Expires)