diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs index 658a47bbeb6f56..827e092eb7e704 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs @@ -34,6 +34,18 @@ public PhysicalDirectoryContents(string directory, Microsoft.Extensions.FileProv } namespace Microsoft.Extensions.FileProviders.Physical { + public partial class ExcludedFileInfo : Microsoft.Extensions.FileProviders.IFileInfo + { + public ExcludedFileInfo(System.IO.FileInfo info, ExclusionFilters matchingFilter) { } + public Microsoft.Extensions.FileProviders.Physical.ExclusionFilters MatchingFilter { get { throw null; } } + public bool Exists { get { throw null; } } + public bool IsDirectory { get { throw null; } } + public System.DateTimeOffset LastModified { get { throw null; } } + public long Length { get { throw null; } } + public string Name { get { throw null; } } + public string PhysicalPath { get { throw null; } } + public System.IO.Stream CreateReadStream() { throw null; } + } [System.FlagsAttribute] public enum ExclusionFilters { @@ -43,6 +55,11 @@ public enum ExclusionFilters System = 4, Sensitive = 7, } + public partial class FileExcludedException : System.Exception + { + public FileExcludedException(string message, ExclusionFilters matchingFilter) { } + public Microsoft.Extensions.FileProviders.Physical.ExclusionFilters MatchingFilter { get { throw null; } } + } public partial class PhysicalDirectoryInfo : Microsoft.Extensions.FileProviders.IFileInfo { public PhysicalDirectoryInfo(System.IO.DirectoryInfo info) { } diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/ExcludedFileInfo.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/ExcludedFileInfo.cs new file mode 100644 index 00000000000000..eaf944c2e44c68 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/ExcludedFileInfo.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; + +namespace Microsoft.Extensions.FileProviders.Physical +{ + public class ExcludedFileInfo : IFileInfo + { + private readonly FileInfo _info; + + /// + /// Initializes an instance of . + /// + /// The of the file that could was excluded. + /// The the file matched with. + public ExcludedFileInfo(FileInfo info, ExclusionFilters matchingFilter) + { + _info = info; + MatchingFilter = matchingFilter; + } + + /// + /// The the file matched with. + /// + public ExclusionFilters MatchingFilter { get; } + + /// + public bool Exists => _info.Exists; + + /// + public long Length => _info.Length; + + /// + public string PhysicalPath => _info.FullName; + + /// + public string Name => _info.Name; + + /// + public DateTimeOffset LastModified => _info.LastWriteTimeUtc; + + /// + /// Always false. + /// + public bool IsDirectory => false; + + /// + /// Always throws. A stream cannot be created for non-existing file. + /// + /// Always thrown. + /// Does not return + public Stream CreateReadStream() + { + throw new FileExcludedException(SR.Format(SR.FileExcluded, Name), MatchingFilter); + } + } +} diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/FileExcludedException.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/FileExcludedException.cs new file mode 100644 index 00000000000000..022c7fa81bf8cb --- /dev/null +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/FileExcludedException.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Extensions.FileProviders.Physical +{ + public class FileExcludedException : Exception + { + public ExclusionFilters MatchingFilter { get; } + + public FileExcludedException(string message, ExclusionFilters matchingFilter) + : base(message) + { + MatchingFilter = matchingFilter; + } + } +} diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs index 067a1545860e2a..a267d5c5f2ab57 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs @@ -8,24 +8,37 @@ namespace Microsoft.Extensions.FileProviders.Physical { internal static class FileSystemInfoHelper { - public static bool IsExcluded(FileSystemInfo fileSystemInfo, ExclusionFilters filters) + public static bool IsExcluded(FileSystemInfo fileSystemInfo, ExclusionFilters filters) => + FindMatchingExclusionFilter(fileSystemInfo, filters) != ExclusionFilters.None; + + public static ExclusionFilters FindMatchingExclusionFilter(FileSystemInfo fileSystemInfo, ExclusionFilters filters) { if (filters == ExclusionFilters.None) { - return false; + return ExclusionFilters.None; } - else if (fileSystemInfo.Name.StartsWith(".", StringComparison.Ordinal) && (filters & ExclusionFilters.DotPrefixed) != 0) + + if (fileSystemInfo.Name.StartsWith(".", StringComparison.Ordinal) && (filters & ExclusionFilters.DotPrefixed) != 0) { - return true; + return ExclusionFilters.DotPrefixed; } - else if (fileSystemInfo.Exists && - (((fileSystemInfo.Attributes & FileAttributes.Hidden) != 0 && (filters & ExclusionFilters.Hidden) != 0) || - ((fileSystemInfo.Attributes & FileAttributes.System) != 0 && (filters & ExclusionFilters.System) != 0))) + + if (fileSystemInfo.Exists) { - return true; + if ((fileSystemInfo.Attributes & FileAttributes.Hidden) != 0 && + (filters & ExclusionFilters.Hidden) != 0) + { + return ExclusionFilters.Hidden; + } + + if ((fileSystemInfo.Attributes & FileAttributes.System) != 0 && + (filters & ExclusionFilters.System) != 0) + { + return ExclusionFilters.System; + } } - return false; + return ExclusionFilters.None; } } } diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs index 4238fff652eb7a..16caa1910288b5 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs @@ -266,9 +266,10 @@ public IFileInfo GetFileInfo(string subpath) } var fileInfo = new FileInfo(fullPath); - if (FileSystemInfoHelper.IsExcluded(fileInfo, _filters)) + var matchingExclusion = FileSystemInfoHelper.FindMatchingExclusionFilter(fileInfo, _filters); + if (matchingExclusion != ExclusionFilters.None) { - return new NotFoundFileInfo(subpath); + return new ExcludedFileInfo(fileInfo, matchingExclusion); } return new PhysicalFileInfo(fileInfo); diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx index 4d234ccabe2024..20c369aa5ba0a7 100644 --- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx @@ -129,4 +129,7 @@ Unexpected type of FileSystemInfo + + The file {0} has been excluded. + \ No newline at end of file