@@ -14,6 +14,26 @@ namespace Microsoft.Extensions.Caching.InMemory
14
14
/// </summary>
15
15
public class InMemoryCacheHandler : DelegatingHandler
16
16
{
17
+ #if NET5_0_OR_GREATER
18
+ /// <summary>
19
+ /// The key to use to store the UseCache value in the HttpRequestMessage.Options dictionary.
20
+ /// This key is used to determine if the cache should be checked for the request.
21
+ /// If the key is not present, the cache will be checked.
22
+ /// If the key is present and the value is false, the cache will not be checked.
23
+ /// If the key is present and the value is true, the cache will be checked.
24
+ /// </summary>
25
+ public readonly static HttpRequestOptionsKey < bool > UseCache = new ( "UseCache" ) ;
26
+ #else
27
+ /// <summary>
28
+ /// The key to use to store the UseCache value in the HttpRequestMessage.Properties dictionary.
29
+ /// This key is used to determine if the cache should be checked for the request.
30
+ /// If the key is not present, the cache will be checked.
31
+ /// If the key is present and the value is false, the cache will not be checked.
32
+ /// If the key is present and the value is true, the cache will be checked.
33
+ /// </summary>
34
+ public const string UseCache = "UseCache" ;
35
+ #endif
36
+
17
37
private static HashSet < HttpMethod > CachedHttpMethods = new HashSet < HttpMethod >
18
38
{
19
39
HttpMethod . Get ,
@@ -104,6 +124,37 @@ public void InvalidateCache(Uri uri, HttpMethod httpMethod = null)
104
124
}
105
125
}
106
126
127
+ /// <summary>
128
+ /// Determines if the cache should be checked for the request.
129
+ /// </summary>
130
+ /// <param name="request"></param>
131
+ /// <returns>A bool representing if the cache should be cached or not</returns>
132
+ private bool ShouldTheCacheBeChecked ( HttpRequestMessage request )
133
+ {
134
+ #if NET5_0_OR_GREATER
135
+ return request . Options . TryGetValue ( UseCache , out bool useCache ) == false || useCache == true ;
136
+ #else
137
+ return request . Properties . TryGetValue ( UseCache , out var useCache ) == false || ( bool ) useCache == true ;
138
+ #endif
139
+ }
140
+
141
+ /// <summary>
142
+ /// Determines if the response should be cached.
143
+ /// </summary>
144
+ /// <param name="response"></param>
145
+ /// <returns>A bool representing if the response should be cached or not</returns>
146
+ private bool ShouldCacheResponse ( HttpResponseMessage response )
147
+ {
148
+ if ( response . Headers . CacheControl is not null )
149
+ {
150
+ return response . Headers . CacheControl . NoStore == false
151
+ && response . Headers . CacheControl . NoCache == false
152
+ && response . StatusCode != HttpStatusCode . NotModified ;
153
+ }
154
+
155
+ return response . StatusCode != HttpStatusCode . NotModified ;
156
+ }
157
+
107
158
/// <summary>
108
159
/// Tries to get the value from the cache, and only calls the delegating handler on cache misses.
109
160
/// </summary>
@@ -114,7 +165,9 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
114
165
115
166
// Gets the data from cache, and returns the data if it's a cache hit
116
167
var isCachedHttpMethod = CachedHttpMethods . Contains ( request . Method ) ;
117
- if ( isCachedHttpMethod )
168
+ // Check if the cache should be checked
169
+ var shouldCheckCache = this . ShouldTheCacheBeChecked ( request ) ;
170
+ if ( shouldCheckCache && isCachedHttpMethod )
118
171
{
119
172
key = this . CacheKeysProvider . GetKey ( request ) ;
120
173
@@ -134,7 +187,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
134
187
135
188
this . StatsProvider . ReportCacheMiss ( response . StatusCode ) ;
136
189
137
- if ( TimeSpan . Zero != absoluteExpirationRelativeToNow )
190
+ if ( this . ShouldCacheResponse ( response ) && TimeSpan . Zero != absoluteExpirationRelativeToNow )
138
191
{
139
192
var entry = await response . ToCacheEntryAsync ( ) ;
140
193
await this . responseCache . TrySetAsync ( key , entry , absoluteExpirationRelativeToNow ) ;
@@ -153,7 +206,9 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella
153
206
154
207
// Gets the data from cache, and returns the data if it's a cache hit
155
208
var isCachedHttpMethod = CachedHttpMethods . Contains ( request . Method ) ;
156
- if ( isCachedHttpMethod )
209
+ // Check if the cache should be checked
210
+ var shouldCheckCache = this . ShouldTheCacheBeChecked ( request ) ;
211
+ if ( shouldCheckCache && isCachedHttpMethod )
157
212
{
158
213
key = this . CacheKeysProvider . GetKey ( request ) ;
159
214
@@ -172,7 +227,7 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella
172
227
173
228
this . StatsProvider . ReportCacheMiss ( response . StatusCode ) ;
174
229
175
- if ( TimeSpan . Zero != absoluteExpirationRelativeToNow )
230
+ if ( this . ShouldCacheResponse ( response ) && TimeSpan . Zero != absoluteExpirationRelativeToNow )
176
231
{
177
232
var cacheData = response . ToCacheEntry ( ) ;
178
233
this . responseCache . TrySetCacheData ( key , cacheData , absoluteExpirationRelativeToNow ) ;
0 commit comments