diff --git a/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.User.cs b/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.User.cs index bf1981f..1a737f3 100644 --- a/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.User.cs +++ b/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.User.cs @@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using SixLabors.ImageSharp; -using SixLabors.ImageSharp.PixelFormats; using StackExchange.Redis; using System.Text; using System.Text.Json; diff --git a/LightlessSyncServer/LightlessSyncServer/LightlessSyncServer.csproj b/LightlessSyncServer/LightlessSyncServer/LightlessSyncServer.csproj index 2891a14..10af95d 100644 --- a/LightlessSyncServer/LightlessSyncServer/LightlessSyncServer.csproj +++ b/LightlessSyncServer/LightlessSyncServer/LightlessSyncServer.csproj @@ -21,6 +21,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/LightlessSyncServer/LightlessSyncStaticFilesServer/Controllers/ServerFilesController.cs b/LightlessSyncServer/LightlessSyncStaticFilesServer/Controllers/ServerFilesController.cs index d0b5d95..1f9f992 100644 --- a/LightlessSyncServer/LightlessSyncStaticFilesServer/Controllers/ServerFilesController.cs +++ b/LightlessSyncServer/LightlessSyncStaticFilesServer/Controllers/ServerFilesController.cs @@ -1,4 +1,5 @@ -using K4os.Compression.LZ4.Legacy; +using Blake3; +using K4os.Compression.LZ4.Legacy; using LightlessSync.API.Dto.Files; using LightlessSync.API.Routes; using LightlessSync.API.SignalR; @@ -208,11 +209,13 @@ public class ServerFilesController : ControllerBase [RequestSizeLimit(200 * 1024 * 1024)] public async Task UploadFile(string hash, CancellationToken requestAborted) { - using var dbContext = await _lightlessDbContext.CreateDbContextAsync(); + await using var dbContext = await _lightlessDbContext.CreateDbContextAsync(); _logger.LogInformation("{user}|{file}: Uploading", LightlessUser, hash); - - hash = hash.ToUpperInvariant(); + if (hash.Length == 40) + { + hash = hash.ToUpperInvariant(); + } var existingFile = await dbContext.Files.SingleOrDefaultAsync(f => f.Hash == hash); if (existingFile != null) return Ok(); @@ -263,10 +266,13 @@ public class ServerFilesController : ControllerBase [RequestSizeLimit(200 * 1024 * 1024)] public async Task UploadFileMunged(string hash, CancellationToken requestAborted) { - using var dbContext = await _lightlessDbContext.CreateDbContextAsync(); + await using var dbContext = await _lightlessDbContext.CreateDbContextAsync(); _logger.LogInformation("{user}|{file}: Uploading munged", LightlessUser, hash); - hash = hash.ToUpperInvariant(); + if (hash.Length == 40) + { + hash = hash.ToUpperInvariant(); + } var existingFile = await dbContext.Files.SingleOrDefaultAsync(f => f.Hash == hash); if (existingFile != null) return Ok(); @@ -319,20 +325,26 @@ public class ServerFilesController : ControllerBase private async Task StoreData(string hash, LightlessDbContext dbContext, MemoryStream compressedFileStream) { var decompressedData = LZ4Wrapper.Unwrap(compressedFileStream.ToArray()); - // reset streams compressedFileStream.Seek(0, SeekOrigin.Begin); - // compute hash to verify - var hashString = BitConverter.ToString(SHA1.HashData(decompressedData)) - .Replace("-", "", StringComparison.Ordinal).ToUpperInvariant(); - if (!string.Equals(hashString, hash, StringComparison.Ordinal)) - throw new InvalidOperationException($"{LightlessUser}|{hash}: Hash does not match file, computed: {hashString}, expected: {hash}"); + bool valid; - // save file - var path = FilePathUtil.GetFilePath(_basePath, hash); - using var fileStream = new FileStream(path, FileMode.Create); - await compressedFileStream.CopyToAsync(fileStream).ConfigureAwait(false); - _logger.LogDebug("{user}|{file}: Uploaded file saved to {path}", LightlessUser, hash, path); + if (hash.Length == 40) + { + var sha1Hex = Convert.ToHexString(SHA1.HashData(decompressedData)); + valid = string.Equals(sha1Hex, hash, StringComparison.OrdinalIgnoreCase); + } + else + { + var blakeHash = Hasher.Hash(decompressedData); + var blakeHex = Convert.ToHexString(blakeHash.AsSpan()); + valid = string.Equals(blakeHex, hash, StringComparison.OrdinalIgnoreCase); + } + + if (!valid) + throw new InvalidOperationException( + $"{LightlessUser}|{hash}: Hash does not match file, computed mismatch." + ); // update on db await dbContext.Files.AddAsync(new FileCache() diff --git a/LightlessSyncServer/LightlessSyncStaticFilesServer/LightlessSyncStaticFilesServer.csproj b/LightlessSyncServer/LightlessSyncStaticFilesServer/LightlessSyncStaticFilesServer.csproj index 0676329..3d1984e 100644 --- a/LightlessSyncServer/LightlessSyncStaticFilesServer/LightlessSyncStaticFilesServer.csproj +++ b/LightlessSyncServer/LightlessSyncStaticFilesServer/LightlessSyncStaticFilesServer.csproj @@ -18,6 +18,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive