/// <summary> /// Create required components to use Flatwhite cache for WebApi /// </summary> /// <param name="config"></param> /// <param name="flatwhiteConfig"></param> public static HttpConfiguration UseFlatwhiteCache(this HttpConfiguration config, FlatwhiteWebApiConfiguration flatwhiteConfig = null) { _fwConfig = flatwhiteConfig ?? new FlatwhiteWebApiConfiguration(); Global.CacheStrategyProvider = new WebApiCacheStrategyProvider(); Global.BackgroundTaskManager = new RegisteredTasks(); var allHandlers = config.DependencyResolver .GetServices(typeof(ICachControlHeaderHandler)) .OfType<ICachControlHeaderHandler>() .ToList(); if (allHandlers.All(h => h.GetType() != typeof(EtagHeaderHandler))) { var cacheResponseBuilder = config.DependencyResolver.GetService(typeof(ICacheResponseBuilder)) as ICacheResponseBuilder ?? new CacheResponseBuilder(); var etagHeaderHandler = new EtagHeaderHandler(cacheResponseBuilder); allHandlers.Add(etagHeaderHandler); } var handlerProvider = config.DependencyResolver.GetService(typeof(ICachControlHeaderHandlerProvider)) as ICachControlHeaderHandlerProvider ?? new CachControlHeaderHandlerProvider(); allHandlers.ForEach(h => handlerProvider.Register(h)); config.MessageHandlers.Add(new CacheMessageHandler(handlerProvider)); if (_fwConfig.EnableStatusController) { config.Routes.MapHttpRoute( name: "_FlatwhiteStatus", routeTemplate: "_flatwhite/{action}/{id}", defaults: new {id = RouteParameter.Optional, controller = "FlatwhiteStatus"} ); } return config; }
/// <summary> /// Create required components to use Flatwhite cache for WebApi /// </summary> /// <param name="app"></param> /// <param name="config"></param> public static IAppBuilder UseFlatwhiteCache(this IAppBuilder app, HttpConfiguration config) { Global.CacheStrategyProvider = new WebApiCacheStrategyProvider(); _dependencyResolverActivator = new WebApiDependencyResolverActivator(() => config.DependencyResolver); var allHandlers = config.DependencyResolver .GetServices(typeof (ICachControlHeaderHandler)) .OfType<ICachControlHeaderHandler>() .ToList(); if (allHandlers.All(h => h.GetType() != typeof (EtagHeaderHandler))) { var cacheResponseBuilder = config.DependencyResolver.GetService(typeof(ICacheResponseBuilder)) as ICacheResponseBuilder ?? new CacheResponseBuilder(); var etagHeaderHandler = new EtagHeaderHandler(cacheResponseBuilder); allHandlers.Add(etagHeaderHandler); } var handlerProvider = config.DependencyResolver.GetService(typeof(ICachControlHeaderHandlerProvider)) as ICachControlHeaderHandlerProvider ?? new CachControlHeaderHandlerProvider(); allHandlers.ForEach(h => handlerProvider.Register(h)); config.MessageHandlers.Add(new CacheMessageHandler(handlerProvider)); return app; }
public async Task Should_return_null_if_no_etag_in_request() { // Arrange var cacheControl = new CacheControlHeaderValue(); var request = new HttpRequestMessage { Method = new HttpMethod("GET"), RequestUri = new Uri("http://localhost") }; var builder = Substitute.For<ICacheResponseBuilder>(); var handler = new EtagHeaderHandler(builder); // Action var response = await handler.HandleAsync(cacheControl, request, CancellationToken.None); Assert.IsNull(response); }
public async Task Should_return_null_if_cache_item_not_found() { // Arrange var cacheControl = new CacheControlHeaderValue(); var request = new HttpRequestMessage { Method = new HttpMethod("GET"), RequestUri = new Uri("http://localhost") }; request.Headers.Add("If-None-Match", "\"fw-1000-HASHEDKEY-CHECKSUM\""); var builder = Substitute.For<ICacheResponseBuilder>(); var handler = new EtagHeaderHandler(builder); // Action var response = await handler.HandleAsync(cacheControl, request, CancellationToken.None); Assert.IsNull(response); }
public async Task Should_return_new_etag_if_cache_item_found_but_doesnt_match_checksum(string cacheChecksum, HttpStatusCode resultCode) { // Arrange var cacheControl = new CacheControlHeaderValue { MaxStale = true, MaxStaleLimit = TimeSpan.FromSeconds(15), MinFresh = TimeSpan.FromSeconds(20) }; var oldCacheItem = new WebApiCacheItem { CreatedTime = DateTime.UtcNow.AddSeconds(-11), MaxAge = 10, StaleWhileRevalidate = 5, IgnoreRevalidationRequest = true, ResponseCharSet = "UTF8", ResponseMediaType = "text/json", Content = new byte[0], Key = "fw-0-HASHEDKEY", Checksum = cacheChecksum }; var request = new HttpRequestMessage { Method = new HttpMethod("GET"), RequestUri = new Uri("http://localhost") }; request.Headers.Add("If-None-Match", "\"fw-0-HASHEDKEY-OLDCHECKSUM\""); var builder = new CacheResponseBuilder(); var handler = new EtagHeaderHandler(builder); await Global.CacheStoreProvider.GetAsyncCacheStore().SetAsync("fw-0-HASHEDKEY", oldCacheItem, DateTimeOffset.Now.AddDays(1)).ConfigureAwait(false); // Action Global.Cache.PhoenixFireCage["fw-0-HASHEDKEY"] = new WebApiPhoenix(NSubstitute.Substitute.For<_IInvocation>(), new CacheInfo(), oldCacheItem, request); var response = await handler.HandleAsync(cacheControl, request, CancellationToken.None).ConfigureAwait(false); Assert.AreEqual(resultCode, response.StatusCode); if (resultCode == HttpStatusCode.OK) { Assert.AreEqual($"\"fw-0-HASHEDKEY-{cacheChecksum}\"", response.Headers.ETag.Tag); } else { Assert.IsNull(response.Headers.ETag); } }