debugging: _args.CommonConfig.Debugging);
runArgsJson.Save(Path.Combine(_args.CommonConfig.AppPath, "runArgs.json"));
+ var urls = new string[] { $"http://localhost:{_args.CommonConfig.HostProperties.WebServerPort}", "https://localhost:0" };
+ if (envVars["ASPNETCORE_URLS"] is not null)
+ urls = envVars["ASPNETCORE_URLS"].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+
(ServerURLs serverURLs, IWebHost host) = await StartWebServerAsync(_args.CommonConfig.AppPath,
_args.ForwardConsoleOutput ?? false,
- _args.CommonConfig.HostProperties.WebServerPort,
+ urls,
token);
string[] fullUrls = BuildUrls(serverURLs, _args.AppArgs);
await host.WaitForShutdownAsync(token);
}
- private async Task<(ServerURLs, IWebHost)> StartWebServerAsync(string appPath, bool forwardConsole, int port, CancellationToken token)
+ private async Task<(ServerURLs, IWebHost)> StartWebServerAsync(string appPath, bool forwardConsole, string[] urls, CancellationToken token)
{
WasmTestMessagesProcessor? logProcessor = null;
if (forwardConsole)
ContentRootPath: Path.GetFullPath(appPath),
WebServerUseCors: true,
WebServerUseCrossOriginPolicy: true,
- Port: port
+ Urls: urls
);
(ServerURLs serverURLs, IWebHost host) = await WebServer.StartAsync(options, _logger, token);
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Net;
using System.Net.WebSockets;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using System.Web;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
+using Microsoft.WebAssembly.Diagnostics;
#nullable enable
internal sealed class WebServerStartup
{
private readonly IWebHostEnvironment _hostingEnvironment;
-
+ private static readonly object LaunchLock = new object();
+ private static string LaunchedDebugProxyUrl = "";
public WebServerStartup(IWebHostEnvironment hostingEnvironment) => _hostingEnvironment = hostingEnvironment;
+ public static int StartDebugProxy(string devToolsHost)
+ {
+ //we need to start another process, otherwise it will be running the BrowserDebugProxy in the same process that will be debugged, so pausing in a breakpoint
+ //on managed code will freeze because it will not be able to continue executing the BrowserDebugProxy to get the locals value
+ var executablePath = Path.Combine(System.AppContext.BaseDirectory, "BrowserDebugHost.dll");
+ var ownerPid = Environment.ProcessId;
+ var generateRandomPort = new Random().Next(5000, 5300);
+ var processStartInfo = new ProcessStartInfo
+ {
+ FileName = "dotnet" + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : ""),
+ Arguments = $"exec \"{executablePath}\" --OwnerPid {ownerPid} --DevToolsUrl {devToolsHost} --DevToolsProxyPort {generateRandomPort}",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ };
+ var debugProxyProcess = Process.Start(processStartInfo);
+ if (debugProxyProcess is null)
+ {
+ throw new InvalidOperationException("Unable to start debug proxy process.");
+ }
+ return generateRandomPort;
+ }
+
public void Configure(IApplicationBuilder app, IOptions<WebServerOptions> optionsContainer)
{
var provider = new FileExtensionContentTypeProvider();
});
}
- // app.UseEndpoints(endpoints =>
- // {
- // endpoints.MapFallbackToFile(options.DefaultFileName);
- // });
+ app.Map("/debug", app =>
+ {
+ app.Run(async (context) =>
+ {
+ //debug from VS
+ var queryParams = HttpUtility.ParseQueryString(context.Request.QueryString.Value!);
+ var browserParam = queryParams.Get("browser");
+ Uri? browserUrl = null;
+ var devToolsHost = "http://localhost:9222";
+ if (browserParam != null)
+ {
+ browserUrl = new Uri(browserParam);
+ devToolsHost = $"http://{browserUrl.Host}:{browserUrl.Port}";
+ }
+ lock (LaunchLock)
+ {
+ if (LaunchedDebugProxyUrl == "")
+ {
+ LaunchedDebugProxyUrl = $"http://localhost:{StartDebugProxy(devToolsHost)}";
+ }
+ }
+ var requestPath = context.Request.Path.ToString();
+ if (requestPath == string.Empty)
+ {
+ requestPath = "/";
+ }
+ context.Response.Redirect($"{LaunchedDebugProxyUrl}{browserUrl!.PathAndQuery}");
+ await Task.FromResult(0);
+ });
+ });
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapGet("/", context =>
+ {
+ context.Response.Redirect("index.html", permanent: false);
+ return Task.CompletedTask;
+ });
+ });
}
}