public void CreateFileChangeToken_DoesNotAllowPathsAboveRoot() { using (var root = new DisposableFileSystem()) using (var fileSystemWatcher = new MockFileSystemWatcher(root.RootPath)) using (var physicalFilesWatcher = new PhysicalFilesWatcher(root.RootPath + Path.DirectorySeparatorChar, fileSystemWatcher, pollForChanges: false)) { var token = physicalFilesWatcher.CreateFileChangeToken(Path.GetFullPath(Path.Combine(root.RootPath, ".."))); Assert.IsType <NullChangeToken>(token); token = physicalFilesWatcher.CreateFileChangeToken(Path.GetFullPath(Path.Combine(root.RootPath, "../"))); Assert.IsType <NullChangeToken>(token); token = physicalFilesWatcher.CreateFileChangeToken(".."); Assert.IsType <NullChangeToken>(token); } }
public string GetFileVersionHash(string physicalPath) { if (physicalPath == null) { throw new ArgumentNullException(nameof(physicalPath)); } string result = null; if (File.Exists(physicalPath)) { var cacheKey = CacheKey.With(GetType(), "GetVersion", physicalPath); result = _platformMemoryCache.GetOrCreateExclusive(cacheKey, cacheEntry => { cacheEntry.AddExpirationToken(_fileSystemWatcher.CreateFileChangeToken(GetRelativePath(physicalPath))); using (var stream = File.OpenRead(physicalPath)) { using (var hashAlgorithm = CryptoConfig.AllowOnlyFipsAlgorithms ? (SHA256) new SHA256CryptoServiceProvider() : new SHA256Managed()) { return($"{WebEncoders.Base64UrlEncode(hashAlgorithm.ComputeHash(stream))}"); } } }); } return(result); }
public IChangeToken Watch(string filter) { if (filter == null) { return(NoopChangeToken.Singleton); } if (PathNavigatesAboveRoot(filter)) { return(NoopChangeToken.Singleton); } // Relative paths starting with a leading slash okay if (filter.StartsWith("/", StringComparison.Ordinal)) { filter = filter.Substring(1); } // Absolute paths not permitted. if (Path.IsPathRooted(filter)) { return(NoopChangeToken.Singleton); } return(_filesWatcher.CreateFileChangeToken(filter)); }
public IChangeToken Watch(string filter) { if (filter == null || PathUtils.HasInvalidFilterChars(filter)) { return(NullChangeToken.Singleton); } filter = filter.TrimStart(_pathSeparators); return(_filesWatcher.CreateFileChangeToken(filter)); }
/// <summary> /// <para>Creates a <see cref="IChangeToken" /> for the specified <paramref name="filter" />.</para> /// <para>Globbing patterns are interpreted by <seealso cref="Microsoft.Extensions.FileSystemGlobbing.Matcher" />.</para> /// </summary> /// <param name="filter"> /// Filter string used to determine what files or folders to monitor. Example: **/*.cs, *.*, /// subFolder/**/*.cshtml. /// </param> /// <returns> /// An <see cref="IChangeToken" /> that is notified when a file matching <paramref name="filter" /> is added, /// modified or deleted. Returns a <see cref="NullChangeToken" /> if <paramref name="filter" /> has invalid filter /// characters or if <paramref name="filter" /> is an absolute path or outside the root directory specified in the /// constructor <seealso cref="PhysicalFileProvider(string)" />. /// </returns> public IChangeToken Watch(string filter) { if (filter == null || PathUtils.HasInvalidFilterChars(filter)) { return(NullChangeToken.Singleton); } // Relative paths starting with leading slashes are okay filter = filter.TrimStart(_pathSeparators); return(_filesWatcher.CreateFileChangeToken(filter)); }
public virtual IChangeToken Watch(string path) { //TODO: Test with symbolic links if (_fileSystemWatcher != null) { return(_fileSystemWatcher.CreateFileChangeToken(path)); } else { return(new CancellationChangeToken(new CancellationToken())); } }
public virtual IChangeToken Watch(string path) { //TODO: Test with symbolic links if (_fileSystemWatcher != null) { // Absolute paths not permitted for watcher, need to convert it to relative if (Path.IsPathRooted(path)) { path = GetRelativePath(path).TrimStart('/'); } return(_fileSystemWatcher.CreateFileChangeToken(path)); } else { return(new CancellationChangeToken(new CancellationToken())); } }
/// <summary> /// <para>Creates a <see cref="IChangeToken" /> for the specified <paramref name="filter" />.</para> /// <para>Globbing patterns are interpreted by <seealso cref="HD.Configuration.FileExtensions.Matcher" />.</para> /// </summary> /// <param name="filter"> /// Filter string used to determine what files or folders to monitor. Example: **/*.cs, *.*, /// subFolder/**/*.cshtml. /// </param> /// <returns> /// An <see cref="IChangeToken" /> that is notified when a file matching <paramref name="filter" /> is added, /// modified or deleted. Returns a <see cref="NullChangeToken" /> if <paramref name="filter" /> has invalid filter /// characters or if <paramref name="filter" /> is an absolute path or outside the root directory specified in the /// constructor <seealso cref="PhysicalFileProvider(string)" />. /// </returns> public IChangeToken Watch(string filter) { if (filter == null || HasInvalidFilterChars(filter)) { return(NullChangeToken.Singleton); } // Relative paths starting with leading slashes are okay filter = filter.TrimStart(_pathSeparators); // Absolute paths and paths traversing above root not permitted. if (Path.IsPathRooted(filter) || PathNavigatesAboveRoot(filter)) { return(NullChangeToken.Singleton); } return(_filesWatcher.CreateFileChangeToken(filter)); }
public async Task HandlesOnRenamedEventsThatMatchRootPath() { using (var root = new DisposableFileSystem()) using (var fileSystemWatcher = new MockFileSystemWatcher(root.RootPath)) using (var physicalFilesWatcher = new PhysicalFilesWatcher(root.RootPath + Path.DirectorySeparatorChar, fileSystemWatcher, pollForChanges: false)) { var token = physicalFilesWatcher.CreateFileChangeToken("**"); var called = false; token.RegisterChangeCallback(o => called = true, null); fileSystemWatcher.CallOnRenamed(new RenamedEventArgs(WatcherChangeTypes.Renamed, root.RootPath, string.Empty, string.Empty)); await Task.Delay(WaitTimeForTokenToFire).ConfigureAwait(false); Assert.False(called, "Callback should not have been triggered"); fileSystemWatcher.CallOnRenamed(new RenamedEventArgs(WatcherChangeTypes.Renamed, root.RootPath, "old.txt", "new.txt")); await Task.Delay(WaitTimeForTokenToFire).ConfigureAwait(false); Assert.True(called, "Callback should have been triggered"); } }