private async Task ExecuteRequestAndCache(HttpContext context, string key, CacheAttribute attribute) { var originalBodyStream = context.Response.Body; using (var responseBody = new MemoryStream()) { context.Response.Body = responseBody; await _next(context); if (IsCachableResponse(context.Response)) { context.Response.Body.Seek(0, SeekOrigin.Begin); var buffer = new byte[Convert.ToInt32(context.Response.Body.Length)]; context.Response.Body.Read(buffer, 0, buffer.Length); var options = GetOptions(attribute); _cache.Set(key, buffer, options); _cache.Set(GetContentTypeKey(key), context.Response.ContentType, options); context.Response.Body.Seek(0, SeekOrigin.Begin); await responseBody.CopyToAsync(originalBodyStream); } } }
private bool IsClearCacheAction(HttpContext context, CacheAttribute cacheAttr) { return((new[] { "PATCH", "POST", "PUT" }.Any(method => method.Equals(context.Request.Method, StringComparison.CurrentCultureIgnoreCase)) && !cacheAttr.AsGet) || context.Request.Method.Equals("DELETE", StringComparison.CurrentCultureIgnoreCase)); }
private async Task ExecuteRequest(HttpContext context, string key, CacheAttribute attribute) { if (!IsClearCacheAction(context, attribute)) { await ExecuteRequestAndCache(context, key, attribute); } else { await _next(context); } }
private async Task InvokeCached(HttpContext context, CacheAttribute attribute) { var key = GetKey(context); if (IsClearCacheAction(context, attribute)) { _cache.Remove(key); _cache.Remove(GetContentTypeKey(key)); } _cache.TryGetValue(key, out object value); if (value == null) { await ExecuteRequest(context, key, attribute); } else { _cache.TryGetValue(GetContentTypeKey(key), out string contentType); await SetResponseFromCache(context, (byte[])value, contentType); } }
private MemoryCacheEntryOptions GetOptions(CacheAttribute attribute) { return(new MemoryCacheEntryOptions { AbsoluteExpiration = attribute.AbsoluteExpiration > DateTime.MinValue ? attribute.AbsoluteExpiration : (DateTimeOffset?)null, AbsoluteExpirationRelativeToNow = attribute.AbsoluteExpirationRelativeToNow > int.MinValue ? TimeSpan.FromSeconds(attribute.AbsoluteExpirationRelativeToNow) : (TimeSpan?)null, Priority = attribute.Priority, SlidingExpiration = attribute.SlidingExpiration > int.MinValue ? TimeSpan.FromSeconds(attribute.SlidingExpiration) : (TimeSpan?)null, Size = attribute.Size > long.MinValue ? attribute.Size : (long?)null }); }