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();
        }
Exemple #4
0
        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;
        }
Exemple #5
0
        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);
		}
Exemple #7
0
        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();
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        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();
        }
Exemple #17
0
        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();
        }
Exemple #18
0
        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();
        }
Exemple #19
0
        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();
        }
Exemple #22
0
        /// <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();
        }