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;
12 using System.Collections;
14 namespace System.Web.Caching {
16 internal sealed class OutputCacheModule : IHttpModule {
18 private CacheItemRemovedCallback response_removed;
20 public OutputCacheModule ()
24 public void Dispose ()
28 public void Init (HttpApplication app)
30 app.AddOnResolveRequestCacheAsync (
31 new BeginEventHandler (OnBeginRequestCache),
32 new EndEventHandler (OnEndRequestCache));
34 app.AddOnUpdateRequestCacheAsync (
35 new BeginEventHandler (OnBeginUpdateCache),
36 new EndEventHandler (OnEndUpdateCache));
38 response_removed = new CacheItemRemovedCallback (OnRawResponseRemoved);
41 IAsyncResult OnBeginRequestCache (object o, EventArgs args, AsyncCallback cb, object data)
43 HttpApplication app = (HttpApplication) o;
44 HttpContext context = app.Context;
46 string vary_key = context.Request.FilePath;
47 CachedVaryBy varyby = context.Cache [vary_key] as CachedVaryBy;
54 key = varyby.CreateKey (vary_key, context);
55 c = context.Cache [key] as CachedRawResponse;
59 context.Response.ClearContent ();
60 context.Response.BinaryWrite (c.GetData (), 0, c.ContentLength);
62 context.Response.ClearHeaders ();
63 c.DateHeader.Value = TimeUtil.ToUtcTimeString (DateTime.Now);
64 context.Response.SetCachedHeaders (c.Headers);
66 context.Response.StatusCode = c.StatusCode;
67 context.Response.StatusDescription = c.StatusDescription;
69 app.CompleteRequest ();
70 } else if (c != null) {
71 context.Cache.Remove (key);
75 HttpAsyncResult result = new HttpAsyncResult (cb,this);
76 result.Complete (true, o, null);
81 void OnEndRequestCache (IAsyncResult result)
85 IAsyncResult OnBeginUpdateCache (object o, EventArgs args, AsyncCallback cb, object data)
87 HttpApplication app = (HttpApplication) o;
88 HttpContext context = app.Context;
89 HttpAsyncResult result;
91 if (context.Response.IsCached && context.Response.StatusCode == 200 &&
92 !context.Trace.IsEnabled)
93 DoCacheInsert (context);
95 result = new HttpAsyncResult (cb, this);
96 result.Complete (true, o, null);
100 void OnEndUpdateCache (IAsyncResult result)
104 private void DoCacheInsert (HttpContext context)
106 string vary_key = context.Request.FilePath;
108 CachedVaryBy varyby = context.Cache [vary_key] as CachedVaryBy;
109 CachedRawResponse prev = null;
112 if (varyby == null) {
113 varyby = new CachedVaryBy (context.Response.Cache, vary_key);
114 context.Cache.InsertPrivate (vary_key, varyby, null,
115 Cache.NoAbsoluteExpiration,
116 Cache.NoSlidingExpiration,
117 CacheItemPriority.Normal, null);
121 key = varyby.CreateKey (vary_key, context);
124 prev = context.Cache [key] as CachedRawResponse;
127 CachedRawResponse c = context.Response.GetCachedResponse ();
128 string [] files = new string [] { vary_key };
129 string [] keys = new string [] { vary_key };
130 bool sliding = context.Response.Cache.Sliding;
132 context.Cache.InsertPrivate (key, c, new CacheDependency (files, keys),
133 (sliding ? Cache.NoAbsoluteExpiration :
134 context.Response.Cache.Expires),
135 (sliding ? TimeSpan.FromSeconds (
136 context.Response.Cache.Duration) :
137 Cache.NoSlidingExpiration),
138 CacheItemPriority.Normal, response_removed);
140 varyby.ItemList.Add (key);
144 private void OnRawResponseRemoved (string key, object value, CacheItemRemovedReason reason)
146 CachedRawResponse c = (CachedRawResponse) value;
148 c.VaryBy.ItemList.Remove (key);
149 if (c.VaryBy.ItemList.Count != 0)
152 Cache cache = HttpRuntime.Cache;
153 cache.Remove (c.VaryBy.Key);