public static void TestCacheInvalidationForPost(string method) { const string relatedUrl = "http://api/SomeLocationUrl/"; // setup var locationUrl = new Uri(relatedUrl); var mocks = new MockRepository(); var request = new HttpRequestMessage(new HttpMethod(method), TestUrl); string routePattern = "http://myserver/api/stuffs/*"; var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var cachingHandler = new CachingHandler(new HttpConfiguration(), entityTagStore) { }; var entityTagKey = new CacheKey(TestUrl, new string[0], routePattern); var response = new HttpResponseMessage(); response.Headers.Location = locationUrl; var invalidateCacheForPost = cachingHandler.PostInvalidationRule(entityTagKey, request, response); if(method == "POST") { entityTagStore.Expect(x => x.RemoveAllByRoutePattern("/SomeLocationUrl/")).Return(1); } mocks.ReplayAll(); // run invalidateCacheForPost(); // verify mocks.VerifyAll(); }
public static void Configuration(IAppBuilder appBuilder) { // Configure Web API for self-host. var config = new HttpConfiguration() { DependencyResolver = new UnityDependencyResolver(UnityContainer) }; //Adding CacheCow var objCacheCow = new CacheCow.Server.CachingHandler(config, ""); UnityContainer.RegisterInstance <ICachingHandler>(objCacheCow); config.MessageHandlers.Add(objCacheCow); config.MapHttpAttributeRoutes(new CustomDirectRouteProvider()); config.EnableCors(); config.EnsureInitialized(); appBuilder.Use <HmacAuthenticationMiddleware>(new HmacAuthenticationOptions(UnityContainer)); appBuilder.UseWebApi(config); //Route Debugging //var routes = config.Routes // .Select(route => (IEnumerable)route) // .Single(route => route != null) // .Cast<HttpRoute>(); //var manifest = routes // .Select(route => route.RouteTemplate) // .ToList(); }
public static void GetMatchNonMatchTest( string headerName, string[] values, bool existsInStore, bool expectReturnNull, HttpStatusCode expectedStatus = HttpStatusCode.Unused) { // setup var mocks = new MockRepository(); var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var entityTagHandler = new CachingHandler(entityTagStore); var request = new HttpRequestMessage(HttpMethod.Get, TestUrl); request.Headers.Add(headerName, values); TimedEntityTagHeaderValue entityTagHeaderValue = new TimedEntityTagHeaderValue("\"12345678\""); if(values.Length>0) // if entityTagStore.Expect(x => x.TryGetValue(Arg<CacheKey>.Matches(etg => etg.ResourceUri == entityTagHandler.UriTrimmer(new Uri(TestUrl))), out Arg<TimedEntityTagHeaderValue>.Out(entityTagHeaderValue).Dummy)).Return(existsInStore); mocks.ReplayAll(); // run var matchNoneMatch = entityTagHandler.GetIfMatchNoneMatch(); // verify Task<HttpResponseMessage> resultTask = matchNoneMatch(request); Assert.That(expectReturnNull ^ resultTask != null, "result was not as expected"); if(resultTask!=null && expectedStatus != HttpStatusCode.Unused) { Assert.AreEqual(expectedStatus, resultTask.Result.StatusCode, "Status code"); } mocks.VerifyAll(); }
public void GivenIHaveAnAPIRunningCacheCowServerAndUsingStorage(string storage) { IEntityTagStore store; var configuration = new HttpConfiguration(); switch (storage) { case "InMemory": store = new InMemoryEntityTagStore(); break; default: throw new ArgumentException("Store unknown: " + storage); } configuration.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); var inMemoryServer = new InMemoryServer(configuration); var cachingHandler = new CachingHandler(configuration, store, "Accept") { InnerHandler = inMemoryServer }; var client = new HttpClient(cachingHandler); ScenarioContext.Current[Keys.Client] = client; ScenarioContext.Current[Keys.CacheHandler] = cachingHandler; }
public static void AddCaching(string method, bool existsInStore, bool addVaryHeader, bool addLastModifiedHeader, bool alreadyHasLastModified, string[] varyByHeader) { // setup var mocks = new MockRepository(); var request = new HttpRequestMessage(new HttpMethod(method), TestUrl); request.Headers.Add(HttpHeaderNames.Accept, "text/xml"); request.Headers.Add(HttpHeaderNames.AcceptLanguage, "en-GB"); var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var entityTagHeaderValue = new TimedEntityTagHeaderValue("\"12345678\""); var cachingHandler = new CachingHandler(entityTagStore, varyByHeader) { AddLastModifiedHeader = addLastModifiedHeader, AddVaryHeader = addVaryHeader, ETagValueGenerator = (x,y) => entityTagHeaderValue }; var entityTagKey = new CacheKey(TestUrl, new[] {"text/xml", "en-GB"}, TestUrl + "/*"); entityTagStore.Expect(x => x.TryGetValue(Arg<CacheKey>.Matches(etg => etg.ResourceUri == TestUrl), out Arg<TimedEntityTagHeaderValue>.Out(entityTagHeaderValue).Dummy)).Return(existsInStore); if (!existsInStore) { entityTagStore.Expect( x => x.AddOrUpdate(Arg<CacheKey>.Matches(etk => etk == entityTagKey), Arg<TimedEntityTagHeaderValue>.Matches(ethv => ethv.Tag == entityTagHeaderValue.Tag))); } var response = new HttpResponseMessage(); response.Content = new ByteArrayContent(new byte[0]); if (alreadyHasLastModified) response.Content.Headers.Add(HttpHeaderNames.LastModified, DateTimeOffset.Now.ToString("r")); var cachingContinuation = cachingHandler.AddCaching(entityTagKey, request, response, request.Headers); mocks.ReplayAll(); // run cachingContinuation(); // verify // test kast modified only if it is GET and PUT if (addLastModifiedHeader && method.IsIn("PUT", "GET")) { Assert.That(response.Content.Headers.Any(x => x.Key == HttpHeaderNames.LastModified), "LastModified does not exist"); } if (!addLastModifiedHeader && !alreadyHasLastModified) { Assert.That(!response.Content.Headers.Any(x => x.Key == HttpHeaderNames.LastModified), "LastModified exists"); } mocks.VerifyAll(); }
public static void TestGetReturnsNullIfVerbNotGet() { // setup var request = new HttpRequestMessage(HttpMethod.Put, TestUrl); var entityTagHandler = new CachingHandler(new HttpConfiguration()); var getRule = entityTagHandler.GetIfMatchNoneMatch(); // run var task = getRule(request); // verify Assert.IsNull(task); }
void init(HttpConfiguration config) { var cacheCowCacheHandler = new CachingHandler(config); config.MessageHandlers.Add(cacheCowCacheHandler); //客户端 HttpClient client = new HttpClient(new WebRequestHandler() { CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default) }); //var httpResponseMessage = await client.GetAsync("http://superpoopy"); }
public static void TestGetReturnsBadRequestIfBothIfMatchAndIfNoneMatchExist() { // setup var request = new HttpRequestMessage(HttpMethod.Get, TestUrl); request.Headers.Add(HttpHeaderNames.IfMatch, "\"123\""); request.Headers.Add(HttpHeaderNames.IfNoneMatch, "\"123\""); var entityTagHandler = new CachingHandler(new HttpConfiguration()); var getRule = entityTagHandler.GetIfMatchNoneMatch(); // run var task = getRule(request); var httpResponseMessage = task.Result; // verify Assert.AreEqual(HttpStatusCode.BadRequest, httpResponseMessage.StatusCode); }
public static void RegisterCacheCow(HttpConfiguration config) { //var connString = System.Configuration.ConfigurationManager.ConnectionStrings["eLearningConnection"].ConnectionString; //var eTagStore = new CacheCow.Server.EntityTagStore.SqlServer.SqlServerEntityTagStore(connString); //var cacheCowCacheHandler = new CacheCow.Server.CachingHandler(eTagStore); //cacheCowCacheHandler.AddLastModifiedHeader = false; //config.MessageHandlers.Add(cacheCowCacheHandler); var cacheCowCacheHandler = new CachingHandler(config); config.MessageHandlers.Add(cacheCowCacheHandler); //config.MessageHandlers.Add( // new CachingHandler(new SqlServerEntityTagStore()) // { // CacheKeyGenerator = CacheCowHelper.GenerateCacheKey, // LinkedRoutePatternProvider = CacheCowHelper.GetLinkedRoutes // } //); }
public static void GetModifiedNotModifiedTest( string headerName, bool resourceHasChanged, bool expectReturnNull, HttpStatusCode expectedStatus = HttpStatusCode.Unused) { // setup var mocks = new MockRepository(); var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var entityTagHandler = new CachingHandler(entityTagStore); var request = new HttpRequestMessage(HttpMethod.Get, TestUrl); DateTimeOffset lastChanged = DateTimeOffset.Now.Subtract(TimeSpan.FromDays(7)); DateTimeOffset lastModifiedInQuestion = resourceHasChanged ? lastChanged.Subtract(TimeSpan.FromDays(1)) : lastChanged.Add(TimeSpan.FromDays(1)); request.Headers.Add(headerName, lastModifiedInQuestion.ToString("r")); var entityTagHeaderValue = new TimedEntityTagHeaderValue("\"12345678\"") {LastModified = lastChanged}; entityTagStore.Expect(x => x.TryGetValue(Arg<CacheKey>.Matches(etg => etg.ResourceUri == entityTagHandler.UriTrimmer(new Uri(TestUrl))), out Arg<TimedEntityTagHeaderValue>.Out(entityTagHeaderValue).Dummy)).Return(true); mocks.ReplayAll(); // run var modifiedUnmodifiedSince = entityTagHandler.GetIfModifiedUnmodifiedSince(); var task = modifiedUnmodifiedSince(request); HttpResponseMessage response = task == null ? null : task.Result; // verify Assert.That(expectReturnNull ^ task != null, "result was not as expected"); if (task != null && expectedStatus != HttpStatusCode.Unused) { Assert.AreEqual(expectedStatus, response.StatusCode, "Status code"); } mocks.VerifyAll(); }
static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "PricingApi", routeTemplate: "api/{controller}/{id}", defaults: new { controller = "Test", id = RouteParameter.Optional }); config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; config.Formatters.XmlFormatter.UseXmlSerializer = true; var cachingHandler = new CachingHandler(new HttpConfiguration(), "Accept", "Accept-Encoding"); cachingHandler.CacheControlHeaderProvider = new AttributeBasedCacheControlPolicy(new CacheControlHeaderValue() { NoCache = true, Private = true, NoStore = true }).GetCacheControl; // turn caching off unless an attribute is used cachingHandler.CacheRefreshPolicyProvider = new AttributeBasedCacheRefreshPolicy(TimeSpan.FromMinutes(15)).GetCacheRefreshPolicy; config.MessageHandlers.Add(cachingHandler); }
public void Configuration(IAppBuilder app) { var cachingHandler = new CachingHandler(new HttpConfiguration(), new InMemoryEntityTagStore(), "Accept"); cachingHandler.CacheControlHeaderProvider = (message, configuration) => new CacheControlHeaderValue() { //NoCache = true, //MaxAge = TimeSpan.FromSeconds(100) }; var config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); app.UseWebApi(config, (q,s) => true); //app.UseHttpMessageHandler(new MyClass()); //app.UseHttpMessageHandler(new MyClass2()); //app.UseNancy(); app.UseHttpMessageHandler(new OwinHandlerBridge(cachingHandler), (q,s) => false); }
public static void TestCacheInvalidation(string method) { // setup var mocks = new MockRepository(); var request = new HttpRequestMessage(new HttpMethod(method), TestUrl); string routePattern = "http://myserver/api/stuffs/*"; var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var cachingHandler = new CachingHandler(new HttpConfiguration(), entityTagStore) { }; var entityTagKey = new CacheKey(TestUrl, new string[0], routePattern); var response = new HttpResponseMessage(); var invalidateCache = cachingHandler.InvalidateCache(entityTagKey, request, response); entityTagStore.Expect(x => x.RemoveResource("/api/stuff/")).Return(1); mocks.ReplayAll(); // run invalidateCache(); // verify mocks.VerifyAll(); }
public static void TestGetReturnsBadRequestIfBothIfModifiedAndIfUnmodifiedExist() { // setup var request = new HttpRequestMessage(HttpMethod.Get, TestUrl); request.Headers.Add(HttpHeaderNames.IfModifiedSince, DateTimeOffset.Now.ToString("r")); request.Headers.Add(HttpHeaderNames.IfUnmodifiedSince, DateTimeOffset.Now.ToString("r")); var entityTagHandler = new CachingHandler(); var getRule = entityTagHandler.GetIfModifiedUnmodifiedSince(); // run var task = getRule(request); var httpResponseMessage = task.Result; // verify Assert.AreEqual(HttpStatusCode.BadRequest, httpResponseMessage.StatusCode); }
public static void TestPutIfUnmodifiedReturnsNullIfVerbNotPut() { // setup var request = new HttpRequestMessage(HttpMethod.Get, TestUrl); var entityTagHandler = new CachingHandler(); var getRule = entityTagHandler.PutIfUnmodifiedSince(); // run var task = getRule(request); // verify Assert.IsNull(task); }
public static void Register(HttpConfiguration config) { //var container = new UnityContainer(); //container.RegisterType<IDbContext, RCDB>(new HierarchicalLifetimeManager()); //container.LoadConfiguration(); //config.DependencyResolver = new UnityResolver(container); config.DependencyResolver = IoC.IocContainer.UnityResolver; config.Routes.MapHttpRoute( name: "Restaurants", routeTemplate: "api/rc/restaurants/{restaurantid}", defaults: new { controller = "restaurants", restaurantid = RouteParameter.Optional } //,constraints: new { id = @"\d+" }//one or more digits ); config.Routes.MapHttpRoute( name: "Reviews", routeTemplate: "api/rc/restaurants/{restaurantid}/reviews/{id}", defaults: new { controller = "reviews", id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "Orders", routeTemplate: "api/client/orders/{orderid}", defaults: new { controller = "orders", orderid = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "OrdersItems", routeTemplate: "api/client/orders/{orderid}/items/{id}", defaults: new { controller = "orderitems", id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "OrderSummary", routeTemplate: "api/client/orders/{orderid}/summary", defaults: new { controller = "ordersummary"} ); //config.Routes.MapHttpRoute( // name: "Products", // routeTemplate: "api/products/{id}", // defaults: new { controller = "products", id = RouteParameter.Optional } //); config.Routes.MapHttpRoute( name: "Products", routeTemplate: "api/products/{id}/{action}/{entityid}", defaults: new { controller = "products", id = RouteParameter.Optional, entityid = RouteParameter.Optional, action = "DefaultAction" } ); //config.Routes.MapHttpRoute( // name: "Products", // routeTemplate: "api/products/{id}", // defaults: new // { // controller = "productsv2", // id = RouteParameter.Optional // } //); //using routing to version with URL /* config.Routes.MapHttpRoute( name: "Products2", routeTemplate: "api/v2/products/{id}", defaults: new { controller = "productsv2", id = RouteParameter.Optional } ); */ //config.Routes.MapHttpRoute( // name: "DefaultApi", // routeTemplate: "api/{controller}/{id}", // defaults: new { id = RouteParameter.Optional } //); //VP1 -- makes JSON the default webApi response type //config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); //VP2 //var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml"); //config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType); //VP3 //var xmlFormatter = config.Formatters.OfType<XmlMediaTypeFormatter>().FirstOrDefault(); //config.Formatters.Remove(xmlFormatter); //config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); //config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml")); //config.Formatters.JsonFormatter.MediaTypeMappings.Add(new RequestHeaderMapping("Accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, "application/json")); //GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new RequestHeaderMapping("Accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, "application/json")); //var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); //jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //jsonFormatter.SerializerSettings.Converters.Add(new LinkModelConverter()); /* //Add support JSONP var jsonpformatter = new JsonpMediaTypeFormatter(jsonFormatter,"cb"); config.Formatters.Insert(0,jsonpformatter); config.Formatters.JsonFormatter.MediaTypeMappings.Add(new RequestHeaderMapping("Accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, "application/json")); jsonFormatter.SerializerSettings.Converters.Add(new LinkModelConverter()); CreateMediaTypes(jsonFormatter); //Add support JSONP var jsonpformatter = new JsonpMediaTypeFormatter(jsonFormatter, "cb"); config.Formatters.Insert(0, jsonpformatter); */ var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); jsonFormatter.MediaTypeMappings.Add(new RequestHeaderMapping("Accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, "application/json")); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); jsonFormatter.SerializerSettings.Converters.Add(new LinkModelConverter()); var jsonpFormatter = new JsonpMediaTypeFormatter(jsonFormatter, "cb"); config.Formatters.Insert(0, jsonpFormatter); CreateMediaTypes(jsonFormatter); //replace the Controller original configiration with custom config //web api 1 //not gonna to use it in WEB API 2 config.Services.Replace(typeof(IHttpControllerSelector), new RCControllerSelector(config)); //custom code //Forse HTTPS on entire API #if !DEBUG config.Filters.Add(new RequireHttpsAttribute()); #endif //Configure Caching/Etag support var connString = ConfigurationManager.ConnectionStrings["RCDB"].ConnectionString; var etagStore = new SqlServerEntityTagStore(connString); //var cacheHandler = new CachingHandler(config); var cacheHandler = new CachingHandler(config, etagStore); cacheHandler.AddLastModifiedHeader = false; //config.MessageHandlers.Add(cacheHandler); // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type. // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries. // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. //config.EnableQuerySupport(); // To disable tracing in your application, please comment out or remove the following line of code // For more information, refer to: http://www.asp.net/web-api config.EnableSystemDiagnosticsTracing(); }
public static void TestCacheInvalidation(string method) { // setup var mocks = new MockRepository(); var request = new HttpRequestMessage(new HttpMethod(method), TestUrl); string routePattern = "http://myserver/api/stuffs/*"; var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var linkedUrls = new []{"url1", "url2"}; var cachingHandler = new CachingHandler(entityTagStore) { LinkedRoutePatternProvider = (url, mthd, headers) => linkedUrls }; var entityTagKey = new CacheKey(TestUrl, new string[0], routePattern); var response = new HttpResponseMessage(); var invalidateCache = cachingHandler.InvalidateCache(entityTagKey, request, response); entityTagStore.Expect(x => x.RemoveAllByRoutePattern(routePattern)).Return(1); entityTagStore.Expect(x => x.RemoveAllByRoutePattern(linkedUrls[0])).Return(0); entityTagStore.Expect(x => x.RemoveAllByRoutePattern(linkedUrls[1])).Return(0); mocks.ReplayAll(); // run invalidateCache(); // verify mocks.VerifyAll(); }
public static void TestCacheInvalidationForLinkedResouces(string method) { // setup var mocks = new MockRepository(); var request = new HttpRequestMessage(new HttpMethod(method), TestUrl); string routePattern = "http://myserver/api/stuffs/*"; var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var cachingHandler = new CachingHandler(entityTagStore) { LinkedRoutePatternProvider = (url, mthd, headers) => headers.Where(_ => _.Key == "Link") .SelectMany(_ => _.Value) .Select(_ => System.Text.RegularExpressions.Regex.Match(_, @"<(?<uri>.+?)>").Groups["uri"].Value) }; var entityTagKey = new CacheKey(TestUrl, new string[0], routePattern); var response = new HttpResponseMessage(); response.Headers.Add("Link", "</Now/Invalid/Uri>; rel=\"invalidates\""); var invalidateCache = cachingHandler.InvalidateCache(entityTagKey, request, response); entityTagStore.Expect(x => x.RemoveAllByRoutePattern(routePattern)).Return(1); entityTagStore.Expect(x => x.RemoveAllByRoutePattern("/Now/Invalid/Uri")).Return(0); mocks.ReplayAll(); // run invalidateCache(); // verify mocks.VerifyAll(); }
public static void TestCacheInvalidationForPost(string method) { // setup var locationUrl = new Uri("http://api/SomeLocationUrl"); var mocks = new MockRepository(); var request = new HttpRequestMessage(new HttpMethod(method), TestUrl); string routePattern = "http://myserver/api/stuffs/*"; var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var linkedUrls = new[] { "url1", "url2" }; var cachingHandler = new CachingHandler(entityTagStore) { LinkedRoutePatternProvider = (url, mthd, headers) => linkedUrls }; var entityTagKey = new CacheKey(TestUrl, new string[0], routePattern); var response = new HttpResponseMessage(); response.Headers.Location = locationUrl; var invalidateCacheForPost = cachingHandler.PostInvalidationRule(entityTagKey, request, response); if(method == "POST") { entityTagStore.Expect(x => x.RemoveAllByRoutePattern(locationUrl.ToString())).Return(1); } mocks.ReplayAll(); // run invalidateCacheForPost(); // verify mocks.VerifyAll(); }
public static void TestManualInvalidation(string method) { // setup var mocks = new MockRepository(); string routePattern1 = "http://myserver/api/stuffs/*"; string routePattern2 = "http://myserver/api/more/*"; var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var linkedUrls = new[] { "url1", "url2" }; var cachingHandler = new CachingHandler(entityTagStore) { LinkedRoutePatternProvider = (url, mthd) => linkedUrls, CacheKeyGenerator = (url, headers) => { if (url == "/api/stuff/") return new CacheKey(url, headers.SelectMany(h => h.Value), routePattern1); if (url == "/api/more/") return new CacheKey(url, headers.SelectMany(h => h.Value), routePattern2); throw new ArgumentException(); } }; entityTagStore.Expect(x => x.RemoveAllByRoutePattern(routePattern1)).Return(1); entityTagStore.Expect(x => x.RemoveAllByRoutePattern(routePattern2)).Return(1); entityTagStore.Expect(x => x.RemoveAllByRoutePattern(linkedUrls[0])).Return(0); entityTagStore.Expect(x => x.RemoveAllByRoutePattern(linkedUrls[1])).Return(0); mocks.ReplayAll(); // run cachingHandler.InvalidateResources(new HttpMethod(method), new Uri(TestUrl), new Uri(TestUrl2)); // verify mocks.VerifyAll(); }
public static void TestManualInvalidation(string method) { // setup var mocks = new MockRepository(); var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var cachingHandler = new CachingHandler(new HttpConfiguration(), entityTagStore) { }; entityTagStore.Expect(x => x.RemoveResource("/api/stuff/")).Return(1); entityTagStore.Expect(x => x.RemoveResource("/api/more/")).Return(1); mocks.ReplayAll(); // run cachingHandler.InvalidateResource(new HttpRequestMessage(new HttpMethod(method), new Uri(TestUrl))); cachingHandler.InvalidateResource(new HttpRequestMessage(new HttpMethod(method), new Uri(TestUrl2))); // verify mocks.VerifyAll(); }
/// <summary>Registers the specified configuration.</summary> /// <param name="config">The configuration.</param> /// <param name="unityContainer">The unity container.</param> /// <param name="unitOfWork">The unit of work.</param> public static void Register(HttpConfiguration config, IUnityContainer unityContainer, IUnitOfWork unitOfWork) { var applicationSettingRepository = unitOfWork.GetTypedRepository<IApplicationSettingRepository>(); etagCacheServerDuration = applicationSettingRepository.GetOrCreateByName<int>("EtagCacheServerDuration"); etagCacheClientDuration = applicationSettingRepository.GetOrCreateByName<int>("EtagCacheClientDuration"); #if !DEBUG // Configure Web API to use only bearer token authentication. // Only suppress if not in debug mode, this allows browsing the WebAPI if in debug mode. config.SuppressDefaultHostAuthentication(); #endif config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); config.Filters.Add(new ModelStateValidationFilter()); config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new SelectSupportConverter()); var browserFormatter = new BrowserJsonFormatter { SerializerSettings = { ContractResolver = new CamelCasePropertyNamesContractResolver() } }; browserFormatter.SerializerSettings.Converters.Add(new SelectSupportConverter()); config.Formatters.Add(browserFormatter); config.DependencyResolver = new UnityDependencyResolver(unityContainer); // Changing this setting requires a website restart if (applicationSettingRepository.GetOrCreateByName<bool>("Caching_EnableEtags")) { var etagStore = new SqlServerEntityTagStore(ConfigurationManager.ConnectionStrings["InSite.Commerce"].ConnectionString); // The vary by in the constructor needs to be something that is unique per user so it generates ETags uniquely per user // Cookie contains a cookie we generate InsiteCacheId that is a guid per user. var cacheHandler = new CachingHandler(config, etagStore, "Cookie") { // This must be false so IE client side caching works, anything that needs to vary needs to be done by uri or querystring AddVaryHeader = false, AddLastModifiedHeader = true, RoutePatternProvider = new CacheRoutePatternProvider(), CacheControlHeaderProvider = CacheControlHeaderProvider, CacheRefreshPolicyProvider = CacheRefreshPolicyProvider }; config.MessageHandlers.Add(cacheHandler); } config.MessageHandlers.Add(new LocalizationHandler()); config.MapHttpAttributeRoutes(new InheritanceDirectRouteProvider()); // There can be multiple exception loggers. (By default, no exception loggers are registered.) config.Services.Add(typeof(IExceptionLogger), unityContainer.Resolve<IExceptionLogger>()); // There must be exactly one exception handler. (There is a default one that may be replaced.) config.Services.Replace(typeof(IExceptionHandler), unityContainer.Resolve<IExceptionHandler>()); }
private void ConfigureCaching(HttpConfiguration configuration) { var cachingHandler = new CachingHandler(configuration); configuration.MessageHandlers.Add(cachingHandler); s_container.RegisterInstance<ICachingHandler>(cachingHandler); }
public void Test_NoStore_ResultsIn_ExpiredResourceAndPragmaNoCache() { var request = new HttpRequestMessage(HttpMethod.Get, TestUrl); request.Headers.Add(HttpHeaderNames.Accept, "text/xml"); var entityTagHeaderValue = new TimedEntityTagHeaderValue("\"12345678\""); var cachingHandler = new CachingHandler(new HttpConfiguration()) { ETagValueGenerator = (x, y) => entityTagHeaderValue, CacheControlHeaderProvider = (r, c) => { return new CacheControlHeaderValue() { NoStore = true, NoCache = true }; } }; var response = request.CreateResponse(HttpStatusCode.Accepted); cachingHandler.AddCaching(new CacheKey(TestUrl, new string[0]), request, response)(); Assert.IsTrue(response.Headers.Pragma.Any(x=>x.Name == "no-cache"), "no-cache not in pragma"); }
public static void TestGetModifiedUnmodifiedReturnsNullIfNoneDefined() { // setup var request = new HttpRequestMessage(HttpMethod.Get, TestUrl); var entityTagHandler = new CachingHandler(new HttpConfiguration()); var getRule = entityTagHandler.GetIfModifiedUnmodifiedSince(); // run var task = getRule(request); // verify Assert.IsNull(task); }
public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); //config.Routes.MapHttpRoute( // name: "Food", // routeTemplate: "api/nutrition/foods/{foodid}", // defaults: new { controller = "foods", foodid = RouteParameter.Optional } //); config.Routes.MapHttpRoute( name: "Measures", routeTemplate: "api/nutrition/foods/{id}/measures/{id}", defaults: new { controller = "measures", id = RouteParameter.Optional } ); // config.Routes.MapHttpRoute( // name: "Measures2", // routeTemplate: "api/nutrition/foods/{id}/measures/{id}", // defaults: new { controller = "measuresv2", id = RouteParameter.Optional } //); config.Routes.MapHttpRoute( name: "Diaries", routeTemplate: "api/user/diaries/{diaryid}", defaults: new { controller = "diaries", diaryid = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DiariesEntries", routeTemplate: "api/user/diaries/{diaryid}/entries/{id}", defaults: new { controller = "diaryentries", diaryid = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DiarySummary", routeTemplate: "api/user/diaries/{diaryid}/summary", defaults: new { controller = "diarysummary" } ); config.Routes.MapHttpRoute( name: "Token", routeTemplate: "api/token", defaults: new { controller = "Token" } ); // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type. // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries. // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. //config.EnableQuerySupport(); //return Camelcase for Json formats: var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); CreateMediaTypes(jsonFormatter); // Adding support JSONP using : "webapicontrib.formatting.jsonp" in nugget var formatter = new JsonpMediaTypeFormatter(jsonFormatter, "cb"); config.Formatters.Insert(0, formatter); // Makes API calls in jsonp formatter first // Adds a Https requirement for all API calls config.Filters.Add(new RequireHttpsAttribute()); // Adds CORs By adding: "microsoft.aspnet.webapi.cors" in nugget var attr = new EnableCorsAttribute("*", "*", "GET"); // Allows entire website to use Cors config.EnableCors(attr); // Replace the Controller Configuration config.Services.Replace(typeof(IHttpControllerSelector), new CountingKsControllerSelector(config)); // Configure Caching/ETag Support using CacheCow Server var connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; var etagStore = new SqlServerEntityTagStore(connString); var cacheHandler = new CachingHandler(config, etagStore); config.MessageHandlers.Add(cacheHandler); }
public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); /* config.Routes.MapHttpRoute( name: "Food", routeTemplate: "api/nutrition/{foodid}", defaults: new { Controller = "Foods", foodid = RouteParameter.Optional }, constraints: new { id="/d+"} //regular expression for the parameter so its only an integer that accepted ); */ config.Routes.MapHttpRoute( name: "Measures", routeTemplate: "api/nutrition/{foodid}/measures/{id}", defaults: new { Controller = "measures", id = RouteParameter.Optional }, constraints: new { id = "/d+" } //regular expression for the parameter so its only an integer that accepted ); /* config.Routes.MapHttpRoute( name: "Measures2", routeTemplate: "api/nutrition/{foodid}/measures/{id}", defaults: new { Controller = "MeasuresV2", id = RouteParameter.Optional }, constraints: new { id = "/d+" } //regular expression for the parameter so its only an integer that accepted ); */ config.Routes.MapHttpRoute( name: "Diaries", routeTemplate: "api/user/diaries/{diaryid}", defaults: new { Controller = "diaries", diaryid = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DiarySummary", routeTemplate: "api/user/diaries/{diaryid}/summary", defaults: new { Controller = "DiarySummary" } ); config.Routes.MapHttpRoute( name: "Token", routeTemplate: "api/token", defaults: new { Controller = "token" } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type. // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries. // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. //config.EnableQuerySupport(); var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); jsonFormatter.SerializerSettings.Converters.Add(new LinkModelConverter()); //converters know how to convert into and out of json CreateMediaTypes(jsonFormatter); //Add support for jsonp //without accepts header will go to json, need accepts with javascript //also nees ?callback= in the url var formatter = new JsonpMediaTypeFormatter(jsonFormatter,"cb"); config.Formatters.Insert(0, formatter); //Replace the controller configuration with our controller selector //config.Services.Replace(typeof(IHttpControllerSelector),new CountingKsControllerSelector(config)); //Configure caching/etag support //this outputs etag after request in response header var connString=ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; var etagStore = new SqlServerEntityTagStore(connString); var cacheHandler = new CachingHandler(config); //not sure if config is correct, example didnt pass any params cacheHandler.AddLastModifiedHeader = false; // not needed, true by default config.MessageHandlers.Add(cacheHandler); //Add support for cross origin resource supprt (CORS) var attr = new EnableCorsAttribute("*", "*", "GET"); config.EnableCors(attr); //allowed to enable, not enabled yet #if !DEBUG //Force HTTPS on entire API config.Filters.Add(new RequireHttpsAttribute()); #endif }
public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Food", routeTemplate: "api/nutrition/foods/{foodid}", defaults: new { controller = "foods", foodid = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "Measures", routeTemplate: "api/nutrition/foods/{foodid}/measures/{id}", defaults: new { controller = "measures", id = RouteParameter.Optional } ); //config.Routes.MapHttpRoute( // name: "Measures2", // routeTemplate: "api/nutrition/foods/{foodid}/measures/{id}", // defaults: new { controller = "measuresv2", id = RouteParameter.Optional } //); config.Routes.MapHttpRoute( name: "Diaries", routeTemplate: "api/user/diaries/{diaryid}", defaults: new { controller = "diaries", diaryid = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DiaryEntries", routeTemplate: "api/user/diaries/{diaryid}/entries/{id}", defaults: new { controller = "diaryentries", id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DiarySummary", routeTemplate: "api/user/diaries/{diaryid}/summary", defaults: new { controller = "diarysummary" } ); config.Routes.MapHttpRoute( name: "Tokens", routeTemplate: "api/token", defaults: new { controller = "token" } ); // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type. // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries. // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. //config.EnableQuerySupport(); var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); jsonFormatter.SerializerSettings.Converters.Add(new LinkModelConverter()); CreateMediaTypes(jsonFormatter); // Add support JSONP var formatter = new JsonpMediaTypeFormatter(jsonFormatter, "cb"); config.Formatters.Insert(0, formatter); // Replace the Controller Configuration config.Services.Replace(typeof(IHttpControllerSelector), new CountingKsControllerSelector(config)); // Configure Caching/ETag Support var connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; // REMINDER: Make sure you've run the SQL Scripts in the // Package Folder! var etagStore = new SqlServerEntityTagStore(connString); var cacheHandler = new CachingHandler(etagStore); config.MessageHandlers.Add(cacheHandler); #if !DEBUG // Force HTTPS on entire API config.Filters.Add(new RequireHttpsAttribute()); #endif }
public static void Register(HttpConfiguration config) { // Web API configuration and services // Configure Web API to use only bearer token authentication. var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); config.SuppressDefaultHostAuthentication(); config.Filters.Add(new ValidateModelAttribute()); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); //Added to return JSON as default config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); var formatters = GlobalConfiguration.Configuration.Formatters; var jsonFormatter = formatters.JsonFormatter; var settings = jsonFormatter.SerializerSettings; settings.Formatting = Formatting.Indented; settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); // Web API routes config.MapHttpAttributeRoutes(); //Caching and Etags var connString = ConfigurationManager.ConnectionStrings["AutoResolveContext"].ConnectionString; var sqlServerEtagStore = new InMemoryEntityTagStore(); var cacheHandler = new CachingHandler(config, sqlServerEtagStore); config.MessageHandlers.Add(cacheHandler); /*DEFAULT*/ config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); /*CUSTOMERS*/ config.Routes.MapHttpRoute( name: "Customers", routeTemplate: "api/customers/{id}", defaults: new { id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "CustomersAccidents", routeTemplate: "api/customers/{id}/accidents", defaults: new { controller = "CustomersAccidents" } ); /*ACCIDENTS*/ config.Routes.MapHttpRoute( name: "Accidents", routeTemplate: "api/accidents/{id}", defaults: new { id = RouteParameter.Optional } ); /*DEFENDANTS*/ config.Routes.MapHttpRoute( name: "OtherDrivers", routeTemplate: "api/otherdrivers/{id}", defaults: new { id = RouteParameter.Optional } ); /*WITNESSES*/ config.Routes.MapHttpRoute( name: "Witnesses", routeTemplate: "api/witnesses/{id}", defaults: new { id = RouteParameter.Optional } ); /*MEDIA*/ config.Routes.MapHttpRoute( name: "AccidentMedia", routeTemplate: "api/accidentmedia/{id}", defaults: new { id = RouteParameter.Optional } ); /*NOTIFICATIONS*/ config.Routes.MapHttpRoute( name: "Notifications", routeTemplate: "api/notifications/{id}", defaults: new { id = RouteParameter.Optional } ); /*Account*/ config.Routes.MapHttpRoute( name: "Account", routeTemplate: "api/account/{id}", defaults: new { id = RouteParameter.Optional } ); /*Account*/ config.Routes.MapHttpRoute( name: "CustomerSettings", routeTemplate: "api/customersettings/{id}", defaults: new { id = RouteParameter.Optional } ); /* /*ENTRY#1# config.Routes.MapHttpRoute( name: "Entry", routeTemplate: "api/entry/" );*/ }
public static void TestManualInvalidation(string method) { // setup var mocks = new MockRepository(); string routePattern1 = "http://myserver/api/stuffs/*"; string routePattern2 = "http://myserver/api/more/*"; var entityTagStore = mocks.StrictMock<IEntityTagStore>(); var linkedUrls = new[] { "url1", "url2" }; var cachingHandler = new CachingHandler(new HttpConfiguration(), entityTagStore) { LinkedRoutePatternProvider = (req) => linkedUrls, }; entityTagStore.Expect(x => x.RemoveResource("/api/stuff/")).Return(1); entityTagStore.Expect(x => x.RemoveResource("/api/more/")).Return(1); mocks.ReplayAll(); // run cachingHandler.InvalidateResource(new HttpRequestMessage(new HttpMethod(method), new Uri(TestUrl))); cachingHandler.InvalidateResource(new HttpRequestMessage(new HttpMethod(method), new Uri(TestUrl2))); // verify mocks.VerifyAll(); }