using System.Collections.Generic; using System.IO; using WireMock.Util; using Stef.Validation; namespace WireMock.Handlers; /// /// Default implementation for a handler to interact with the local file system to read and write static mapping files. /// public class LocalFileSystemHandler : IFileSystemHandler { private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings"); private static readonly string UnmatchedRequestsFolder = Path.Combine("requests", "unmatched"); private readonly string _rootFolder; /// /// Initializes a new instance of the class. /// public LocalFileSystemHandler() : this(Directory.GetCurrentDirectory()) { } /// /// Initializes a new instance of the class. /// /// The root folder. public LocalFileSystemHandler(string rootFolder) { _rootFolder = rootFolder; } /// public virtual bool FolderExists(string path) { Guard.NotNullOrEmpty(path); return Directory.Exists(path); } /// public virtual void CreateFolder(string path) { Guard.NotNullOrEmpty(path); Directory.CreateDirectory(path); } /// public virtual IEnumerable EnumerateFiles(string path, bool includeSubdirectories) { Guard.NotNullOrEmpty(path); return includeSubdirectories ? Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) : Directory.EnumerateFiles(path); } /// public virtual string GetMappingFolder() { return Path.Combine(_rootFolder, AdminMappingsFolder); } /// public virtual string ReadMappingFile(string path) { Guard.NotNullOrEmpty(path); return File.ReadAllText(path); } /// public virtual void WriteMappingFile(string path, string text) { Guard.NotNullOrEmpty(path, nameof(path)); Guard.NotNull(text, nameof(text)); File.WriteAllText(path, text); } /// public virtual byte[] ReadResponseBodyAsFile(string path) { Guard.NotNullOrEmpty(path); path = PathUtils.CleanPath(path)!; // If the file exists at the given path relative to the MappingsFolder, then return that. // Else the path will just be as-is. return File.ReadAllBytes(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path); } /// public virtual string ReadResponseBodyAsString(string path) { Guard.NotNullOrEmpty(path); path = PathUtils.CleanPath(path)!; // In case the path is a filename, the path will be adjusted to the MappingFolder. // Else the path will just be as-is. return File.ReadAllText(File.Exists(PathUtils.Combine(GetMappingFolder(), path)) ? PathUtils.Combine(GetMappingFolder(), path) : path); } /// public virtual bool FileExists(string filename) { Guard.NotNullOrEmpty(filename); return File.Exists(AdjustPathForMappingFolder(filename)); } /// public virtual void WriteFile(string filename, byte[] bytes) { Guard.NotNullOrEmpty(filename); Guard.NotNull(bytes); File.WriteAllBytes(AdjustPathForMappingFolder(filename), bytes); } /// public virtual void WriteFile(string folder, string filename, byte[] bytes) { Guard.NotNullOrEmpty(folder); Guard.NotNullOrEmpty(filename); Guard.NotNull(bytes); File.WriteAllBytes(PathUtils.Combine(folder, filename), bytes); } /// public virtual void DeleteFile(string filename) { Guard.NotNullOrEmpty(filename); File.Delete(AdjustPathForMappingFolder(filename)); } /// public virtual byte[] ReadFile(string filename) { Guard.NotNullOrEmpty(filename); return File.ReadAllBytes(AdjustPathForMappingFolder(filename)); } /// public virtual string ReadFileAsString(string filename) { return File.ReadAllText(AdjustPathForMappingFolder(Guard.NotNullOrEmpty(filename, nameof(filename)))); } /// public virtual string GetUnmatchedRequestsFolder() { return Path.Combine(_rootFolder, UnmatchedRequestsFolder); } /// public virtual void WriteUnmatchedRequest(string filename, string text) { Guard.NotNullOrEmpty(filename); Guard.NotNull(text); var folder = GetUnmatchedRequestsFolder(); if (!FolderExists(folder)) { CreateFolder(folder); } File.WriteAllText(Path.Combine(folder, filename), text); } /// /// Adjusts the path to the MappingFolder. /// /// The path. /// Adjusted path private string AdjustPathForMappingFolder(string filename) { return Path.Combine(GetMappingFolder(), filename); } }