Example #1
0
        public async Task Tests_cache_invalidation()
        {
            const string url = "http://thecatapi.com/api/images/get?format=html";

            var handler = new InMemoryCacheHandler(new HttpClientHandler(), CacheExpirationProvider.CreateSimple(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(5)));

            using (var client = new HttpClient(handler))
            {
                for (int i = 0; i < 5; i++)
                {
                    var sw = Stopwatch.StartNew();
                    Debug.Write($"Getting data from {url}, iteration #{i + 1}...");
                    var result = await client.GetAsync(url);

                    var content = await result.Content.ReadAsStringAsync();

                    Debug.WriteLine($" completed in {sw.ElapsedMilliseconds}ms. Content was {content}.");
                    if (i % 2 == 0)
                    {
                        Debug.WriteLine($"Iteration {i}. Invalidating cache.");
                        handler.InvalidateCache(new Uri(url));
                    }
                }
            }

            StatsResult stats = handler.StatsProvider.GetStatistics();

            stats.Total.CacheHit.Should().Be(2);
            stats.Total.CacheMiss.Should().Be(3);
        }
        public async Task Invalidates_cache_per_method()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var handler            = new InMemoryCacheHandler(testMessageHandler);
            var client             = new HttpClient(handler);

            // execute with two methods, and clean up one cache
            var uri = new Uri("http://unittest");
            await client.GetAsync(uri);

            await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, uri));

            testMessageHandler.NumberOfCalls.Should().Be(2);

            // clean cache
            handler.InvalidateCache(uri, HttpMethod.Head);

            // execute both actions, and only one should be retrieved from cache
            await client.GetAsync(uri);

            await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, uri));

            testMessageHandler.NumberOfCalls.Should().Be(3);
        }
Example #3
0
        public void test_Handler_Client_Disabled_Caching()
        {
            APGatewayBuilder <APGateway> builder = new APGatewayBuilder <APGateway>();

            builder.Method(HTTPMethod.GET.ToString());
            builder.Uri("http://localhost/api/user/cacheMe/");
            APGateway gw = builder.Build();

            var mockHttp = new MockHttpMessageHandler();

            // Setup a respond for the user api (including a wildcard in the URL)
            mockHttp.When("http://localhost/api/user/cacheMe/*")
            .Respond("application/json", "{'name' : 'foobar'}");                     // Respond with JSON

            InMemoryCacheHandler cache = new InMemoryCacheHandler();

            gw.RestClient = new APRestClient(mockHttp, cache);
            var listener = new CacheEventListener(gw, cache);

            cache.AddListener(listener);

            var body = gw.UseCaching(false).GetSync("/cacheMe");

            Assert.AreEqual("{'name' : 'foobar'}", body);
            Assert.AreEqual(0, cache.Count());

            mockHttp.Flush();
        }
Example #4
0
        public HttpMessageHandler GetCachedHandler()
        {
            var handler = new HttpClientHandler {
                AllowAutoRedirect = true
            };
            var cacheExpirationPerHttpResponseCode = CacheExpirationProvider.CreateSimple(TimeSpan.FromHours(12), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60));
            var cacheHandler = new InMemoryCacheHandler(handler, cacheExpirationPerHttpResponseCode);

            return(cacheHandler);
        }
Example #5
0
        public WeatherService(ITracer tracer)
        {
            this.tracer = tracer;

            WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;

            var httpClientHandler = new HttpClientHandler();
            var cacheExpirationPerHttpResponseCode = CacheExpirationProvider.CreateSimple(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(5));
            var inMemoryCacheHandler = new InMemoryCacheHandler(httpClientHandler, cacheExpirationPerHttpResponseCode);

            this.httpClient = new HttpClient(inMemoryCacheHandler);
        }
        public async Task Invalidates_cache_correctly()
        {
            // setup
            var testMessageHandler = new TestMessageHandler();
            var handler            = new InMemoryCacheHandler(testMessageHandler);
            var client             = new HttpClient(handler);

            // execute twice, with cache invalidation in between
            var uri = new Uri("http://unittest");
            await client.GetAsync(uri);

            handler.InvalidateCache(uri);
            await client.GetAsync(uri);

            // validate
            testMessageHandler.NumberOfCalls.Should().Be(2);
        }
