1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MonoRail
.Framework
21 /// Defines the cache configuration for an action.
23 [AttributeUsage(AttributeTargets
.Method
|AttributeTargets
.Class
, AllowMultiple
= false, Inherited
= true), Serializable
]
24 public class CacheAttribute
: Attribute
, ICachePolicyConfigurer
26 private readonly HttpCacheability cacheability
;
27 private bool allowInHistory
, slidingExpiration
, validUntilExpires
;
28 private bool setEtagFromFileDependencies
, setLastModifiedFromFileDependencies
;
29 private bool setNoServerCaching
, setNoStore
, setNoTransforms
, omitVaryStar
;
30 private string cacheExtension
;
33 private string varyByCustom
, varyByHeaders
, varyByParams
;
34 private DateTime
? lastModified
;
35 private TimeSpan
? maxAge
, proxyMaxAge
;
36 private HttpCacheRevalidation revalidation
;
38 #if DOTNET2SP1 || DOTNET35
39 private string varyByContentEncodings
;
43 /// Initializes a new instance of the <see cref="CacheAttribute"/> class.
45 /// <param name="cacheability">Sets the Cache-Control HTTP header.
46 /// The Cache-Control HTTP header controls how documents are to be cached on the network.</param>
47 public CacheAttribute(HttpCacheability cacheability
)
49 this.cacheability
= cacheability
;
51 allowInHistory
= true;
52 validUntilExpires
= true;
53 revalidation
= HttpCacheRevalidation
.None
;
57 /// From MSDN: Makes the response is available in the client browser
58 /// History cache, regardless of the HttpCacheability setting
59 /// made on the server, when the allow parameter is true.
62 /// When HttpCacheability is set to NoCache or ServerAndNoCache the Expires
63 /// HTTP header is by default set to -1; this tells the client not to
64 /// cache responses in the History folder, so that when you use the back/forward buttons
65 /// the client requests a new version of the response each time. You can override this
66 /// behavior by calling the SetAllowResponseInBrowserHistory method with the
67 /// allow parameter set to true.
69 /// If HttpCacheability is set to values other than NoCache or ServerAndNoCache, calling the SetAllowResponseInBrowserHistory method with either value for allow has no effect.
72 public bool AllowInHistory
74 get { return allowInHistory; }
75 set { allowInHistory = value; }
79 /// If true, sets the ETag HTTP header based on the time stamps of the handler's file dependencies.
81 public bool SetEtagFromFileDependencies
83 get { return setEtagFromFileDependencies; }
84 set { setEtagFromFileDependencies = value; }
88 /// If true, sets the Last-Modified HTTP header based on the time stamps of the handler's file dependencies.
90 public bool SetLastModifiedFromFileDependencies
92 get { return setLastModifiedFromFileDependencies; }
93 set { setLastModifiedFromFileDependencies = value; }
97 /// If true, stops all origin-server caching for the current response.
99 public bool SetNoServerCaching
101 get { return setNoServerCaching; }
102 set { setNoServerCaching = value; }
106 /// If true, sets the Cache-Control: no-store HTTP header.
108 public bool SetNoStore
110 get { return setNoStore; }
111 set { setNoStore = value; }
115 /// If true, sets the Cache-Control: no-transform HTTP header.
117 public bool SetNoTransforms
119 get { return setNoTransforms; }
120 set { setNoTransforms = value; }
124 /// If true, includes the vary:* header in the response when varying by parameters.
126 public bool OmitVaryStar
128 get { return omitVaryStar; }
129 set { omitVaryStar = value; }
133 /// From MSDN: Sets cache expiration to from absolute to sliding.
136 /// When cache expiration is set to sliding, the Cache-Control
137 /// HTTP header will be renewed with each response. This expiration mode
138 /// is identical to the IIS configuration option to add an expiration
139 /// header to all output set relative to the current time.
141 /// If you explicitly set sliding expiration to off (false), that setting
142 /// will be preserved and any attempts to enable sliding expiration will
143 /// silently fail. This method does not directly map to an HTTP header.
144 /// It is used by subsequent modules or worker requests to set origin-server cache policy.
147 public bool SlidingExpiration
149 get { return slidingExpiration; }
150 set { slidingExpiration = value; }
154 /// Specifies whether the ASP.NET cache should ignore HTTP Cache-Control
155 /// headers sent by the client that invalidate the cache.
158 /// This method is provided because some browsers, when refreshing a
159 /// page view, send HTTP cache invalidation headers to the Web server
160 /// and evict the page from the cache. When the validUntilExpires parameter
161 /// is true, ASP.NET ignores cache invalidation headers and the page
162 /// remains in the cache until it expires.
164 public bool ValidUntilExpires
166 get { return validUntilExpires; }
167 set { validUntilExpires = value; }
171 /// Text to be appended to the Cache-Control HTTP header.
173 public string CacheExtension
175 get { return cacheExtension; }
176 set { cacheExtension = value; }
180 /// Sets the ETag HTTP header to the specified string.
183 /// The ETag header is a unique identifier for a specific version of
184 /// a document. It is used by clients to validate client-cached content to
185 /// avoid requesting it again. Once an ETag header is set, subsequent
186 /// attempts to set it fail and an exception is thrown.
191 set { etag = value; }
195 /// Cache Duration (in seconds)
199 get { return duration; }
200 set { duration = value; }
203 #if DOTNET2SP1 || DOTNET35
205 /// Gets or sets the list of all Content-Encoding headers that will be used to vary the output cache.
207 public string VaryByContentEncodings
209 get { return varyByContentEncodings; }
210 set { varyByContentEncodings = value; }
215 /// Specifies a custom text string to vary cached output responses by.
217 public string VaryByCustom
219 get { return varyByCustom; }
220 set { varyByCustom = value; }
224 /// Gets or sets the list of all HTTP headers that will be used to vary cache output.
227 /// When a cached item has several vary headers, a separate version of
228 /// the requested document is available from the cache for each HTTP header type.
230 public string VaryByHeaders
232 get { return varyByHeaders; }
233 set { varyByHeaders = value; }
237 /// Gets or sets the list of parameters received by an HTTP GET or HTTP POST that affect caching.
240 /// A separate version of the requested document is available from the cache
241 /// for each named parameter in the VaryByParams collection.
243 public string VaryByParams
245 get { return varyByParams; }
246 set { varyByParams = value; }
250 /// Gets or sets the Last-Modified header HTTP header.
252 public DateTime
? LastModified
254 get { return lastModified; }
255 set { lastModified = value; }
259 /// Gets or sets the Cache-Control: max-age HTTP header.
261 public TimeSpan
? MaxAge
263 get { return maxAge; }
264 set { maxAge = value; }
268 /// Gets or sets the Cache-Control: s-maxage HTTP header.
270 public TimeSpan
? ProxyMaxAge
272 get { return proxyMaxAge; }
273 set { proxyMaxAge = value; }
277 /// Gets or sets the Cache-Control must-revalidate or proxy-revalidate HTTP header.
279 public HttpCacheRevalidation Revalidation
281 get { return revalidation; }
282 set { revalidation = value; }
286 /// Configures ASP.Net's Cache policy based on properties set
288 /// <param name="policy">cache policy to set</param>
289 void ICachePolicyConfigurer
.Configure(HttpCachePolicy policy
)
291 policy
.SetAllowResponseInBrowserHistory(allowInHistory
);
292 policy
.SetCacheability(cacheability
);
293 policy
.SetOmitVaryStar(omitVaryStar
);
294 policy
.SetRevalidation(revalidation
);
295 policy
.SetSlidingExpiration(slidingExpiration
);
296 policy
.SetValidUntilExpires(validUntilExpires
);
300 policy
.SetExpires(DateTime
.Now
.AddSeconds(duration
));
303 #if DOTNET2SP1 || DOTNET35
304 if (varyByContentEncodings
!= null)
306 foreach (String header
in varyByContentEncodings
.Split(','))
308 policy
.VaryByContentEncodings
[header
.Trim()] = true;
313 if (varyByCustom
!= null)
315 policy
.SetVaryByCustom(varyByCustom
);
318 if (varyByHeaders
!= null)
320 foreach(String header
in varyByHeaders
.Split(','))
322 policy
.VaryByHeaders
[header
.Trim()] = true;
326 if (varyByParams
!= null)
328 foreach(String param
in varyByParams
.Split(','))
330 policy
.VaryByParams
[param
.Trim()] = true;
334 if (cacheExtension
!= null)
336 policy
.AppendCacheExtension(cacheExtension
);
339 if (setEtagFromFileDependencies
)
341 policy
.SetETagFromFileDependencies();
344 if (setLastModifiedFromFileDependencies
)
346 policy
.SetLastModifiedFromFileDependencies();
349 if (setNoServerCaching
)
351 policy
.SetNoServerCaching();
361 policy
.SetNoTransforms();
366 policy
.SetETag(etag
);
369 if (lastModified
!= null)
371 policy
.SetLastModified(lastModified
.Value
);
376 policy
.SetMaxAge(maxAge
.Value
);
379 if (proxyMaxAge
!= null)
381 policy
.SetProxyMaxAge(proxyMaxAge
.Value
);