/// <summary> /// Registers the output caching service with the dependency injection system. /// </summary> public static void AddOutputCaching(this IServiceCollection services) { var options = new OutputCacheOptions(); services.AddSingleton(options); services.AddSingleton <IOutputCachingService, OutputCachingService>(); }
public async Task ServesFreshContent_If_ResponseExpired(string method) { var options = new OutputCacheOptions { DefaultExpirationTimeSpan = TimeSpan.FromMicroseconds(100) }; var builders = TestUtils.CreateBuildersWithOutputCaching(options: options); foreach (var builder in builders) { using var host = builder.Build(); await host.StartAsync(); using var server = host.GetTestServer(); var client = server.CreateClient(); var initialResponse = await client.SendAsync(TestUtils.CreateRequest(method, "")); await Task.Delay(1); var subsequentResponse = await client.SendAsync(TestUtils.CreateRequest(method, "")); await AssertFreshResponseAsync(initialResponse, subsequentResponse); } }
public async Task ServesCachedContent_If_Authorization_HeaderExists(string method) { var options = new OutputCacheOptions(); var builders = TestUtils.CreateBuildersWithOutputCaching(options: options); // This is added after the DefaultPolicy which disables caching for authenticated requests options.AddBasePolicy(b => b.AddPolicy <AllowTestPolicy>()); foreach (var builder in builders) { using var host = builder.Build(); await host.StartAsync(); using var server = host.GetTestServer(); var client = server.CreateClient(); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("abc"); var initialResponse = await client.SendAsync(TestUtils.CreateRequest(method, "")); var subsequentResponse = await client.SendAsync(TestUtils.CreateRequest(method, "")); await AssertCachedResponseAsync(initialResponse, subsequentResponse); } }
public async Task ServesFreshContent_IfVaryHeader_Mismatches() { var options = new OutputCacheOptions(); options.AddBasePolicy(b => b.VaryByHeader(HeaderNames.From).Build()); var builders = TestUtils.CreateBuildersWithOutputCaching(options: options); foreach (var builder in builders) { using var host = builder.Build(); await host.StartAsync(); using var server = host.GetTestServer(); var client = server.CreateClient(); client.DefaultRequestHeaders.From = "*****@*****.**"; var initialResponse = await client.GetAsync(""); client.DefaultRequestHeaders.From = "*****@*****.**"; var subsequentResponse = await client.GetAsync(""); await AssertFreshResponseAsync(initialResponse, subsequentResponse); } }
internal static OutputCacheMiddleware CreateTestMiddleware( RequestDelegate?next = null, IOutputCacheStore?cache = null, OutputCacheOptions?options = null, TestSink?testSink = null, IOutputCacheKeyProvider?keyProvider = null ) { if (next == null) { next = httpContext => Task.CompletedTask; } if (cache == null) { cache = new TestOutputCache(); } if (options == null) { options = new OutputCacheOptions(); } if (keyProvider == null) { keyProvider = new OutputCacheKeyProvider(new DefaultObjectPoolProvider(), Options.Create(options)); } return(new OutputCacheMiddleware( next, Options.Create(options), testSink == null ? NullLoggerFactory.Instance : new TestLoggerFactory(testSink, true), cache, keyProvider)); }
/// <summary> /// Registers the output caching service with the dependency injection system. /// </summary> public static void AddOutputCaching(this IServiceCollection services, Action <OutputCacheOptions> outputCacheOptions) { var options = new OutputCacheOptions(); outputCacheOptions(options); services.AddOutputCaching(options); }
internal OutputCacheKeyProvider(ObjectPoolProvider poolProvider, IOptions <OutputCacheOptions> options) { ArgumentNullException.ThrowIfNull(poolProvider); ArgumentNullException.ThrowIfNull(options); _builderPool = poolProvider.CreateStringBuilderPool(); _options = options.Value; }
public string RemoveDonutHoleWrappers(string content, ControllerContext filterContext, OutputCacheOptions options) { //if ( // filterContext.IsChildAction && // (options & OutputCacheOptions.ReplaceDonutsInChildActions) != OutputCacheOptions.ReplaceDonutsInChildActions) //{ // return content; //} return DonutHoles.Replace(content, match => match.Groups[2].Value); }
public async Task Attribute_CreatesNamedPolicy() { var options = new OutputCacheOptions(); options.AddPolicy("MyPolicy", b => b.Expire(TimeSpan.FromSeconds(42))); var context = TestUtils.CreateTestContext(options: options); var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.PolicyName)); await attribute.BuildPolicy().CacheRequestAsync(context, cancellation: default); Assert.True(context.EnableOutputCaching); Assert.Equal(42, context.ResponseExpirationTimeSpan?.TotalSeconds); }
public async Task BuildPolicy_CacheReturnsDefault() { // Each predicate should override the duration from the first base policy var options = new OutputCacheOptions(); options.AddBasePolicy(build => build.Cache()); var context = TestUtils.CreateUninitializedContext(options: options); foreach (var policy in options.BasePolicies) { await policy.CacheRequestAsync(context, default); } Assert.True(context.EnableOutputCaching); }
public async Task BuildPolicy_AddsCustomPolicy() { var options = new OutputCacheOptions(); var name = "MyPolicy"; var duration = 42; options.AddPolicy(name, b => b.Expire(TimeSpan.FromSeconds(duration))); var context = TestUtils.CreateUninitializedContext(options: options); var builder = new OutputCachePolicyBuilder(); var policy = builder.AddPolicy(new NamedPolicy(name)).Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Equal(duration, context.ResponseExpirationTimeSpan?.TotalSeconds); }
public async Task BuildPolicy_NoDefaultWithFalsePredicate() { // Each predicate should override the duration from the first base policy var options = new OutputCacheOptions(); options.AddBasePolicy(build => build.With(c => false).Expire(TimeSpan.FromSeconds(2))); var context = TestUtils.CreateUninitializedContext(options: options); foreach (var policy in options.BasePolicies) { await policy.CacheRequestAsync(context, default); } Assert.False(context.EnableOutputCaching); Assert.NotEqual(2, context.ResponseExpirationTimeSpan?.TotalSeconds); }
public async Task BuildPolicy_ChecksWithPredicate(int source, int expected) { // Each predicate should override the duration from the first base policy var options = new OutputCacheOptions(); options.AddBasePolicy(build => build.Expire(TimeSpan.FromSeconds(1))); options.AddBasePolicy(build => build.With(c => source == 1).Expire(TimeSpan.FromSeconds(2))); options.AddBasePolicy(build => build.With(c => source == 2).Expire(TimeSpan.FromSeconds(3))); var context = TestUtils.CreateUninitializedContext(options: options); foreach (var policy in options.BasePolicies) { await policy.CacheRequestAsync(context, default); } Assert.True(context.EnableOutputCaching); Assert.Equal(expected, context.ResponseExpirationTimeSpan?.TotalSeconds); }
public async Task ProfilePolicy_UsesNamedProfile() { var options = new OutputCacheOptions(); options.AddPolicy("enabled", EnableCachePolicy.Enabled); options.AddPolicy("disabled", EnableCachePolicy.Disabled); var context = TestUtils.CreateUninitializedContext(options: options); IOutputCachePolicy policy = new NamedPolicy("enabled"); await policy.CacheRequestAsync(context, default); Assert.True(context.EnableOutputCaching); policy = new NamedPolicy("disabled"); await policy.CacheRequestAsync(context, default); Assert.False(context.EnableOutputCaching); }
public string ReplaceDonutHoleContent(string content, ControllerContext filterContext, OutputCacheOptions options) { //if ( // filterContext.IsChildAction && // (options & OutputCacheOptions.ReplaceDonutsInChildActions) != OutputCacheOptions.ReplaceDonutsInChildActions) //{ // return content; //} return DonutHoles.Replace(content, match => { var actionSettings = _actionSettingsSerialiser.Deserialise(match.Groups[1].Value); return InvokeAction( filterContext.Controller, actionSettings.ActionName, actionSettings.ControllerName, actionSettings.RouteValues ); }); }
// for testing internal OutputCacheMiddleware( RequestDelegate next, IOptions <OutputCacheOptions> options, ILoggerFactory loggerFactory, IOutputCacheStore cache, IOutputCacheKeyProvider keyProvider) { ArgumentNullException.ThrowIfNull(next); ArgumentNullException.ThrowIfNull(options); ArgumentNullException.ThrowIfNull(loggerFactory); ArgumentNullException.ThrowIfNull(cache); ArgumentNullException.ThrowIfNull(keyProvider); _next = next; _options = options.Value; _logger = loggerFactory.CreateLogger <OutputCacheMiddleware>(); _store = cache; _keyProvider = keyProvider; _outputCacheEntryDispatcher = new(); _requestDispatcher = new(); }
public async Task ServesFreshContent_If_PathCasingDiffers(string method) { var options = new OutputCacheOptions { UseCaseSensitivePaths = true }; var builders = TestUtils.CreateBuildersWithOutputCaching(options: options); foreach (var builder in builders) { using var host = builder.Build(); await host.StartAsync(); using var server = host.GetTestServer(); var client = server.CreateClient(); var initialResponse = await client.SendAsync(TestUtils.CreateRequest(method, "path")); var subsequentResponse = await client.SendAsync(TestUtils.CreateRequest(method, "PATH")); await AssertFreshResponseAsync(initialResponse, subsequentResponse); } }
public async Task ServesCachedContent_IfVaryQueryKeyStar_Matches_OrderInsensitive() { var options = new OutputCacheOptions(); options.AddBasePolicy(b => b.VaryByQuery("*")); var builders = TestUtils.CreateBuildersWithOutputCaching(options: options); foreach (var builder in builders) { using var host = builder.Build(); await host.StartAsync(); using var server = host.GetTestServer(); var client = server.CreateClient(); var initialResponse = await client.GetAsync("?QueryA=ValueA&QueryB=ValueB"); var subsequentResponse = await client.GetAsync("?QueryB=ValueB&QueryA=ValueA"); await AssertCachedResponseAsync(initialResponse, subsequentResponse); } }
public string ReplaceDonutHoleContent(string content, ControllerContext filterContext, OutputCacheOptions options) { return(ReplaceDonutHoleContent(content, null, filterContext, options)); }
public string ReplaceDonutHoleContent(string content, ControllerContext filterContext, OutputCacheOptions options) { if (filterContext.IsChildAction && (options & OutputCacheOptions.ReplaceDonutsInChildActions) != OutputCacheOptions.ReplaceDonutsInChildActions) { return(content); } return(DonutHoleRegex.Replace(content, match => { var contentReference = JsonConvert.DeserializeObject <ContentReference>(match.Groups[1].Value); if (contentReference == null) { return null; } var htmlToRenderWithoutDonutComment = new StringBuilder(); using (var stringWriter = new StringWriter()) { var htmlHelper = EpiServerDonutHelper.CreateHtmlHelper(filterContext.Controller, stringWriter); var repo = ServiceLocator.Current.GetInstance <IContentRepository>(); var epiContentToRender = repo.Get <IContent>(contentReference); var openTag = OpenTagRegex.Match(match.Groups[1].ToString()).Groups[1].ToString(); if (!string.IsNullOrEmpty(openTag)) { htmlToRenderWithoutDonutComment.Append(openTag); } EpiServerDonutHelper.RenderContentData(htmlHelper, epiContentToRender, string.Empty); htmlToRenderWithoutDonutComment.Append(stringWriter.ToString()); var closeTag = CloseTagRegex.Match(match.Groups[1].ToString()).Groups[1].ToString(); if (!string.IsNullOrEmpty(closeTag)) { htmlToRenderWithoutDonutComment.Append(closeTag); } } return htmlToRenderWithoutDonutComment.ToString(); })); }
public string ReplaceDonutHoleContent(string content, string contentType, ControllerContext filterContext, OutputCacheOptions options) { if ( filterContext.IsChildAction && (options & OutputCacheOptions.ReplaceDonutsInChildActions) != OutputCacheOptions.ReplaceDonutsInChildActions) { return(content); } return(DonutHoles.Replace(content, match => { var actionSettings = _actionSettingsSerialiser.Deserialise(match.Groups[1].Value); var actionResultString = InvokeAction( filterContext.Controller, actionSettings.ActionName, actionSettings.ControllerName, actionSettings.RouteValues ); // escape the string, so the parent's json is not broken // notice: rendering json objects with donut caching inside a json object is not supported! if (contentType != null && contentType.Equals("application/json", StringComparison.InvariantCultureIgnoreCase)) { var escaped = System.Web.Helpers.Json.Encode(actionResultString); if (string.IsNullOrEmpty(escaped)) { return escaped; } // the escaped string is wrapped in quotes return escaped.Substring(1, escaped.Length - 2); } return actionResultString; })); }
private static void AddOutputCaching(this IServiceCollection services, OutputCacheOptions options) { services.AddSingleton(options); services.TryAddSingleton <IOutputCachingService, OutputCachingService>(); services.TryAddSingleton <IOutputCacheKeysProvider, OutputCacheKeysProvider>(); }
internal static IOutputCacheKeyProvider CreateTestKeyProvider(OutputCacheOptions options) { return(new OutputCacheKeyProvider(new DefaultObjectPoolProvider(), Options.Create(options))); }