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