using EmbedIO.Utilities; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Threading; namespace EmbedIO.Files { /// /// Provides access to files contained in a .zip file to a . /// /// public class ZipFileProvider : IDisposable, IFileProvider { private readonly ZipArchive _zipArchive; /// /// Initializes a new instance of the class. /// /// The zip file path. public ZipFileProvider(string zipFilePath) : this(new FileStream(Validate.LocalPath(nameof(zipFilePath), zipFilePath, true), FileMode.Open)) { } /// /// Initializes a new instance of the class. /// /// The stream that contains the archive. /// to leave the stream open after the web server /// is disposed; otherwise, . public ZipFileProvider(Stream stream, bool leaveOpen = false) { _zipArchive = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen); } /// /// Finalizes an instance of the class. /// ~ZipFileProvider() { Dispose(false); } /// public event Action ResourceChanged { add { } remove { } } /// public bool IsImmutable => true; /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// public void Start(CancellationToken cancellationToken) { } /// public MappedResourceInfo? MapUrlPath(string urlPath, IMimeTypeProvider mimeTypeProvider) { if (urlPath.Length == 1) return null; urlPath = Uri.UnescapeDataString(urlPath); var entry = _zipArchive.GetEntry(urlPath.Substring(1)); if (entry == null) return null; return MappedResourceInfo.ForFile( entry.FullName, entry.Name, entry.LastWriteTime.DateTime, entry.Length, mimeTypeProvider.GetMimeType(Path.GetExtension(entry.Name))); } /// public Stream OpenFile(string path) => _zipArchive.GetEntry(path)?.Open() ?? throw new FileNotFoundException($"\"{path}\" cannot be found in Zip archive."); /// public IEnumerable GetDirectoryEntries(string path, IMimeTypeProvider mimeTypeProvider) => Enumerable.Empty(); /// /// Releases unmanaged and - optionally - managed resources. /// /// to release both managed and unmanaged resources; /// to release only unmanaged resources. protected virtual void Dispose(bool disposing) { if (!disposing) return; _zipArchive.Dispose(); } } }