protected override async Task <SymbolStoreFile> GetFileInner(SymbolStoreKey key, CancellationToken token) { Uri uri = GetRequestUri(key.Index); bool needsChecksumMatch = key.PdbChecksums.Any(); if (needsChecksumMatch) { string checksumHeader = string.Join(";", key.PdbChecksums); HttpClient client = _authenticatedClient ?? _client; Tracer.Information($"SymbolChecksum: {checksumHeader}"); client.DefaultRequestHeaders.Add("SymbolChecksum", checksumHeader); } Stream stream = await GetFileStream(uri, token); if (stream != null) { if (needsChecksumMatch) { ChecksumValidator.Validate(Tracer, stream, key.PdbChecksums); } return(new SymbolStoreFile(stream, uri.ToString())); } return(null); }
// Token: 0x0600017F RID: 383 RVA: 0x00007068 File Offset: 0x00005268 private ViewCompilerWorkItem CreatePrecompiledWorkItem(string normalizedPath, CompiledViewDescriptor precompiledView) { if (precompiledView.Item == null || !ChecksumValidator.IsRecompilationSupported(precompiledView.Item)) { return(new ViewCompilerWorkItem { SupportsCompilation = false, ExpirationTokens = Array.Empty <IChangeToken>(), Descriptor = precompiledView }); } ViewCompilerWorkItem viewCompilerWorkItem = new ViewCompilerWorkItem { SupportsCompilation = true, Descriptor = precompiledView, NormalizedPath = normalizedPath, ExpirationTokens = new List <IChangeToken>() }; IReadOnlyList <IRazorSourceChecksumMetadata> checksumMetadata = RazorCompiledItemExtensions.GetChecksumMetadata(precompiledView.Item); for (int i = 0; i < checksumMetadata.Count; i++) { viewCompilerWorkItem.ExpirationTokens.Add(this._fileProvider.Watch(checksumMetadata[i].Identifier)); } viewCompilerWorkItem.Descriptor = new CompiledViewDescriptor { ExpirationTokens = viewCompilerWorkItem.ExpirationTokens, IsPrecompiled = true, Item = precompiledView.Item, RelativePath = precompiledView.RelativePath, ViewAttribute = precompiledView.ViewAttribute }; return(viewCompilerWorkItem); }
// Token: 0x0600017E RID: 382 RVA: 0x00006EDC File Offset: 0x000050DC private Task <CompiledViewDescriptor> OnCacheMiss(string normalizedPath) { object cacheLock = this._cacheLock; ViewCompilerWorkItem viewCompilerWorkItem; MemoryCacheEntryOptions memoryCacheEntryOptions; TaskCompletionSource <CompiledViewDescriptor> taskCompletionSource; lock (cacheLock) { Task <CompiledViewDescriptor> result; if (CacheExtensions.TryGetValue <Task <CompiledViewDescriptor> >(this._cache, normalizedPath, out result)) { return(result); } CompiledViewDescriptor precompiledView; if (this._precompiledViews.TryGetValue(normalizedPath, out precompiledView)) { this._logger.ViewCompilerLocatedCompiledViewForPath(normalizedPath); viewCompilerWorkItem = this.CreatePrecompiledWorkItem(normalizedPath, precompiledView); } else { viewCompilerWorkItem = this.CreateRuntimeCompilationWorkItem(normalizedPath); } memoryCacheEntryOptions = new MemoryCacheEntryOptions(); for (int i = 0; i < viewCompilerWorkItem.ExpirationTokens.Count; i++) { memoryCacheEntryOptions.ExpirationTokens.Add(viewCompilerWorkItem.ExpirationTokens[i]); } taskCompletionSource = new TaskCompletionSource <CompiledViewDescriptor>(); if (!viewCompilerWorkItem.SupportsCompilation) { taskCompletionSource.SetResult(viewCompilerWorkItem.Descriptor); } _cacheKeyList.Add(normalizedPath); CacheExtensions.Set <Task <CompiledViewDescriptor> >(this._cache, normalizedPath, taskCompletionSource.Task, memoryCacheEntryOptions); } if (viewCompilerWorkItem.SupportsCompilation) { CompiledViewDescriptor descriptor = viewCompilerWorkItem.Descriptor; if (((descriptor != null) ? descriptor.Item : null) != null && ChecksumValidator.IsItemValid(this._projectEngine.FileSystem, viewCompilerWorkItem.Descriptor.Item)) { taskCompletionSource.SetResult(viewCompilerWorkItem.Descriptor); return(taskCompletionSource.Task); } this._logger.ViewCompilerInvalidingCompiledFile(viewCompilerWorkItem.NormalizedPath); try { CompiledViewDescriptor compiledViewDescriptor = this.CompileAndEmit(normalizedPath); compiledViewDescriptor.ExpirationTokens = memoryCacheEntryOptions.ExpirationTokens; taskCompletionSource.SetResult(compiledViewDescriptor); } catch (Exception exception) { taskCompletionSource.SetException(exception); } } return(taskCompletionSource.Task); }
public void GivenNoChecksum_Validate_ReturnsFalse() { var message = new TestFixMessageBuilder(TestFixMessageBuilder.DefaultBody).AddChecksum("3").Build(); var uut = new ChecksumValidator(IntegerToFixConverter.Instance); var msgContext = new FixMessageContext().Setup(message); var result = uut.IsValid(message.AsSpan(), msgContext); Assert.False(result); }
public void IsRecompilationSupported_NoChecksumAttributes_ReturnsFalse() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { }); // Act var result = ChecksumValidator.IsRecompilationSupported(item); // Assert Assert.False(result); }
public void IsItemValid_NoChecksumAttributes_ReturnsTrue() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { }); // Act var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item); // Assert Assert.True(result); }
public void StartPlayback() { _recording = false; if (_recorderView != null) { _recorderView.StartPlayback(); } _checksumValidator = new ChecksumValidatorBasic(); }
public void GivenCorrectChecksum_Validate_ReturnsTrue(string input) { byte[] message = new TestFixMessageBuilder(input).Build(out byte checksumValue, out int checksumStart); var uut = new ChecksumValidator(IntegerToFixConverter.Instance); var msgContext = new FixMessageContext() { ChecksumValue = checksumValue, ChecksumTagStartIndex = checksumStart }; var result = uut.IsValid(message.AsSpan(), msgContext); Assert.True(result); }
public void IsRecompilationSupported_NoPrimaryChecksumAttribute_ReturnsFalse() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), }); // Act var result = ChecksumValidator.IsRecompilationSupported(item); // Assert Assert.False(result); }
public void IsItemValid_NoPrimaryChecksumAttribute_ReturnsTrue() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/About.cstml"), }); // Act var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item); // Assert Assert.True(result); }
public void IsItemValid_PrimaryFileDoesNotExist_ReturnsTrue() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"), }); ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "dkdkfkdf")); // This will be ignored // Act var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item); // Assert Assert.True(result); }
private void CreateModels(PageRouteModelProviderContext context) { var rootDirectory = _pagesOptions.RootDirectory; if (!rootDirectory.EndsWith("/", StringComparison.Ordinal)) { rootDirectory = rootDirectory + "/"; } var areaRootDirectory = _pagesOptions.AreaRootDirectory; if (!areaRootDirectory.EndsWith("/", StringComparison.Ordinal)) { areaRootDirectory = areaRootDirectory + "/"; } foreach (var viewDescriptor in GetViewDescriptors(_applicationManager)) { if (viewDescriptor.Item != null && !ChecksumValidator.IsItemValid(_razorProjectEngine.FileSystem, viewDescriptor.Item)) { // If we get here, this compiled Page has different local content, so ignore it. continue; } var relativePath = viewDescriptor.RelativePath; var routeTemplate = GetRouteTemplate(viewDescriptor); PageRouteModel routeModel = null; // When RootDirectory and AreaRootDirectory overlap (e.g. RootDirectory = '/', AreaRootDirectory = '/Areas'), we // only want to allow a page to be associated with the area route. if (_pagesOptions.AllowAreas && relativePath.StartsWith(areaRootDirectory, StringComparison.OrdinalIgnoreCase)) { routeModel = _routeModelFactory.CreateAreaRouteModel(relativePath, routeTemplate); } else if (relativePath.StartsWith(rootDirectory, StringComparison.OrdinalIgnoreCase)) { routeModel = _routeModelFactory.CreateRouteModel(relativePath, routeTemplate); } if (routeModel != null) { context.RouteModels.Add(routeModel); } } }
private ViewCompilerWorkItem CreatePrecompiledWorkItem(string normalizedPath, CompiledViewDescriptor precompiledView) { // We have a precompiled view - but we're not sure that we can use it yet. // // We need to determine first if we have enough information to 'recompile' this view. If that's the case // we'll create change tokens for all of the files. // // Then we'll attempt to validate if any of those files have different content than the original sources // based on checksums. if (precompiledView.Item == null || !ChecksumValidator.IsRecompilationSupported(precompiledView.Item)) { return(new ViewCompilerWorkItem() { // If we don't have a checksum for the primary source file we can't recompile. SupportsCompilation = false, ExpirationTokens = Array.Empty <IChangeToken>(), // Never expire because we can't recompile. Descriptor = precompiledView, // This will be used as-is. }); } var item = new ViewCompilerWorkItem() { SupportsCompilation = true, Descriptor = precompiledView, // This might be used, if the checksums match. // Used to validate and recompile NormalizedPath = normalizedPath, ExpirationTokens = GetExpirationTokens(precompiledView), }; // We also need to create a new descriptor, because the original one doesn't have expiration tokens on // it. These will be used by the view location cache, which is like an L1 cache for views (this class is // the L2 cache). item.Descriptor = new CompiledViewDescriptor() { ExpirationTokens = item.ExpirationTokens, Item = precompiledView.Item, RelativePath = precompiledView.RelativePath, }; return(item); }
public void IsItemValid_ImportFileExistsButDoesNotMatch_ReturnsFalse() { // Arrange var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"), new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"), }); ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/Index.cstml", "some content")); ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "some other import")); // Act var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item); // Assert Assert.False(result); }
private void CreateModels(IList <PageRouteModel> results) { var rootDirectory = _pagesOptions.RootDirectory; if (!rootDirectory.EndsWith("/", StringComparison.Ordinal)) { rootDirectory = rootDirectory + "/"; } var areaRootDirectory = _pagesOptions.AreaRootDirectory; if (!areaRootDirectory.EndsWith("/", StringComparison.Ordinal)) { areaRootDirectory = areaRootDirectory + "/"; } foreach (var viewDescriptor in GetViewDescriptors(_applicationManager)) { if (viewDescriptor.Item != null && !ChecksumValidator.IsItemValid(_templateEngine.Project, viewDescriptor.Item)) { // If we get here, this compiled Page has different local content, so ignore it. continue; } PageRouteModel model = null; // When RootDirectory and AreaRootDirectory overlap (e.g. RootDirectory = '/', AreaRootDirectory = '/Areas'), we // only want to allow a page to be associated with the area route. if (_pagesOptions.AllowAreas && viewDescriptor.RelativePath.StartsWith(areaRootDirectory, StringComparison.OrdinalIgnoreCase)) { model = GetAreaPageRouteModel(areaRootDirectory, viewDescriptor); } else if (viewDescriptor.RelativePath.StartsWith(rootDirectory, StringComparison.OrdinalIgnoreCase)) { model = GetPageRouteModel(rootDirectory, viewDescriptor); } if (model != null) { results.Add(model); } } }
private ViewCompilerWorkItem CreatePrecompiledWorkItem(string normalizedPath, CompiledViewDescriptor precompiledView) { if (precompiledView.Item == null || !ChecksumValidator.IsRecompilationSupported(precompiledView.Item)) { return(new ViewCompilerWorkItem() { SupportsCompilation = false, ExpirationTokens = Array.Empty <IChangeToken>(), Descriptor = precompiledView, }); } var item = new ViewCompilerWorkItem() { SupportsCompilation = true, Descriptor = precompiledView, NormalizedPath = normalizedPath, ExpirationTokens = new List <IChangeToken>(), }; var checksums = precompiledView.Item.GetChecksumMetadata(); for (var i = 0; i < checksums.Count; i++) { item.ExpirationTokens.Add(_fileProvider.Watch(checksums[i].Identifier)); } item.Descriptor = new CompiledViewDescriptor() { ExpirationTokens = item.ExpirationTokens, IsPrecompiled = true, Item = precompiledView.Item, RelativePath = precompiledView.RelativePath, ViewAttribute = precompiledView.ViewAttribute, }; return(item); }
private Task <CompiledViewDescriptor> OnCacheMiss(string normalizedPath) { ViewCompilerWorkItem item; TaskCompletionSource <CompiledViewDescriptor> taskSource; MemoryCacheEntryOptions cacheEntryOptions; // Safe races cannot be allowed when compiling Razor pages. To ensure only one compilation request succeeds // per file, we'll lock the creation of a cache entry. Creating the cache entry should be very quick. The // actual work for compiling files happens outside the critical section. lock (_cacheLock) { // Double-checked locking to handle a possible race. if (_cache.TryGetValue(normalizedPath, out Task <CompiledViewDescriptor> result)) { return(result); } if (_precompiledViews.TryGetValue(normalizedPath, out var precompiledView)) { Log.ViewCompilerLocatedCompiledViewForPath(_logger, normalizedPath); item = CreatePrecompiledWorkItem(normalizedPath, precompiledView); } else { item = CreateRuntimeCompilationWorkItem(normalizedPath); } // At this point, we've decided what to do - but we should create the cache entry and // release the lock first. cacheEntryOptions = new MemoryCacheEntryOptions(); Debug.Assert(item.ExpirationTokens != null); for (var i = 0; i < item.ExpirationTokens.Count; i++) { cacheEntryOptions.ExpirationTokens.Add(item.ExpirationTokens[i]); } taskSource = new TaskCompletionSource <CompiledViewDescriptor>(creationOptions: TaskCreationOptions.RunContinuationsAsynchronously); if (item.SupportsCompilation) { // We'll compile in just a sec, be patient. } else { // If we can't compile, we should have already created the descriptor Debug.Assert(item.Descriptor != null); taskSource.SetResult(item.Descriptor); } _cache.Set(normalizedPath, taskSource.Task, cacheEntryOptions); } // Now the lock has been released so we can do more expensive processing. if (item.SupportsCompilation) { Debug.Assert(taskSource != null); if (item.Descriptor?.Item != null && ChecksumValidator.IsItemValid(_projectEngine.FileSystem, item.Descriptor.Item)) { // If the item has checksums to validate, we should also have a precompiled view. Debug.Assert(item.Descriptor != null); taskSource.SetResult(item.Descriptor); return(taskSource.Task); } Log.ViewCompilerInvalidatingCompiledFile(_logger, item.NormalizedPath); try { var descriptor = CompileAndEmit(normalizedPath); descriptor.ExpirationTokens = cacheEntryOptions.ExpirationTokens; taskSource.SetResult(descriptor); } catch (Exception ex) { taskSource.SetException(ex); } } return(taskSource.Task); }
private Task <CompiledViewDescriptor> OnCacheMiss(string normalizedPath) { ViewCompilerWorkItem item; TaskCompletionSource <CompiledViewDescriptor> taskSource; MemoryCacheEntryOptions cacheEntryOptions; lock (_cacheLock) { if (_cache.TryGetValue(normalizedPath, out Task <CompiledViewDescriptor> result)) { return(result); } if (_precompiledViews.TryGetValue(normalizedPath, out var precompiledView)) { _logger.ViewCompilerLocatedCompiledViewForPath(normalizedPath); item = CreatePrecompiledWorkItem(normalizedPath, precompiledView); } else { item = CreateRuntimeCompilationWorkItem(normalizedPath); } cacheEntryOptions = new MemoryCacheEntryOptions(); Debug.Assert(item.ExpirationTokens != null); for (var i = 0; i < item.ExpirationTokens.Count; i++) { cacheEntryOptions.ExpirationTokens.Add(item.ExpirationTokens[i]); } taskSource = new TaskCompletionSource <CompiledViewDescriptor>(); if (item.SupportsCompilation) { } else { Debug.Assert(item.Descriptor != null); taskSource.SetResult(item.Descriptor); } _cache.Set(normalizedPath, taskSource.Task, cacheEntryOptions); } if (item.SupportsCompilation) { Debug.Assert(taskSource != null); if (item.Descriptor?.Item != null && ChecksumValidator.IsItemValid(_projectEngine.FileSystem, item.Descriptor.Item)) { Debug.Assert(item.Descriptor != null); taskSource.SetResult(item.Descriptor); return(taskSource.Task); } _logger.ViewCompilerInvalidingCompiledFile(item.NormalizedPath); try { var descriptor = CompileAndEmit(normalizedPath); descriptor.ExpirationTokens = cacheEntryOptions.ExpirationTokens; taskSource.SetResult(descriptor); } catch (Exception ex) { taskSource.SetException(ex); } } return(taskSource.Task); }