2 // System.Web.Caching.OutputCacheModule
5 // Jackson Harper (jackson@ximian.com)
7 // (C) 2003 Novell, Inc (http://www.novell.com)
11 using System.Web.Util;
13 namespace System.Web.Caching {
15 internal sealed class OutputCacheModule : IHttpModule {
17 public OutputCacheModule ()
21 public void Dispose ()
25 public void Init (HttpApplication app)
27 app.AddOnResolveRequestCacheAsync (
28 new BeginEventHandler (OnBeginRequestCache),
29 new EndEventHandler (OnEndRequestCache));
31 app.AddOnUpdateRequestCacheAsync (
32 new BeginEventHandler (OnBeginUpdateCache),
33 new EndEventHandler (OnEndUpdateCache));
36 IAsyncResult OnBeginRequestCache (object o, EventArgs args, AsyncCallback cb, object data)
38 HttpApplication app = (HttpApplication) o;
39 HttpContext context = app.Context;
41 string vary_key = context.Request.FilePath;
42 CachedVaryBy varyby = context.Cache [vary_key] as CachedVaryBy;
49 key = varyby.CreateKey (vary_key, context);
50 c = context.Cache [key] as CachedRawResponse;
52 if (c != null && context.Timestamp < c.Policy.Expires) {
54 context.Response.ClearContent ();
55 context.Response.BinaryWrite (c.GetData (), 0, c.ContentLength);
57 context.Response.ClearHeaders ();
58 c.DateHeader.Value = TimeUtil.ToUtcTimeString (DateTime.Now);
59 context.Response.SetCachedHeaders (c.Headers);
61 context.Response.StatusCode = c.StatusCode;
62 context.Response.StatusDescription = c.StatusDescription;
64 app.CompleteRequest ();
65 } else if (c != null) {
66 context.Cache.Remove (key);
70 HttpAsyncResult result = new HttpAsyncResult (cb,this);
71 result.Complete (true, o, null);
76 void OnEndRequestCache (IAsyncResult result)
80 IAsyncResult OnBeginUpdateCache (object o, EventArgs args, AsyncCallback cb, object data)
82 HttpApplication app = (HttpApplication) o;
83 HttpContext context = app.Context;
84 HttpAsyncResult result;
86 if (context.Response.IsCached && context.Response.StatusCode == 200)
87 DoCacheInsert (context);
89 result = new HttpAsyncResult (cb, this);
90 result.Complete (true, o, null);
94 void OnEndUpdateCache (IAsyncResult result)
98 private void DoCacheInsert (HttpContext context)
100 string vary_key = context.Request.FilePath;
102 CachedVaryBy varyby = context.Cache [vary_key] as CachedVaryBy;
103 CachedRawResponse prev = null;
106 if (varyby == null) {
107 varyby = new CachedVaryBy (context.Response.Cache);
108 context.Cache.InsertPrivate (vary_key, varyby, null,
109 Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
110 CacheItemPriority.Normal, null);
114 key = varyby.CreateKey (vary_key, context);
117 prev = context.Cache [key] as CachedRawResponse;
119 if (IsExpired (context, prev)) {
120 CachedRawResponse c = context.Response.GetCachedResponse ();
121 string [] files = new string [0];
122 string [] keys = new string [] { vary_key };
124 context.Cache.InsertPrivate (key, c, new CacheDependency (files, keys),
125 context.Response.Cache.Expires,
126 Cache.NoSlidingExpiration,
127 CacheItemPriority.Normal, null);
131 private bool IsExpired (HttpContext context, CachedRawResponse crr)
133 if (crr == null || context.Timestamp > crr.Policy.Expires)