Skip to content

Commit

Permalink
Merge pull request #855 from Youssef1313/dev/youssef/preview4-support
Browse files Browse the repository at this point in the history
feat: Support new Fingerprint and Integrity metadata required in .NET 9 SDK Preview 4
  • Loading branch information
jeromelaban committed Jun 10, 2024
2 parents 72de499 + f88924d commit e23dd36
Showing 1 changed file with 59 additions and 15 deletions.
74 changes: 59 additions & 15 deletions src/Uno.Wasm.Bootstrap/StaticWebAssetsResolverTask.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// ******************************************************************

// ******************************************************************
// Copyright � 2015-2022 Uno Platform inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -22,6 +23,8 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Uno.Wasm.Bootstrap.Extensions;
Expand Down Expand Up @@ -70,20 +73,7 @@ public override bool Execute()
Log.LogMessage(MessageImportance.Low, $"Found {filteredAssets.Length} filtered assets");

StaticWebAsset =
filteredAssets.Select(asset =>
new TaskItem(asset, new Dictionary<string, string>
{
["SourceType"] = "Discovered",
["SourceId"] = AssemblyName,
["ContentRoot"] = fixedDistPath,
["RelativePath"] = asset.Replace(fixedDistPath, ""),
["BasePath"] = WebAppBasePath is { Length: > 0 } ? WebAppBasePath : "/",
["AssetKind"] = "All",
["AssetMode"] = "All",
["AssetRole"] = "Primary",
["OriginalItemSpec"] = asset,
}
))
filteredAssets.Select(asset => new TaskItem(asset, GetMetadata(asset, fixedDistPath)))
.ToArray();
}
else
Expand All @@ -93,4 +83,58 @@ public override bool Execute()

return true;
}

private Dictionary<string, string> GetMetadata(string asset, string fixedDistPath)
{
var dict = new Dictionary<string, string>
{
["SourceType"] = "Discovered",
["SourceId"] = AssemblyName,
["ContentRoot"] = fixedDistPath,
["RelativePath"] = asset.Replace(fixedDistPath, ""),
["BasePath"] = WebAppBasePath is { Length: > 0 } ? WebAppBasePath : "/",
["AssetKind"] = "All",
["AssetMode"] = "All",
["AssetRole"] = "Primary",
["OriginalItemSpec"] = asset,
};

var (fingerprint, integrity) = ComputeFingerprintAndIntegrity(asset, asset);
dict.Add("Fingerprint", fingerprint);
dict.Add("Integrity", integrity);
return dict;
}

// https://github.com/dotnet/sdk/blob/cc17704acfbee4b2ef49a82aa6f65aaa9cafffef/src/StaticWebAssetsSdk/Tasks/Data/StaticWebAsset.cs#L233-L248
private static (string fingerprint, string integrity) ComputeFingerprintAndIntegrity(string identity, string originalItemSpec)
{
using var file = File.Exists(identity) ?
File.OpenRead(identity) :
(File.Exists(originalItemSpec) ?
File.OpenRead(originalItemSpec) :
throw new InvalidOperationException($"No file exists for the asset at either location '{identity}' or '{originalItemSpec}'."));

#if NET6_0_OR_GREATER
var hash = SHA256.HashData(file);
#else
using var sha = SHA256.Create();
var hash = sha.ComputeHash(file);
#endif
return (ToBase36(hash), Convert.ToBase64String(hash));
}

private static string ToBase36(byte[] hash)
{
const string chars = "0123456789abcdefghijklmnopqrstuvwxyz";

var result = new char[10];
var dividend = BigInteger.Abs(new BigInteger(hash.AsSpan().Slice(0, 9).ToArray()));
for (var i = 0; i < 10; i++)
{
dividend = BigInteger.DivRem(dividend, 36, out var remainder);
result[i] = chars[(int)remainder];
}

return new string(result);
}
}

0 comments on commit e23dd36

Please sign in to comment.