コード例 #1
0
        public async Task Should_response_current_cache_if_there_is_error_but_StaleIfError_is_not_zero()
        {
            // Arrange
            _request.Headers.CacheControl =
                new CacheControlHeaderValue
            {
                MaxAge     = TimeSpan.FromSeconds(10),
                Extensions = { new NameValueHeaderValue(WebApiExtensions.__cacheControl_flatwhite_force_refresh, "1") }
            };

            var att = new Flatwhite.WebApi.OutputCacheAttribute
            {
                MaxAge = 10,
                IgnoreRevalidationRequest = true,
                StaleIfError = 2
            };

            _actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            var objCacheItem = new WebApiCacheItem
            {
                MaxAge = 10,
                Key    = CacheKey,
                StaleWhileRevalidate = 5,
                StoreId                   = _store.StoreId,
                StaleIfError              = 2,
                CreatedTime               = DateTime.UtcNow.AddSeconds(-5).AddMilliseconds(-1),
                Content                   = new byte[] { 0, 1, 2 },
                ResponseMediaType         = "application/json",
                ResponseCharSet           = "utf-8",
                IgnoreRevalidationRequest = true
            };

            _store.GetAsync(CacheKey).Returns(objCacheItem);

            // Action
            await att.OnActionExecutedAsync(_actionExecutedContext, CancellationToken.None);

            // Assert
            Assert.IsTrue(_actionExecutedContext.Response.IsSuccessStatusCode);
            await _store.DidNotReceive().SetAsync(Arg.Any <string>(), Arg.Any <object>(), Arg.Any <DateTimeOffset>());
        }
コード例 #2
0
        private async Task <bool> AttemptToResponseTheCacheWhenError(HttpActionExecutedContext actionExecutedContext, IAsyncCacheStore cacheStore, string storedKey)
        {
            if (actionExecutedContext.ActionContext.Response == null || !actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
            {
                var cacheItem = await cacheStore.GetAsync(storedKey).ConfigureAwait(false) as WebApiCacheItem;

                if (cacheItem != null && StaleIfError > 0)
                {
                    var builder  = actionExecutedContext.Request.GetConfiguration().GetFlatwhiteCacheConfiguration().ResponseBuilder;
                    var response = builder.GetResponse(actionExecutedContext.Request.Headers.CacheControl, cacheItem, actionExecutedContext.Request);

                    if (response != null)
                    {
                        //NOTE: Override error response
                        actionExecutedContext.Response = response;
                    }
                    return(true);
                }
            }
            return(false);
        }
コード例 #3
0
        /// <summary>
        /// Try to get the cache from etag and build the response if cache is available
        /// </summary>
        /// <param name="cacheControl"></param>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <HttpResponseMessage> HandleAsync(CacheControlHeaderValue cacheControl, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request.Headers.IfNoneMatch != null)
            {
                // Etag format: fw-StoreId-HashedKey-Checksum
                var requestEtags = request.Headers.IfNoneMatch.Where(t => t.Tag != null && t.Tag.StartsWith("\"fw-")).ToList();
                if (requestEtags.Count > 0)
                {
                    foreach (var etag in requestEtags)
                    {
                        var etagString    = etag.Tag.Trim('"');
                        var index         = etagString.IndexOf("-", 4, StringComparison.Ordinal);
                        var storeIdString = index > 0 ? etagString.Substring(3, index - 3) : "0";
                        index = etagString.LastIndexOf("-", StringComparison.Ordinal);

                        int storeId;
                        IAsyncCacheStore cacheStore = null;
                        if (int.TryParse(storeIdString, out storeId))
                        {
                            cacheStore = Global.CacheStoreProvider.GetAsyncCacheStore(storeId) ?? Global.CacheStoreProvider.GetAsyncCacheStore();
                        }

                        if (cacheStore != null && index > 0)
                        {
                            var hashedKey = etagString.Substring(0, index);
                            var checkSum  = etagString.Substring(index + 1);
                            var cacheItem = (await cacheStore.GetAsync(hashedKey)) as WebApiCacheItem;

                            if (cacheItem != null && cacheItem.Checksum == checkSum)
                            {
                                request.Properties[WebApiExtensions.__webApi_etag_matched] = true;
                            }
                            return(_builder.GetResponse(cacheControl, cacheItem, request));
                        }
                    }
                }
            }
            return(null);
        }