Support hosting at non-root URL. Prove it by updating BasicTestApp to serve from non-root location.

This commit is contained in:
Steve Sanderson 2018-02-20 23:11:40 +00:00
parent 7073429cd5
commit 8bc7c92683
7 changed files with 43 additions and 12 deletions

View File

@ -20,7 +20,7 @@ async function boot() {
// Determine the URLs of the assemblies we want to load // Determine the URLs of the assemblies we want to load
const loadAssemblyUrls = [entryPointDll] const loadAssemblyUrls = [entryPointDll]
.concat(referenceAssemblies) .concat(referenceAssemblies)
.map(filename => `/_framework/_bin/${filename}`); .map(filename => `_framework/_bin/${filename}`);
try { try {
await platform.start(loadAssemblyUrls); await platform.start(loadAssemblyUrls);

View File

@ -48,9 +48,9 @@ export const monoPlatform: Platform = {
callEntryPoint: function callEntryPoint(assemblyName: string, entrypointMethod: string, args: System_Object[]): void { callEntryPoint: function callEntryPoint(assemblyName: string, entrypointMethod: string, args: System_Object[]): void {
// Parse the entrypointMethod, which is of the form MyApp.MyNamespace.MyTypeName::MyMethodName // Parse the entrypointMethod, which is of the form MyApp.MyNamespace.MyTypeName::MyMethodName
// Note that we don't support specifying a method overload, so it has to be unique // Note that we don't support specifying a method overload, so it has to be unique
const entrypointSegments = entrypointMethod.split("::"); const entrypointSegments = entrypointMethod.split('::');
if (entrypointSegments.length != 2) { if (entrypointSegments.length != 2) {
throw new Error("malformed entry point method name; could not resolve class name and method name"); throw new Error('Malformed entry point method name; could not resolve class name and method name.');
} }
const typeFullName = entrypointSegments[0]; const typeFullName = entrypointSegments[0];
const methodName = entrypointSegments[1]; const methodName = entrypointSegments[1];
@ -146,7 +146,7 @@ export const monoPlatform: Platform = {
function addScriptTagsToDocument() { function addScriptTagsToDocument() {
// Load either the wasm or asm.js version of the Mono runtime // Load either the wasm or asm.js version of the Mono runtime
const browserSupportsNativeWebAssembly = typeof WebAssembly !== 'undefined' && WebAssembly.validate; const browserSupportsNativeWebAssembly = typeof WebAssembly !== 'undefined' && WebAssembly.validate;
const monoRuntimeUrlBase = '/_framework/' + (browserSupportsNativeWebAssembly ? 'wasm' : 'asmjs'); const monoRuntimeUrlBase = '_framework/' + (browserSupportsNativeWebAssembly ? 'wasm' : 'asmjs');
const monoRuntimeScriptUrl = `${monoRuntimeUrlBase}/mono.js`; const monoRuntimeScriptUrl = `${monoRuntimeUrlBase}/mono.js`;
if (!browserSupportsNativeWebAssembly) { if (!browserSupportsNativeWebAssembly) {
@ -165,8 +165,8 @@ function createEmscriptenModuleInstance(loadAssemblyUrls: string[], onReady: ()
module.print = line => console.log(`WASM: ${line}`); module.print = line => console.log(`WASM: ${line}`);
module.printErr = line => console.error(`WASM: ${line}`); module.printErr = line => console.error(`WASM: ${line}`);
module.wasmBinaryFile = '/_framework/wasm/mono.wasm'; module.wasmBinaryFile = '_framework/wasm/mono.wasm';
module.asmjsCodeFile = '/_framework/asmjs/mono.asm.js'; module.asmjsCodeFile = '_framework/asmjs/mono.asm.js';
module.preRun = []; module.preRun = [];
module.postRun = []; module.postRun = [];
module.preloadPlugins = []; module.preloadPlugins = [];

View File

@ -2,11 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Reflection;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.IO; using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Blazor.DevHost.Server namespace Microsoft.AspNetCore.Blazor.DevHost.Server
{ {
@ -17,14 +18,40 @@ namespace Microsoft.AspNetCore.Blazor.DevHost.Server
services.AddRouting(); services.AddRouting();
} }
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app, IConfiguration configuration)
{ {
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
EnableConfiguredPathbase(app, configuration);
var clientAssemblyPath = FindClientAssemblyPath(app); var clientAssemblyPath = FindClientAssemblyPath(app);
app.UseBlazor(new BlazorOptions { ClientAssemblyPath = clientAssemblyPath }); app.UseBlazor(new BlazorOptions { ClientAssemblyPath = clientAssemblyPath });
} }
private static void EnableConfiguredPathbase(IApplicationBuilder app, IConfiguration configuration)
{
var pathBase = configuration.GetValue<string>("pathbase");
if (!string.IsNullOrEmpty(pathBase))
{
app.UsePathBase(pathBase);
// To ensure consistency with a production environment, only handle requests
// that match the specified pathbase.
app.Use((context, next) =>
{
if (context.Request.PathBase == pathBase)
{
return next();
}
else
{
context.Response.StatusCode = 404;
return context.Response.WriteAsync($"The server is configured only to " +
$"handle request URIs within the PathBase '{pathBase}'.");
}
});
}
}
private static string FindClientAssemblyPath(IApplicationBuilder app) private static string FindClientAssemblyPath(IApplicationBuilder app)
{ {
var env = app.ApplicationServices.GetRequiredService<IHostingEnvironment>(); var env = app.ApplicationServices.GetRequiredService<IHostingEnvironment>();

View File

@ -1,7 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using DevHostServerProgram = Microsoft.AspNetCore.Blazor.DevHost.Server.Program; using DevHostServerProgram = Microsoft.AspNetCore.Blazor.DevHost.Server.Program;
@ -9,6 +8,8 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure.ServerFixtures
{ {
public class DevHostServerFixture<TProgram> : WebHostServerFixture public class DevHostServerFixture<TProgram> : WebHostServerFixture
{ {
public string PathBase { get; set; }
protected override IWebHost CreateWebHost() protected override IWebHost CreateWebHost()
{ {
var sampleSitePath = FindSampleOrTestSitePath( var sampleSitePath = FindSampleOrTestSitePath(
@ -17,7 +18,8 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure.ServerFixtures
return DevHostServerProgram.BuildWebHost(new string[] return DevHostServerProgram.BuildWebHost(new string[]
{ {
"--urls", "http://127.0.0.1:0", "--urls", "http://127.0.0.1:0",
"--contentroot", sampleSitePath "--contentroot", sampleSitePath,
"--pathbase", PathBase
}); });
} }
} }

View File

@ -23,7 +23,8 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests
public ComponentRenderingTest(BrowserFixture browserFixture, DevHostServerFixture<Program> serverFixture) public ComponentRenderingTest(BrowserFixture browserFixture, DevHostServerFixture<Program> serverFixture)
: base(browserFixture, serverFixture) : base(browserFixture, serverFixture)
{ {
Navigate("/", noReload: true); serverFixture.PathBase = "/subdir";
Navigate("/subdir", noReload: true);
} }
[Fact] [Fact]

View File

@ -5,7 +5,7 @@
<!-- Local alternative to <RunArguments>blazor serve</RunArguments> --> <!-- Local alternative to <RunArguments>blazor serve</RunArguments> -->
<RunCommand>dotnet</RunCommand> <RunCommand>dotnet</RunCommand>
<RunArguments>run --project ..\..\..\src\Microsoft.AspNetCore.Blazor.DevHost serve</RunArguments> <RunArguments>run --project ..\..\..\src\Microsoft.AspNetCore.Blazor.DevHost serve --pathbase /subdir</RunArguments>
</PropertyGroup> </PropertyGroup>
<!-- Local alternative to <PackageReference Include="Microsoft.AspNetCore.Blazor.Build" /> --> <!-- Local alternative to <PackageReference Include="Microsoft.AspNetCore.Blazor.Build" /> -->

View File

@ -3,6 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Basic test app</title> <title>Basic test app</title>
<base href="/subdir/" />
</head> </head>
<body> <body>
<app>Loading...</app> <app>Loading...</app>