Example #7
0
        /// <summary>
        /// Adds the Claims client (with caching enabled) to a service collection.
        /// </summary>
        /// <param name="services">The service collection.</param>
        /// <param name="getOptions">A callback method to retrieve options for the client.</param>
        /// <returns>The modified service collection.</returns>
        public static IServiceCollection AddClaimsClientWithCaching(
            this IServiceCollection services,
            Func <IServiceProvider, ClaimsClientWithCachingOptions> getOptions)
        {
            return(services.AddSingleton <IClaimsService>(sp =>
            {
                ClaimsClientWithCachingOptions options = getOptions(sp);

                var handler = new InMemoryCacheHandler(new HttpClientHandler(), options.CacheExpirationPerHttpResponseCode);
                return options.ResourceIdForMsiAuthentication == null
                ? new UnauthenticatedClaimsService(options.BaseUri, handler)
                : new ClaimsService(
                    options.BaseUri,
                    new TokenCredentials(
                        sp.GetRequiredService <IServiceIdentityMicrosoftRestTokenProviderSource>().GetTokenProvider(
                            $"{options.ResourceIdForMsiAuthentication}/.default")),
                    handler);
            }));
        }
Example #8
0
        public void test_Handler()
        {
            APGatewayBuilder <APGateway> builder = new APGatewayBuilder <APGateway>();

            builder.Method(HTTPMethod.GET.ToString());
            builder.Uri("http://localhost/api/user/cacheMe");
            APGateway gw = builder.Build();

            var mockHttp = new MockHttpMessageHandler();

            // Setup a respond for the user api (including a wildcard in the URL)
            mockHttp.When("http://localhost/api/user/cacheMe/*")
            .Respond("application/json", "{'name' : 'foobar'}");         // Respond with JSON

            InMemoryCacheHandler cache = new InMemoryCacheHandler();

            gw.RestClient = new APRestClient(mockHttp, cache);
            var listener = new CacheEventListener(gw, cache);

            cache.AddListener(listener);

            // Count listener
            Assert.AreEqual(1, cache.countListeners());

            var body = gw.GetSync("/cacheThis");

            Assert.AreEqual("{'name' : 'foobar'}", body);
            Assert.AreEqual(1, cache.Count());

            Assert.AreEqual("{'name' : 'foobar'}", cache.GetFromCache(uri: "http://localhost/api/user/cacheMe/cacheThis"));

            // Should reduce the number of listeners
            Assert.AreEqual(0, cache.countListeners());

            mockHttp.Flush();

            // Clear out mock
            //mockHttp.Clear ();

            body = gw.GetSync("foo");
            Assert.AreEqual("{'name' : 'foobar'}", body);
        }
Example #9
0
        static HTTP()
        {
            if (Plugin.Instance.Configuration.ProxyEnable && !string.IsNullOrEmpty(Plugin.Instance.Configuration.ProxyHost) && Plugin.Instance.Configuration.ProxyPort > 0)
            {
                var proxy = new List <ProxyInfo>();

                if (string.IsNullOrEmpty(Plugin.Instance.Configuration.ProxyLogin) || string.IsNullOrEmpty(Plugin.Instance.Configuration.ProxyPassword))
                {
                    proxy.Add(new ProxyInfo(Plugin.Instance.Configuration.ProxyHost, Plugin.Instance.Configuration.ProxyPort));
                }
                else
                {
                    proxy.Add(new ProxyInfo(
                                  Plugin.Instance.Configuration.ProxyHost,
                                  Plugin.Instance.Configuration.ProxyPort,
                                  Plugin.Instance.Configuration.ProxyLogin,
                                  Plugin.Instance.Configuration.ProxyPassword));
                }

                Proxy = new HttpToSocks5Proxy(proxy.ToArray());
            }

            HttpHandler = new HttpClientHandler()
            {
                CookieContainer = CookieContainer,
                Proxy           = Proxy,
            };

            CacheHandler = new InMemoryCacheHandler(HttpHandler, CacheExpirationPerHttpResponseCode);

            CloudflareHandler = new ClearanceHandler(Plugin.Instance.Configuration.FlareSolverrURL)
            {
                InnerHandler = CacheHandler,
                MaxTimeout   = (int)TimeSpan.FromSeconds(120).TotalMilliseconds,
                UserAgent    = GetUserAgent(),
            };

            Http = new HttpClient(CloudflareHandler)
            {
                Timeout = TimeSpan.FromSeconds(120),
            };
        }
