From 8bc7c926835e811b1d42135171d2b808add6775d Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 20 Feb 2018 23:11:40 +0000 Subject: [PATCH] Support hosting at non-root URL. Prove it by updating BasicTestApp to serve from non-root location. --- .../src/Boot.ts | 2 +- .../src/Platform/Mono/MonoPlatform.ts | 10 +++--- .../Server/Startup.cs | 31 +++++++++++++++++-- .../ServerFixtures/DevHostServerFixture.cs | 6 ++-- .../Tests/ComponentRenderingTest.cs | 3 +- .../testapps/BasicTestApp/BasicTestApp.csproj | 2 +- test/testapps/BasicTestApp/wwwroot/index.html | 1 + 7 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Boot.ts b/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Boot.ts index 5fde164327..e4ba205083 100644 --- a/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Boot.ts +++ b/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Boot.ts @@ -20,7 +20,7 @@ async function boot() { // Determine the URLs of the assemblies we want to load const loadAssemblyUrls = [entryPointDll] .concat(referenceAssemblies) - .map(filename => `/_framework/_bin/${filename}`); + .map(filename => `_framework/_bin/${filename}`); try { await platform.start(loadAssemblyUrls); diff --git a/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Platform/Mono/MonoPlatform.ts b/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Platform/Mono/MonoPlatform.ts index 4def049f99..d12aec6169 100644 --- a/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Platform/Mono/MonoPlatform.ts @@ -48,9 +48,9 @@ export const monoPlatform: Platform = { callEntryPoint: function callEntryPoint(assemblyName: string, entrypointMethod: string, args: System_Object[]): void { // 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 - const entrypointSegments = entrypointMethod.split("::"); + const entrypointSegments = entrypointMethod.split('::'); 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 methodName = entrypointSegments[1]; @@ -146,7 +146,7 @@ export const monoPlatform: Platform = { function addScriptTagsToDocument() { // Load either the wasm or asm.js version of the Mono runtime const browserSupportsNativeWebAssembly = typeof WebAssembly !== 'undefined' && WebAssembly.validate; - const monoRuntimeUrlBase = '/_framework/' + (browserSupportsNativeWebAssembly ? 'wasm' : 'asmjs'); + const monoRuntimeUrlBase = '_framework/' + (browserSupportsNativeWebAssembly ? 'wasm' : 'asmjs'); const monoRuntimeScriptUrl = `${monoRuntimeUrlBase}/mono.js`; if (!browserSupportsNativeWebAssembly) { @@ -165,8 +165,8 @@ function createEmscriptenModuleInstance(loadAssemblyUrls: string[], onReady: () module.print = line => console.log(`WASM: ${line}`); module.printErr = line => console.error(`WASM: ${line}`); - module.wasmBinaryFile = '/_framework/wasm/mono.wasm'; - module.asmjsCodeFile = '/_framework/asmjs/mono.asm.js'; + module.wasmBinaryFile = '_framework/wasm/mono.wasm'; + module.asmjsCodeFile = '_framework/asmjs/mono.asm.js'; module.preRun = []; module.postRun = []; module.preloadPlugins = []; diff --git a/src/Microsoft.AspNetCore.Blazor.DevHost/Server/Startup.cs b/src/Microsoft.AspNetCore.Blazor.DevHost/Server/Startup.cs index 5cfb93db14..cefc3218ae 100644 --- a/src/Microsoft.AspNetCore.Blazor.DevHost/Server/Startup.cs +++ b/src/Microsoft.AspNetCore.Blazor.DevHost/Server/Startup.cs @@ -2,11 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using System.IO; +using Microsoft.Extensions.Configuration; +using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Blazor.DevHost.Server { @@ -17,14 +18,40 @@ namespace Microsoft.AspNetCore.Blazor.DevHost.Server services.AddRouting(); } - public void Configure(IApplicationBuilder app) + public void Configure(IApplicationBuilder app, IConfiguration configuration) { app.UseDeveloperExceptionPage(); + EnableConfiguredPathbase(app, configuration); var clientAssemblyPath = FindClientAssemblyPath(app); app.UseBlazor(new BlazorOptions { ClientAssemblyPath = clientAssemblyPath }); } + private static void EnableConfiguredPathbase(IApplicationBuilder app, IConfiguration configuration) + { + var pathBase = configuration.GetValue("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) { var env = app.ApplicationServices.GetRequiredService(); diff --git a/test/Microsoft.AspNetCore.Blazor.E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs b/test/Microsoft.AspNetCore.Blazor.E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs index eb5024c186..26904f2ad9 100644 --- a/test/Microsoft.AspNetCore.Blazor.E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs +++ b/test/Microsoft.AspNetCore.Blazor.E2ETest/Infrastructure/ServerFixtures/DevHostServerFixture.cs @@ -1,7 +1,6 @@ // 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 System.IO; using Microsoft.AspNetCore.Hosting; using DevHostServerProgram = Microsoft.AspNetCore.Blazor.DevHost.Server.Program; @@ -9,6 +8,8 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure.ServerFixtures { public class DevHostServerFixture : WebHostServerFixture { + public string PathBase { get; set; } + protected override IWebHost CreateWebHost() { var sampleSitePath = FindSampleOrTestSitePath( @@ -17,7 +18,8 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure.ServerFixtures return DevHostServerProgram.BuildWebHost(new string[] { "--urls", "http://127.0.0.1:0", - "--contentroot", sampleSitePath + "--contentroot", sampleSitePath, + "--pathbase", PathBase }); } } diff --git a/test/Microsoft.AspNetCore.Blazor.E2ETest/Tests/ComponentRenderingTest.cs b/test/Microsoft.AspNetCore.Blazor.E2ETest/Tests/ComponentRenderingTest.cs index 307255c5ca..3883ccf899 100644 --- a/test/Microsoft.AspNetCore.Blazor.E2ETest/Tests/ComponentRenderingTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.E2ETest/Tests/ComponentRenderingTest.cs @@ -23,7 +23,8 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests public ComponentRenderingTest(BrowserFixture browserFixture, DevHostServerFixture serverFixture) : base(browserFixture, serverFixture) { - Navigate("/", noReload: true); + serverFixture.PathBase = "/subdir"; + Navigate("/subdir", noReload: true); } [Fact] diff --git a/test/testapps/BasicTestApp/BasicTestApp.csproj b/test/testapps/BasicTestApp/BasicTestApp.csproj index b41f246ec0..040158b78a 100644 --- a/test/testapps/BasicTestApp/BasicTestApp.csproj +++ b/test/testapps/BasicTestApp/BasicTestApp.csproj @@ -5,7 +5,7 @@ dotnet - run --project ..\..\..\src\Microsoft.AspNetCore.Blazor.DevHost serve + run --project ..\..\..\src\Microsoft.AspNetCore.Blazor.DevHost serve --pathbase /subdir diff --git a/test/testapps/BasicTestApp/wwwroot/index.html b/test/testapps/BasicTestApp/wwwroot/index.html index b5d5ef0fab..97a440d873 100644 --- a/test/testapps/BasicTestApp/wwwroot/index.html +++ b/test/testapps/BasicTestApp/wwwroot/index.html @@ -3,6 +3,7 @@ Basic test app + Loading...