DefaultFilesMiddleware in conjunction with EmbeddedFileProvider and subpaths
muratg opened this issue · 5 comments
From @avanderhoorn on January 3, 2017 6:10
The behaviour of DefaultFilesMiddleware
doesn't seem quite right when used in conjunction with EmbeddedFileProvider
and subpaths. Specifically if my url was "localhost:3000/static/client/" and my EmbeddedFileProvider
s baseNamespace
was setup to point to static
, I would expect that translate through to and look for "localhost:3000/static/client/index.html"... this is not the case however.
Specifically, in scenarios where the EmbeddedFileProvider
has been setup as described, the DefaultFilesMiddleware
fails to find a match as the subpath.Value
(in the first link below below) is equal to /client/
which causes the EmbeddedFileProvider
to short circuit (in the second link below):
- https://github.com/aspnet/StaticFiles/blob/dev/src/Microsoft.AspNetCore.StaticFiles/DefaultFilesMiddleware.cs#L69
- https://github.com/aspnet/FileSystem/blob/dev/src/Microsoft.Extensions.FileProviders.Embedded/EmbeddedFileProvider.cs#L151-L154
Based on the comment in GetDirectoryContents
, I understand why this is the case - // Non-hierarchal.
but in the context of how this is used within DefaultFilesMiddleware
it seems like the wrong decision, or at the very least, very limiting - as the way the logic is setup, it can only ever support matching defaults at the root level.
I can think of a few different solutions to this problem, but before putting further energy into this, I wanted to see if there is any desire to support this use case?
Copied from original issue: aspnet/StaticFiles#164
From @Tratcher on January 3, 2017 6:53
Yes, this is a known limitation of EmbeddedFileProvider and that's where any enhancements would need to be made.
From @avanderhoorn on January 3, 2017 17:22
I'm happy to bring this up there, but before putting further energy into this, I wanted to see if there is any desire to support this use case?
From @Tratcher on January 3, 2017 17:52
It has come up before, though I can't find the thread at the moment. Yes, it would be nice to make it work eventually.
If I follow this correctly, I think users could overcome this limitation using my InMemoryFileProvider. ?
For example, this test shows taking resource embedded @ Dazinator.AspNet.Extensions.FileProviders.Tests.Resources.myresource.txt
, and then serving it on a subpath /some/folder/myfile.txt
- which is completely customised.
[Fact]
public void GetFileInfo_ReturnsFileInfo_ForEmbeddedFile()
{
using (var provider = new InMemoryFileProvider())
{
var embeddedFileInfo = new EmbeddedFileInfo(GetAssemblyFromType(this.GetType()),
$"Dazinator.AspNet.Extensions.FileProviders.Tests.Resources.myresource.txt",
"myfile.txt");
provider.Directory.AddFile("/some/folder", embeddedFileInfo);
var info = provider.GetFileInfo("/some/folder/myfile.txt");
using (var stream = info.CreateReadStream())
{
Assert.NotNull(stream);
Assert.True(stream.Length > 0);
}
}
}
Obiously you would need to set up the InMemoryFileProvider on startup, and include it in the IHostingEnvironments
WebRootFileProvider (or static files options fileproviders)
The main reason this functionality came about though was to overcome the issue that embedded file provider is non hierarchical. If you set up your resources as above, you can set them up into hierarchical folder structures - and GetDirectoryContents and everything else will work with them.
This issue was moved to aspnet/Home#2543