From 635e206e0374860d6536983bf20bb24cee5f5621 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Thu, 18 Jul 2013 16:36:49 -0700 Subject: [PATCH] replaced our zip library so we can validate update package before applying. --- NzbDrone.Common/ArchiveProvider.cs | 74 ++++++++++++++++--- NzbDrone.Common/NzbDrone.Common.csproj | 4 +- NzbDrone.Common/packages.config | 2 +- NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 2 +- ...veFixture.cs => ArchiveProviderFixture.cs} | 6 +- .../UpdateTests/UpdateServiceFixture.cs | 10 +-- NzbDrone.Core/NzbDrone.Core.csproj | 6 -- NzbDrone.Core/Providers/BackupProvider.cs | 36 --------- NzbDrone.Core/Update/InstallUpdateService.cs | 8 +- NzbDrone.Core/packages.config | 1 - .../UpdateEngine/TerminateNzbDrone.cs | 8 +- 11 files changed, 82 insertions(+), 75 deletions(-) rename NzbDrone.Core.Test/ProviderTests/DiskProviderTests/{ExtractArchiveFixture.cs => ArchiveProviderFixture.cs} (79%) delete mode 100644 NzbDrone.Core/Providers/BackupProvider.cs diff --git a/NzbDrone.Common/ArchiveProvider.cs b/NzbDrone.Common/ArchiveProvider.cs index 3cac6f464..629d3c6bb 100644 --- a/NzbDrone.Common/ArchiveProvider.cs +++ b/NzbDrone.Common/ArchiveProvider.cs @@ -1,23 +1,79 @@ -using System.Linq; -using Ionic.Zip; +using System; +using System.IO; +using ICSharpCode.SharpZipLib.Core; +using ICSharpCode.SharpZipLib.Zip; using NLog; namespace NzbDrone.Common { - public class ArchiveProvider + public interface IArchiveService { - private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + void Extract(string compressedFile, string destination); + } - public virtual void ExtractArchive(string compressedFile, string destination) + public class ArchiveService : IArchiveService + { + private readonly Logger _logger; + + public ArchiveService(Logger logger) { - logger.Trace("Extracting archive [{0}] to [{1}]", compressedFile, destination); + _logger = logger; + } - using (var zipFile = ZipFile.Read(compressedFile)) + public void Extract(string compressedFile, string destination) + { + _logger.Trace("Extracting archive [{0}] to [{1}]", compressedFile, destination); + + using (var fileStream = File.OpenRead(compressedFile)) { - zipFile.ExtractAll(destination); + var zipFile = new ZipFile(fileStream); + + _logger.Debug("Validating Archive {0}", compressedFile); + + if (!zipFile.TestArchive(true, TestStrategy.FindFirstError, OnZipError)) + { + throw new IOException(string.Format("File {0} failed archive validation.", compressedFile)); + } + + foreach (ZipEntry zipEntry in zipFile) + { + if (!zipEntry.IsFile) + { + continue; // Ignore directories + } + String entryFileName = zipEntry.Name; + // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); + // Optionally match entrynames against a selection list here to skip as desired. + // The unpacked length is available in the zipEntry.Size property. + + byte[] buffer = new byte[4096]; // 4K is optimum + Stream zipStream = zipFile.GetInputStream(zipEntry); + + // Manipulate the output filename here as desired. + String fullZipToPath = Path.Combine(destination, entryFileName); + string directoryName = Path.GetDirectoryName(fullZipToPath); + if (directoryName.Length > 0) + Directory.CreateDirectory(directoryName); + + // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size + // of the file, but does not waste memory. + // The "using" will close the stream even if an exception occurs. + using (FileStream streamWriter = File.Create(fullZipToPath)) + { + StreamUtils.Copy(zipStream, streamWriter, buffer); + } + } } - logger.Trace("Extraction complete."); + _logger.Trace("Extraction complete."); + } + + private void OnZipError(TestStatus status, string message) + { + if (!string.IsNullOrWhiteSpace(message)) + { + _logger.Error("File {0} failed zip validation. {1}", status.File.Name, message); + } } } } \ No newline at end of file diff --git a/NzbDrone.Common/NzbDrone.Common.csproj b/NzbDrone.Common/NzbDrone.Common.csproj index 5eb5847ed..d2f6d0062 100644 --- a/NzbDrone.Common/NzbDrone.Common.csproj +++ b/NzbDrone.Common/NzbDrone.Common.csproj @@ -55,8 +55,8 @@ MinimumRecommendedRules.ruleset - - ..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll + + ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll False diff --git a/NzbDrone.Common/packages.config b/NzbDrone.Common/packages.config index 90227afa3..9bc3a3d0d 100644 --- a/NzbDrone.Common/packages.config +++ b/NzbDrone.Common/packages.config @@ -1,7 +1,7 @@  - + \ No newline at end of file diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index e2d2f90cf..b521911c2 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -196,7 +196,7 @@ - + diff --git a/NzbDrone.Core.Test/ProviderTests/DiskProviderTests/ExtractArchiveFixture.cs b/NzbDrone.Core.Test/ProviderTests/DiskProviderTests/ArchiveProviderFixture.cs similarity index 79% rename from NzbDrone.Core.Test/ProviderTests/DiskProviderTests/ExtractArchiveFixture.cs rename to NzbDrone.Core.Test/ProviderTests/DiskProviderTests/ArchiveProviderFixture.cs index e6c5e43f4..9cf514eb1 100644 --- a/NzbDrone.Core.Test/ProviderTests/DiskProviderTests/ExtractArchiveFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/DiskProviderTests/ArchiveProviderFixture.cs @@ -1,19 +1,19 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Common; -using NzbDrone.Core.Test.Framework; using System.IO; +using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.ProviderTests.DiskProviderTests { [TestFixture] - public class ExtractArchiveFixture : CoreTest + public class ArchiveProviderFixture : TestBase { [Test] public void Should_extract_to_correct_folder() { var destination = Path.Combine(TempFolder, "destination"); - Mocker.Resolve().ExtractArchive(GetTestFilePath("TestArchive.zip"), destination); + Subject.Extract(GetTestFilePath("TestArchive.zip"), destination); var destinationFolder = new DirectoryInfo(destination); diff --git a/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs b/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs index bfaffa287..93330b543 100644 --- a/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs +++ b/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs @@ -22,9 +22,9 @@ public class UpdateServiceFixture : CoreTest private readonly UpdatePackage _updatePackage = new UpdatePackage { - FileName = "NzbDrone.vnext.0.8.1.226.zip", - Url = "http://update.nzbdrone.com/vnext/NzbDrone.vnext.0.8.1.226.zip", - Version = new Version("0.8.1.226") + FileName = "NzbDrone.vnext.0.8.1.385.zip", + Url = "http://update.nzbdrone.com/vnext/NzbDrone.vnext.0.8.1.385.zip", + Version = new Version("0.8.1.385") }; [SetUp] @@ -83,7 +83,7 @@ public void Should_extract_update_package() Subject.Execute(new ApplicationUpdateCommand()); - Mocker.GetMock().Verify(c => c.ExtractArchive(updateArchive, _sandboxFolder)); + Mocker.GetMock().Verify(c => c.Extract(updateArchive, _sandboxFolder)); } [Test] @@ -131,7 +131,7 @@ public void Should_download_and_extract_to_temp_folder() updateSubFolder.Exists.Should().BeFalse(); Mocker.Resolve(); - Mocker.Resolve(); + Mocker.SetConstant(Mocker.Resolve()); Subject.Execute(new ApplicationUpdateCommand()); diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 70600f2d9..e61968fbf 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -136,9 +136,6 @@ ..\packages\Growl.0.6\lib\Growl.CoreLibrary.dll - - ..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll - ..\packages\MediaInfoNet.0.3\lib\MediaInfoDotNet.dll @@ -431,9 +428,6 @@ - - Code - Code diff --git a/NzbDrone.Core/Providers/BackupProvider.cs b/NzbDrone.Core/Providers/BackupProvider.cs deleted file mode 100644 index e0083fa65..000000000 --- a/NzbDrone.Core/Providers/BackupProvider.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Linq; -using Ionic.Zip; -using NzbDrone.Common; -using NzbDrone.Common.EnvironmentInfo; - -namespace NzbDrone.Core.Providers -{ - public class BackupProvider - { - private readonly IAppFolderInfo _appFolderInfo; - - public BackupProvider(IAppFolderInfo appFolderInfo) - { - _appFolderInfo = appFolderInfo; - } - - public BackupProvider() - { - } - - public virtual string CreateBackupZip() - { - var configFile = _appFolderInfo.GetConfigPath(); - var zipFile = _appFolderInfo.GetConfigBackupFile(); - - using (var zip = new ZipFile()) - { - zip.AddFile(configFile, String.Empty); - zip.Save(zipFile); - } - - return zipFile; - } - } -} diff --git a/NzbDrone.Core/Update/InstallUpdateService.cs b/NzbDrone.Core/Update/InstallUpdateService.cs index 0c174cbf9..3ba9541c3 100644 --- a/NzbDrone.Core/Update/InstallUpdateService.cs +++ b/NzbDrone.Core/Update/InstallUpdateService.cs @@ -16,19 +16,19 @@ public class InstallUpdateService : IExecute private readonly IDiskProvider _diskProvider; private readonly IHttpProvider _httpProvider; - private readonly ArchiveProvider _archiveProvider; + private readonly IArchiveService _archiveService; private readonly IProcessProvider _processProvider; public InstallUpdateService(ICheckUpdateService checkUpdateService, IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IHttpProvider httpProvider, - ArchiveProvider archiveProvider, IProcessProvider processProvider, Logger logger) + IArchiveService archiveService, IProcessProvider processProvider, Logger logger) { _checkUpdateService = checkUpdateService; _appFolderInfo = appFolderInfo; _diskProvider = diskProvider; _httpProvider = httpProvider; - _archiveProvider = archiveProvider; + _archiveService = archiveService; _processProvider = processProvider; _logger = logger; } @@ -60,7 +60,7 @@ private void InstallUpdate(UpdatePackage updatePackage) _logger.Info("Download completed for update package from [{0}]", updatePackage.FileName); _logger.Info("Extracting Update package"); - _archiveProvider.ExtractArchive(packageDestination, updateSandboxFolder); + _archiveService.Extract(packageDestination, updateSandboxFolder); _logger.Info("Update package extracted successfully"); _logger.Info("Preparing client"); diff --git a/NzbDrone.Core/packages.config b/NzbDrone.Core/packages.config index 021bedc53..6ec33862e 100644 --- a/NzbDrone.Core/packages.config +++ b/NzbDrone.Core/packages.config @@ -1,6 +1,5 @@  - diff --git a/NzbDrone.Update/UpdateEngine/TerminateNzbDrone.cs b/NzbDrone.Update/UpdateEngine/TerminateNzbDrone.cs index 4bb38aebf..99e55470b 100644 --- a/NzbDrone.Update/UpdateEngine/TerminateNzbDrone.cs +++ b/NzbDrone.Update/UpdateEngine/TerminateNzbDrone.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using NLog; using NzbDrone.Common; using IServiceProvider = NzbDrone.Common.IServiceProvider; @@ -45,13 +44,8 @@ public void Terminate() _logger.Info("Killing all running processes"); - if (_processProvider.GetProcessByName(ProcessProvider.NzbDroneConsoleProcessName).Any()) - { - _processProvider.KillAll(ProcessProvider.NzbDroneConsoleProcessName); - } - + _processProvider.KillAll(ProcessProvider.NzbDroneConsoleProcessName); _processProvider.KillAll(ProcessProvider.NzbDroneProcessName); - } } } \ No newline at end of file