@@ -25,8 +25,6 @@ public class ResponseCachingMiddleware
25
25
private readonly IResponseCachingPolicyProvider _policyProvider ;
26
26
private readonly IResponseCache _cache ;
27
27
private readonly IResponseCachingKeyProvider _keyProvider ;
28
- private readonly Action < object > _onStartingCallback ;
29
- private readonly Func < object , Task > _onStartingCallbackAsync ;
30
28
31
29
public ResponseCachingMiddleware (
32
30
RequestDelegate next ,
@@ -67,8 +65,6 @@ public ResponseCachingMiddleware(
67
65
_policyProvider = policyProvider ;
68
66
_cache = cache ;
69
67
_keyProvider = keyProvider ;
70
- _onStartingCallback = state => OnResponseStarting ( ( ResponseCachingContext ) state ) ;
71
- _onStartingCallbackAsync = state => OnResponseStartingAsync ( ( ResponseCachingContext ) state ) ;
72
68
}
73
69
74
70
public async Task Invoke ( HttpContext httpContext )
@@ -218,10 +214,11 @@ internal async Task<bool> TryServeFromCacheAsync(ResponseCachingContext context)
218
214
return false ;
219
215
}
220
216
221
- internal void FinalizeCacheHeaders ( ResponseCachingContext context )
217
+ private bool FinalizeCacheHeadersShouldStoreVaryByEntry ( ResponseCachingContext context )
222
218
{
223
219
if ( _policyProvider . IsResponseCacheable ( context ) )
224
220
{
221
+ var storeVaryByEntry = false ;
225
222
context . ShouldCacheResponse = true ;
226
223
227
224
// Create the cache entry now
@@ -261,7 +258,7 @@ internal void FinalizeCacheHeaders(ResponseCachingContext context)
261
258
262
259
// Always overwrite the CachedVaryByRules to update the expiry information
263
260
_logger . LogVaryByRulesUpdated ( normalizedVaryHeaders , normalizedVaryQueryKeys ) ;
264
- _cache . Set ( context . BaseKey , context . CachedVaryByRules , context . CachedResponseValidFor ) ;
261
+ storeVaryByEntry = true ;
265
262
266
263
context . StorageVaryKey = _keyProvider . CreateStorageVaryByKey ( context ) ;
267
264
}
@@ -289,89 +286,31 @@ internal void FinalizeCacheHeaders(ResponseCachingContext context)
289
286
context . CachedResponse . Headers . Add ( header ) ;
290
287
}
291
288
}
289
+
290
+ return storeVaryByEntry ;
292
291
}
293
292
else
294
293
{
295
294
context . ResponseCachingStream . DisableBuffering ( ) ;
295
+ return false ;
296
296
}
297
297
}
298
298
299
- internal async Task FinalizeCacheHeadersAsync ( ResponseCachingContext context )
299
+ internal void FinalizeCacheHeaders ( ResponseCachingContext context )
300
300
{
301
- if ( _policyProvider . IsResponseCacheable ( context ) )
301
+ if ( FinalizeCacheHeadersShouldStoreVaryByEntry ( context ) )
302
302
{
303
- context . ShouldCacheResponse = true ;
304
-
305
- // Create the cache entry now
306
- var response = context . HttpContext . Response ;
307
- var varyHeaders = new StringValues ( response . Headers . GetCommaSeparatedValues ( HeaderNames . Vary ) ) ;
308
- var varyQueryKeys = new StringValues ( context . HttpContext . Features . Get < IResponseCachingFeature > ( ) ? . VaryByQueryKeys ) ;
309
- context . CachedResponseValidFor = context . ResponseSharedMaxAge ??
310
- context . ResponseMaxAge ??
311
- ( context . ResponseExpires - context . ResponseTime . Value ) ??
312
- DefaultExpirationTimeSpan ;
313
-
314
- // Generate a base key if none exist
315
- if ( string . IsNullOrEmpty ( context . BaseKey ) )
316
- {
317
- context . BaseKey = _keyProvider . CreateBaseKey ( context ) ;
318
- }
319
-
320
- // Check if any vary rules exist
321
- if ( ! StringValues . IsNullOrEmpty ( varyHeaders ) || ! StringValues . IsNullOrEmpty ( varyQueryKeys ) )
322
- {
323
- // Normalize order and casing of vary by rules
324
- var normalizedVaryHeaders = GetOrderCasingNormalizedStringValues ( varyHeaders ) ;
325
- var normalizedVaryQueryKeys = GetOrderCasingNormalizedStringValues ( varyQueryKeys ) ;
326
-
327
- // Update vary rules if they are different
328
- if ( context . CachedVaryByRules == null ||
329
- ! StringValues . Equals ( context . CachedVaryByRules . QueryKeys , normalizedVaryQueryKeys ) ||
330
- ! StringValues . Equals ( context . CachedVaryByRules . Headers , normalizedVaryHeaders ) )
331
- {
332
- context . CachedVaryByRules = new CachedVaryByRules
333
- {
334
- VaryByKeyPrefix = FastGuid . NewGuid ( ) . IdString ,
335
- Headers = normalizedVaryHeaders ,
336
- QueryKeys = normalizedVaryQueryKeys
337
- } ;
338
- }
339
-
340
- // Always overwrite the CachedVaryByRules to update the expiry information
341
- _logger . LogVaryByRulesUpdated ( normalizedVaryHeaders , normalizedVaryQueryKeys ) ;
342
- await _cache . SetAsync ( context . BaseKey , context . CachedVaryByRules , context . CachedResponseValidFor ) ;
343
-
344
- context . StorageVaryKey = _keyProvider . CreateStorageVaryByKey ( context ) ;
345
- }
346
-
347
- // Ensure date header is set
348
- if ( ! context . ResponseDate . HasValue )
349
- {
350
- context . ResponseDate = context . ResponseTime . Value ;
351
- // Setting the date on the raw response headers.
352
- context . HttpContext . Response . Headers [ HeaderNames . Date ] = HeaderUtilities . FormatDate ( context . ResponseDate . Value ) ;
353
- }
354
-
355
- // Store the response on the state
356
- context . CachedResponse = new CachedResponse
357
- {
358
- Created = context . ResponseDate . Value ,
359
- StatusCode = context . HttpContext . Response . StatusCode ,
360
- Headers = new HeaderDictionary ( )
361
- } ;
362
-
363
- foreach ( var header in context . HttpContext . Response . Headers )
364
- {
365
- if ( ! string . Equals ( header . Key , HeaderNames . Age , StringComparison . OrdinalIgnoreCase ) )
366
- {
367
- context . CachedResponse . Headers . Add ( header ) ;
368
- }
369
- }
303
+ _cache . Set ( context . BaseKey , context . CachedVaryByRules , context . CachedResponseValidFor ) ;
370
304
}
371
- else
305
+ }
306
+
307
+ internal Task FinalizeCacheHeadersAsync ( ResponseCachingContext context )
308
+ {
309
+ if ( FinalizeCacheHeadersShouldStoreVaryByEntry ( context ) )
372
310
{
373
- context . ResponseCachingStream . DisableBuffering ( ) ;
311
+ return _cache . SetAsync ( context . BaseKey , context . CachedVaryByRules , context . CachedResponseValidFor ) ;
374
312
}
313
+ return TaskCache . CompletedTask ;
375
314
}
376
315
377
316
internal async Task FinalizeCacheBodyAsync ( ResponseCachingContext context )
@@ -404,30 +343,33 @@ internal async Task FinalizeCacheBodyAsync(ResponseCachingContext context)
404
343
}
405
344
}
406
345
407
- internal void OnResponseStarting ( ResponseCachingContext context )
346
+ private bool OnResponseStartingShouldFinalizeHeaders ( ResponseCachingContext context )
408
347
{
409
348
if ( ! context . ResponseStarted )
410
349
{
411
350
context . ResponseStarted = true ;
412
351
context . ResponseTime = _options . SystemClock . UtcNow ;
413
352
353
+ return true ;
354
+ }
355
+ return false ;
356
+ }
357
+
358
+ internal void OnResponseStarting ( ResponseCachingContext context )
359
+ {
360
+ if ( OnResponseStartingShouldFinalizeHeaders ( context ) )
361
+ {
414
362
FinalizeCacheHeaders ( context ) ;
415
363
}
416
364
}
417
365
418
366
internal Task OnResponseStartingAsync ( ResponseCachingContext context )
419
367
{
420
- if ( ! context . ResponseStarted )
368
+ if ( OnResponseStartingShouldFinalizeHeaders ( context ) )
421
369
{
422
- context . ResponseStarted = true ;
423
- context . ResponseTime = _options . SystemClock . UtcNow ;
424
-
425
370
return FinalizeCacheHeadersAsync ( context ) ;
426
371
}
427
- else
428
- {
429
- return TaskCache . CompletedTask ;
430
- }
372
+ return TaskCache . CompletedTask ;
431
373
}
432
374
433
375
internal static void AddResponseCachingFeature ( HttpContext context )
@@ -443,7 +385,12 @@ internal void ShimResponseStream(ResponseCachingContext context)
443
385
{
444
386
// Shim response stream
445
387
context . OriginalResponseStream = context . HttpContext . Response . Body ;
446
- context . ResponseCachingStream = new ResponseCachingStream ( context . OriginalResponseStream , _options . MaximumBodySize , StreamUtilities . BodySegmentSize , ( ) => OnResponseStarting ( context ) , async ( ) => await OnResponseStartingAsync ( context ) ) ;
388
+ context . ResponseCachingStream = new ResponseCachingStream (
389
+ context . OriginalResponseStream ,
390
+ _options . MaximumBodySize ,
391
+ StreamUtilities . BodySegmentSize ,
392
+ ( ) => OnResponseStarting ( context ) ,
393
+ async ( ) => await OnResponseStartingAsync ( context ) ) ;
447
394
context . HttpContext . Response . Body = context . ResponseCachingStream ;
448
395
449
396
// Shim IHttpSendFileFeature
0 commit comments