public async Task includeUrlWithCache(ScriptScopeContext scope, string url, object options) { var scopedParams = scope.AssertOptions(nameof(includeUrl), options); var expireIn = scopedParams.TryGetValue("expireInSecs", out object value) ? TimeSpan.FromSeconds(value.ConvertTo <int>()) : (TimeSpan)scope.Context.Args[ScriptConstants.DefaultUrlCacheExpiry]; var cacheKey = CreateCacheKey("url:" + url, scopedParams); if (Context.ExpiringCache.TryGetValue(cacheKey, out Tuple <DateTime, object> cacheEntry)) { if (cacheEntry.Item1 > DateTime.UtcNow && cacheEntry.Item2 is byte[] bytes) { await scope.OutputStream.WriteAsync(bytes); return; } } var dataType = scopedParams.TryGetValue("dataType", out value) ? ConvertDataTypeToContentType((string)value) : null; if (scopedParams.TryGetValue("method", out value) && !((string)value).EqualsIgnoreCase("GET")) { throw new NotSupportedException($"Only GET requests can be used in {nameof(includeUrlWithCache)} filters in page '{scope.Page.VirtualPath}'"); } if (scopedParams.TryGetValue("data", out value)) { throw new NotSupportedException($"'data' is not supported in {nameof(includeUrlWithCache)} filters in page '{scope.Page.VirtualPath}'"); } var ms = MemoryStreamFactory.GetStream(); using (ms) { var captureScope = scope.ScopeWithStream(ms); await includeUrl(captureScope, url, options); ms.Position = 0; var expireAt = DateTime.UtcNow.Add(expireIn); var bytes = ms.ToArray(); Context.ExpiringCache[cacheKey] = cacheEntry = Tuple.Create(expireAt, (object)bytes); await scope.OutputStream.WriteAsync(bytes); } }
public override async Task <bool> WritePageFragmentAsync(ScriptScopeContext scope, PageFragment fragment, CancellationToken token) { var page = scope.PageResult; if (fragment is PageJsBlockStatementFragment blockFragment) { var blockStatements = blockFragment.Block.Statements; if (blockFragment.Quiet && scope.OutputStream != Stream.Null) { scope = scope.ScopeWithStream(Stream.Null); } await page.WriteStatementsAsync(scope, blockStatements, token); return(true); } return(false); }