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); }
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(); }
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); }
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); }
/// <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); })); }
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); }
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), }; }
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; }
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(); }
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(); }