Open Maetis opened 2 years ago
I found a simple workaround:
Do not rename the namespace or class otherwise the Mono interop will not work
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Primitives;
using System.Collections;
using System.Runtime.CompilerServices;
namespace Wasi.AspNetCore.BundledFiles;
// Do NOT change the namespace or type name
// Wasi.AspNetCore.BundledFiles.WasiBundledFileProvider
// Otherwise Mono will not find the interop call (GetEmbeddedFile)
public class WasiBundledFileProvider : IFileProvider
{
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern unsafe byte* GetEmbeddedFile(string name, out int length);
private readonly static DateTime FakeLastModified = new DateTime(2000, 1, 1);
public IDirectoryContents GetDirectoryContents(string subpath)
{
return new BundledDirectoryContents(this, subpath);
}
public unsafe IFileInfo GetFileInfo(string subpath)
{
var subpathWithoutLeadingSlash = subpath.AsSpan(1);
var fileBytes = GetEmbeddedFile($"wwwroot/{subpathWithoutLeadingSlash}", out var length);
return fileBytes == null
? new NotFoundFileInfo(subpath)
: new BundledFileInfo(subpath, length, FakeLastModified, fileBytes);
}
public IChangeToken Watch(string filter)
{
return NullChangeToken.Singleton;
}
unsafe class BundledFileInfo : IFileInfo
{
private byte* _fileBytes;
public BundledFileInfo(string name, long length, DateTime lastModified, byte* fileBytes)
{
Name = name;
LastModified = lastModified;
Length = length;
_fileBytes = fileBytes;
}
public bool Exists => true;
public bool IsDirectory => false;
public DateTimeOffset LastModified { get; }
public long Length { get; }
public string Name { get; }
public string? PhysicalPath => null;
public Stream CreateReadStream()
=> new UnmanagedMemoryStream(_fileBytes, Length);
}
class BundledDirectoryContents : IDirectoryContents
{
private readonly IFileProvider _owner;
private readonly string _subpath;
public BundledDirectoryContents(IFileProvider owner, string subpath)
{
_owner = owner;
_subpath = subpath;
}
public bool Exists => _subpath == "/";
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public IEnumerator<IFileInfo> GetEnumerator()
{
// TODO: Mechanism for enumerating everything in a bundled directory
// Currently this only recognizes index.html files to support UseDefaultFiles
if (_subpath == "/")
{
var fileInfo = _owner.GetFileInfo("/index.html");
if (fileInfo.Exists)
{
yield return fileInfo;
}
}
}
}
}
This is obviously the culprit:
public IChangeToken Watch(string filter)
{
return NullChangeToken.Singleton;
}
StaticFileOptions
either using UseStaticFiles
or UseBundledStaticFiles
:app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new WasiBundledFileProvider()
});
Description
I tried to use the Wasi.AspNetCore.BundledFiles package in order to bundle the static files of my web, and I got an error about a not implemented method.
Reproduction Steps
And follow steps in How to use: ASP.NET Core applications for code modifications.
Expected behavior
Web app work!
Actual behavior
Configuration
Please provide more information on your .NET configuration:
Which version of .NET is the code running on? 7.0.100-rc.2.22477.23 What OS and version, and what distro if applicable? Ubuntu 22.04 LTS (WSL) What is the architecture (x64, x86, ARM, ARM64)? x64 WASM runner? wasmtime-cli 2.0.0