Add ability to serve Mono static files

This commit is contained in:
Steve Sanderson 2017-12-06 12:13:22 +00:00
parent 29a8a21ed3
commit 47c8af1c54
9 changed files with 184 additions and 2 deletions

View File

@ -37,7 +37,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mono", "mono", "{7B5CAAB1-A
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Blazor.Mono", "runtime\Microsoft.Blazor.Mono\Microsoft.Blazor.Mono.csproj", "{39FEC72D-AF52-47A3-B63D-7BF0E4335248}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoSanity", "samples\MonoSanity\MonoSanity.csproj", "{7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoSanity", "samples\MonoSanity\MonoSanity.csproj", "{7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Blazor.Server", "runtime\Microsoft.Blazor.Server\Microsoft.Blazor.Server.csproj", "{5A694793-3257-4D37-BB74-4A41B3894685}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{ADA3AE29-F6DE-49F6-8C7C-B321508CAE8E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Blazor.Mono.Test", "test\Microsoft.Blazor.Mono.Test\Microsoft.Blazor.Mono.Test.csproj", "{118484D3-3993-45CE-97C1-6F28A517529B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -61,15 +67,26 @@ Global
{7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C53BB6B-5906-4753-B507-C9FCC2F7E5B7}.Release|Any CPU.Build.0 = Release|Any CPU
{5A694793-3257-4D37-BB74-4A41B3894685}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A694793-3257-4D37-BB74-4A41B3894685}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A694793-3257-4D37-BB74-4A41B3894685}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A694793-3257-4D37-BB74-4A41B3894685}.Release|Any CPU.Build.0 = Release|Any CPU
{118484D3-3993-45CE-97C1-6F28A517529B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{118484D3-3993-45CE-97C1-6F28A517529B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{118484D3-3993-45CE-97C1-6F28A517529B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{118484D3-3993-45CE-97C1-6F28A517529B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4C7EE25B-E9C7-4CA3-8357-77ADF9AAD20A} = {F5FDD4E5-6A52-4A86-BE5E-5E42CB1DC8DA}
{A1A3AEB6-A832-477E-8D91-A672CFE53801} = {ADA3AE29-F6DE-49F6-8C7C-B321508CAE8E}
{7B5CAAB1-A3EB-44F7-87E3-A13ED89FC17D} = {B867E038-B3CE-43E3-9292-61568C46CDEB}
{39FEC72D-AF52-47A3-B63D-7BF0E4335248} = {B867E038-B3CE-43E3-9292-61568C46CDEB}
{7C53BB6B-5906-4753-B507-C9FCC2F7E5B7} = {F5FDD4E5-6A52-4A86-BE5E-5E42CB1DC8DA}
{5A694793-3257-4D37-BB74-4A41B3894685} = {B867E038-B3CE-43E3-9292-61568C46CDEB}
{118484D3-3993-45CE-97C1-6F28A517529B} = {ADA3AE29-F6DE-49F6-8C7C-B321508CAE8E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {504DA352-6788-4DC0-8705-82167E72A4D3}

View File

@ -6,11 +6,15 @@
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.0.0" />
</ItemGroup>
<Target Name="EmbedMonoResources" BeforeTargets="PreBuildEvent" DependsOnTargets="OptimizeMono">
<ItemGroup>
<MonoResourcesToEmbed Include="$(MonoOptimizedDir)**" />
<EmbeddedResource Include="@(MonoResourcesToEmbed)">
<LogicalName>mono:%(RecursiveDir)%(Filename)%(Extension)</LogicalName>
<LogicalName>mono.$([System.String]::Copy('/%(RecursiveDir)%(FileName)%(Extension)').Replace('\', '$').Replace('/', '$'))</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Target>

View File

@ -0,0 +1,30 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Primitives;
using System;
namespace Microsoft.Blazor.Mono
{
public class MonoStaticFileProvider : IFileProvider
{
private EmbeddedFileProvider _embeddedFiles = new EmbeddedFileProvider(
typeof(MonoStaticFileProvider).Assembly,
"mono");
public IFileInfo GetFileInfo(string subpath)
{
// EmbeddedFileProvider can't find resources whose names include '/' (or '\'),
// so the resources in the assembly use '$' as a directory separator
var possibleResourceName = subpath.Replace('/', '$');
return _embeddedFiles.GetFileInfo(possibleResourceName);
}
public IDirectoryContents GetDirectoryContents(string subpath)
=> throw new NotImplementedException(); // Don't need to support this
public IChangeToken Watch(string filter)
=> throw new NotImplementedException(); // Don't need to support this
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Blazor.Mono;
using System.Collections.Generic;
using System.Net.Mime;
namespace Microsoft.AspNetCore.Builder
{
public static class BlazorAppBuilderExtensions
{
public static void UseBlazor(this IApplicationBuilder applicationBuilder)
{
applicationBuilder.UseStaticFiles(new StaticFileOptions
{
RequestPath = "/_framework",
FileProvider = new MonoStaticFileProvider(),
ContentTypeProvider = CreateContentTypeProvider(),
});
}
private static IContentTypeProvider CreateContentTypeProvider()
{
return new FileExtensionContentTypeProvider(new Dictionary<string, string>
{
{ ".dll", MediaTypeNames.Application.Octet },
{ ".js", "application/javascript" },
{ ".wasm", MediaTypeNames.Application.Octet }
});
}
}
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Blazor.Mono\Microsoft.Blazor.Mono.csproj" />
</ItemGroup>
</Project>

View File

@ -8,4 +8,8 @@
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\runtime\Microsoft.Blazor.Server\Microsoft.Blazor.Server.csproj" />
</ItemGroup>
</Project>

View File

@ -12,6 +12,7 @@ namespace MonoSanity
{
app.UseDeveloperExceptionPage();
app.UseFileServer();
app.UseBlazor();
}
}
}

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\runtime\Microsoft.Blazor.Mono\Microsoft.Blazor.Mono.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,58 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Xunit;
namespace Microsoft.Blazor.Mono.Test
{
public class MonoStaticFileProviderTest
{
[Fact]
public void SuppliesMonoFiles()
{
var provider = new MonoStaticFileProvider();
// This is not an exhaustive list. The set of BCL facade types is long and
// will probably change. This test is just to verify the resource embedding
// and filename mapping is working correctly.
var expectedFiles = new[]
{
"/asmjs/mono.asm.js",
"/wasm/mono.wasm",
"/bcl/mscorlib.dll",
"/bcl/Facades/System.Collections.dll",
};
foreach (var name in expectedFiles)
{
var fileInfo = provider.GetFileInfo(name);
Assert.True(fileInfo.Exists);
Assert.False(fileInfo.IsDirectory);
Assert.True(fileInfo.Length > 0);
}
}
[Fact]
public void DoesNotSupplyUnexpectedFiles()
{
var provider = new MonoStaticFileProvider();
var notExpectedFiles = new[]
{
"",
"mono",
"wasm",
"/wasm",
"/wasm/",
"wasm/mono.wasm",
"/wasm/../wasm/mono.wasm",
};
foreach (var name in notExpectedFiles)
{
var fileInfo = provider.GetFileInfo(name);
Assert.False(fileInfo.Exists);
}
}
}
}