Add support for ZIP plugin archives
Most code from @cvium. Also removes the lazy and ill-conceived GUID- based checksumming, which just died with ZIP archives.
This commit is contained in:
parent
bcb32ec6ad
commit
2f4a00d322
|
@ -564,7 +564,7 @@ namespace Emby.Server.Implementations
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var assembly = Assembly.Load(File.ReadAllBytes(file));
|
var assembly = Assembly.LoadFrom(file);
|
||||||
|
|
||||||
return new Tuple<Assembly, string>(assembly, file);
|
return new Tuple<Assembly, string>(assembly, file);
|
||||||
}
|
}
|
||||||
|
@ -777,12 +777,12 @@ namespace Emby.Server.Implementations
|
||||||
SocketFactory = new SocketFactory();
|
SocketFactory = new SocketFactory();
|
||||||
RegisterSingleInstance(SocketFactory);
|
RegisterSingleInstance(SocketFactory);
|
||||||
|
|
||||||
InstallationManager = new InstallationManager(LoggerFactory, this, ApplicationPaths, HttpClient, JsonSerializer, ServerConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime);
|
|
||||||
RegisterSingleInstance(InstallationManager);
|
|
||||||
|
|
||||||
ZipClient = new ZipClient(FileSystemManager);
|
ZipClient = new ZipClient(FileSystemManager);
|
||||||
RegisterSingleInstance(ZipClient);
|
RegisterSingleInstance(ZipClient);
|
||||||
|
|
||||||
|
InstallationManager = new InstallationManager(LoggerFactory, this, ApplicationPaths, HttpClient, JsonSerializer, ServerConfigurationManager, FileSystemManager, CryptographyProvider, ZipClient, PackageRuntime);
|
||||||
|
RegisterSingleInstance(InstallationManager);
|
||||||
|
|
||||||
HttpResultFactory = new HttpResultFactory(LoggerFactory, FileSystemManager, JsonSerializer, CreateBrotliCompressor());
|
HttpResultFactory = new HttpResultFactory(LoggerFactory, FileSystemManager, JsonSerializer, CreateBrotliCompressor());
|
||||||
RegisterSingleInstance(HttpResultFactory);
|
RegisterSingleInstance(HttpResultFactory);
|
||||||
|
|
||||||
|
@ -1603,7 +1603,7 @@ namespace Emby.Server.Implementations
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return FilterAssembliesToLoad(Directory.EnumerateFiles(path, "*.dll", SearchOption.TopDirectoryOnly))
|
return FilterAssembliesToLoad(Directory.EnumerateFiles(path, "*.dll", SearchOption.AllDirectories))
|
||||||
.Select(LoadAssembly)
|
.Select(LoadAssembly)
|
||||||
.Where(a => a != null)
|
.Where(a => a != null)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
|
@ -116,6 +116,7 @@ namespace Emby.Server.Implementations.Updates
|
||||||
private readonly IApplicationHost _applicationHost;
|
private readonly IApplicationHost _applicationHost;
|
||||||
|
|
||||||
private readonly ICryptoProvider _cryptographyProvider;
|
private readonly ICryptoProvider _cryptographyProvider;
|
||||||
|
private readonly IZipClient _zipClient;
|
||||||
|
|
||||||
// netframework or netcore
|
// netframework or netcore
|
||||||
private readonly string _packageRuntime;
|
private readonly string _packageRuntime;
|
||||||
|
@ -129,6 +130,7 @@ namespace Emby.Server.Implementations.Updates
|
||||||
IServerConfigurationManager config,
|
IServerConfigurationManager config,
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
ICryptoProvider cryptographyProvider,
|
ICryptoProvider cryptographyProvider,
|
||||||
|
IZipClient zipClient,
|
||||||
string packageRuntime)
|
string packageRuntime)
|
||||||
{
|
{
|
||||||
if (loggerFactory == null)
|
if (loggerFactory == null)
|
||||||
|
@ -146,6 +148,7 @@ namespace Emby.Server.Implementations.Updates
|
||||||
_config = config;
|
_config = config;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_cryptographyProvider = cryptographyProvider;
|
_cryptographyProvider = cryptographyProvider;
|
||||||
|
_zipClient = zipClient;
|
||||||
_packageRuntime = packageRuntime;
|
_packageRuntime = packageRuntime;
|
||||||
_logger = loggerFactory.CreateLogger(nameof(InstallationManager));
|
_logger = loggerFactory.CreateLogger(nameof(InstallationManager));
|
||||||
}
|
}
|
||||||
|
@ -527,13 +530,19 @@ namespace Emby.Server.Implementations.Updates
|
||||||
private async Task PerformPackageInstallation(IProgress<double> progress, string target, PackageVersionInfo package, CancellationToken cancellationToken)
|
private async Task PerformPackageInstallation(IProgress<double> progress, string target, PackageVersionInfo package, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Target based on if it is an archive or single assembly
|
// Target based on if it is an archive or single assembly
|
||||||
// zip archives are assumed to contain directory structures relative to our ProgramDataPath
|
|
||||||
var extension = Path.GetExtension(package.targetFilename);
|
var extension = Path.GetExtension(package.targetFilename);
|
||||||
var isArchive = string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase) || string.Equals(extension, ".rar", StringComparison.OrdinalIgnoreCase) || string.Equals(extension, ".7z", StringComparison.OrdinalIgnoreCase);
|
var isArchive = string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
target = Path.Combine(isArchive ? _appPaths.TempUpdatePath : _appPaths.PluginsPath, package.targetFilename);
|
if (isArchive)
|
||||||
|
{
|
||||||
|
target = Path.Combine(_appPaths.PluginsPath, Path.GetFileNameWithoutExtension(package.targetFilename));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target = Path.Combine(_appPaths.PluginsPath, package.targetFilename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download to temporary file so that, if interrupted, it won't destroy the existing installation
|
// Download to temporary file so that, if interrupted, it won't destroy the existing installation
|
||||||
|
@ -547,31 +556,22 @@ namespace Emby.Server.Implementations.Updates
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
// Validate with a checksum
|
// TODO: Validate with a checksum, *properly*
|
||||||
var packageChecksum = string.IsNullOrWhiteSpace(package.checksum) ? Guid.Empty : new Guid(package.checksum);
|
|
||||||
if (!packageChecksum.Equals(Guid.Empty)) // support for legacy uploads for now
|
|
||||||
{
|
|
||||||
using (var stream = File.OpenRead(tempFile))
|
|
||||||
{
|
|
||||||
var check = Guid.Parse(BitConverter.ToString(_cryptographyProvider.ComputeMD5(stream)).Replace("-", string.Empty));
|
|
||||||
if (check != packageChecksum)
|
|
||||||
{
|
|
||||||
throw new Exception(string.Format("Download validation failed for {0}. Probably corrupted during transfer.", package.name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
// Success - move it to the real target
|
// Success - move it to the real target
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(target));
|
|
||||||
File.Copy(tempFile, target, true);
|
|
||||||
//If it is an archive - write out a version file so we know what it is
|
|
||||||
if (isArchive)
|
if (isArchive)
|
||||||
{
|
{
|
||||||
File.WriteAllText(target + ".ver", package.versionStr);
|
using (var stream = File.OpenRead(tempFile))
|
||||||
|
{
|
||||||
|
_zipClient.ExtractAllFromZip(stream, target, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(target));
|
||||||
|
File.Copy(tempFile, target, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user