Example #10
0
        public ApiService(ITracer tracer, IApiServiceConfiguration apiServiceConfiguration, IMemoryCache memoryCache)
        {
            if (tracer == null)
            {
                throw new ArgumentNullException(nameof(tracer));
            }

            if (apiServiceConfiguration == null)
            {
                throw new ArgumentNullException(nameof(apiServiceConfiguration));
            }

            if (memoryCache == null)
            {
                throw new ArgumentNullException(nameof(memoryCache));
            }

            WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;

            if (apiServiceConfiguration.CachingEnabled)
            {
                var inMemoryCacheHandler = new InMemoryCacheHandler();
                this.httpClient = new HttpClient(inMemoryCacheHandler);
            }
            else
            {
                this.httpClient = new HttpClient();
            }

            this.httpClient.BaseAddress = new Uri(apiServiceConfiguration.BaseUrl);
            this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            if (apiServiceConfiguration.Timeout != TimeSpan.Zero)
            {
                this.httpClient.Timeout = apiServiceConfiguration.Timeout;
            }

            this.tracer      = tracer;
            this.memoryCache = memoryCache;
        }
Example #11
0
        public void test_NoCache()
        {
            APGatewayBuilder <APGateway> builder = new APGatewayBuilder <APGateway>();

            builder.Method(HTTPMethod.GET.ToString());
            builder.Uri("http://localhost/api/user/");
            APGateway gw = builder.Build();

            var mockHttp = new MockHttpMessageHandler();

            HttpResponseMessage message = new HttpResponseMessage();

            message.Headers.CacheControl         = new System.Net.Http.Headers.CacheControlHeaderValue();
            message.Headers.CacheControl.NoCache = true;
            message.Content = new StringContent("foo");

            // Setup a respond for the user api (including a wildcard in the URL)
            mockHttp.When("http://localhost/api/user/*")
            .Respond(message);         // Respond with JSON

            InMemoryCacheHandler cache = new InMemoryCacheHandler();

            gw.RestClient = new APRestClient(mockHttp, cache);

            cache.AddListener(new CacheEventListener(gw, cache));


            // Count listener
            Assert.AreEqual(1, cache.countListeners());

            var body = gw.GetSync("foo");

            Assert.AreEqual("foo", body);
            Assert.AreEqual(0, cache.Count());

            // Should reduce the number of listeners
            Assert.AreEqual(0, cache.countListeners());

            mockHttp.Flush();
        }
Example #12
0
        static void Main(string[] args)
        {
            const string url = "http://worldclockapi.com/api/json/utc/now";

            // HttpClient uses an HttpClientHandler nested into InMemoryCacheHandler in order to handle http get response caching
            var httpClientHandler = new HttpClientHandler();
            var cacheExpirationPerHttpResponseCode = CacheExpirationProvider.CreateSimple(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(5));
            var handler = new InMemoryCacheHandler(httpClientHandler, cacheExpirationPerHttpResponseCode);

            using (var client = new HttpClient(handler))
            {
                // HttpClient calls the same API endpoint five times:
                // - The first attempt is called against the real API endpoint since no cache is available
                // - Attempts 2 to 5 can be read from cache
                for (var i = 1; i <= 5; i++)
                {
                    Console.Write($"Attempt {i}: HTTP GET {url}...");
                    var stopwatch = Stopwatch.StartNew();
                    var result    = client.GetAsync(url).GetAwaiter().GetResult();

                    // Do something useful with the returned content...
                    var content = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    Console.WriteLine($" completed in {stopwatch.ElapsedMilliseconds}ms");

                    // Artificial wait time...
                    Thread.Sleep(1000);
                }
            }

            Console.WriteLine();

            StatsResult stats = handler.StatsProvider.GetStatistics();

            Console.WriteLine($"TotalRequests: {stats.Total.TotalRequests}");
            Console.WriteLine($"-> CacheHit: {stats.Total.CacheHit}");
            Console.WriteLine($"-> CacheMiss: {stats.Total.CacheMiss}");
            Console.ReadKey();
        }