mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-07-21 13:03:41 +01:00
Properly make ZipToDirectory use IFileSystem
This commit is contained in:
@@ -14,7 +14,7 @@ namespace Tgstation.Server.Host.Components.Engine
|
||||
/// </summary>
|
||||
/// <param name="path">The full path to extract to.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task ExtractToPath(string path, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask ExtractToPath(string path, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,12 +48,11 @@ namespace Tgstation.Server.Host.Components.Engine
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ExtractToPath(string path, CancellationToken cancellationToken)
|
||||
public ValueTask ExtractToPath(string path, CancellationToken cancellationToken)
|
||||
=> repository.CopyTo(
|
||||
ioManager.ConcatPath(
|
||||
path,
|
||||
targetSubDirectory),
|
||||
cancellationToken)
|
||||
.AsTask();
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Tgstation.Server.Host.Components.Engine
|
||||
public ValueTask DisposeAsync() => zipStream.DisposeAsync();
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ExtractToPath(string path, CancellationToken cancellationToken)
|
||||
public ValueTask ExtractToPath(string path, CancellationToken cancellationToken)
|
||||
=> ioManager.ZipToDirectory(path, zipStream, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Tgstation.Server.Host.Jobs;
|
||||
using Tgstation.Server.Host.Utils;
|
||||
|
||||
namespace Tgstation.Server.Host.IO
|
||||
@@ -335,26 +336,46 @@ namespace Tgstation.Server.Host.IO
|
||||
TaskScheduler.Current);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ZipToDirectory(string path, Stream zipFile, CancellationToken cancellationToken) => Task.Factory.StartNew(
|
||||
() =>
|
||||
{
|
||||
path = ResolvePath(path);
|
||||
ArgumentNullException.ThrowIfNull(zipFile);
|
||||
public async ValueTask ZipToDirectory(string path, Stream zipFile, CancellationToken cancellationToken)
|
||||
{
|
||||
path = ResolvePath(path);
|
||||
ArgumentNullException.ThrowIfNull(zipFile);
|
||||
|
||||
#if NET9_0_OR_GREATER
|
||||
#error Check if zip file seeking has been addressesed. See https://github.com/tgstation/tgstation-server/issues/1531
|
||||
#endif
|
||||
|
||||
// ZipArchive does a synchronous copy on unseekable streams we want to avoid
|
||||
if (!zipFile.CanSeek)
|
||||
throw new ArgumentException("Stream does not support seeking!", nameof(zipFile));
|
||||
// ZipArchive does a synchronous copy on unseekable streams we want to avoid
|
||||
if (!zipFile.CanSeek)
|
||||
throw new ArgumentException("Stream does not support seeking!", nameof(zipFile));
|
||||
|
||||
using var archive = new ZipArchive(zipFile, ZipArchiveMode.Read, true);
|
||||
archive.ExtractToDirectory(path);
|
||||
},
|
||||
cancellationToken,
|
||||
BlockingTaskCreationOptions,
|
||||
TaskScheduler.Current);
|
||||
using var archive = new ZipArchive(zipFile, ZipArchiveMode.Read, true);
|
||||
|
||||
// start async context
|
||||
await Task.Yield();
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var entryPath = fileSystem.Path.Combine(path, entry.FullName);
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
fileSystem.Directory.CreateDirectory(entryPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
var directoryPath = fileSystem.Path.GetDirectoryName(entryPath);
|
||||
if (directoryPath == null)
|
||||
{
|
||||
throw new JobException("Zip archive concatenation resulted in a null directory path!");
|
||||
}
|
||||
|
||||
fileSystem.Directory.CreateDirectory(directoryPath);
|
||||
|
||||
using var entryStream = entry.Open();
|
||||
using var outputStream = fileSystem.File.Create(entryPath);
|
||||
await entryStream.CopyToAsync(outputStream, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool PathContainsParentAccess(string path) => path
|
||||
|
||||
@@ -238,8 +238,8 @@ namespace Tgstation.Server.Host.IO
|
||||
/// <param name="path">The path to unzip to.</param>
|
||||
/// <param name="zipFile">The <see cref="Stream"/> of the <see cref="global::System.IO.Compression.ZipArchive"/>. Must have <see cref="Stream.CanSeek"/> set to <see langword="true"/>. Will be read completely and left open. <see cref="Stream.Position"/> will be indeterminate.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
Task ZipToDirectory(string path, Stream zipFile, CancellationToken cancellationToken);
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask ZipToDirectory(string path, Stream zipFile, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="DateTimeOffset"/> of when a given <paramref name="path"/> was last modified.
|
||||
|
||||
Reference in New Issue
Block a user