Skip to content

Commit

Permalink
[Wasm] Moves wasm reload logic out of ASP.NET Core and into the SDK (#…
Browse files Browse the repository at this point in the history
…42549)

Moves the logic for setting environment variables from ASP.NET Core to the BrowserRefresh middleware in the SDK for webassembly support.
  • Loading branch information
javiercn authored Aug 7, 2024
1 parent 39c3fc2 commit e001cc1
Show file tree
Hide file tree
Showing 2 changed files with 479 additions and 2 deletions.
95 changes: 93 additions & 2 deletions src/BuiltInTools/BrowserRefresh/BrowserRefreshMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,27 @@ namespace Microsoft.AspNetCore.Watch.BrowserRefresh
public class BrowserRefreshMiddleware
{
private static readonly MediaTypeHeaderValue _textHtmlMediaType = new("text/html");
private static readonly MediaTypeHeaderValue _applicationJsonMediaType = new("application/json");
private readonly string? _dotnetModifiableAssemblies = GetNonEmptyEnvironmentVariableValue("DOTNET_MODIFIABLE_ASSEMBLIES");
private readonly string? _aspnetcoreBrowserTools = GetNonEmptyEnvironmentVariableValue("__ASPNETCORE_BROWSER_TOOLS");

private readonly RequestDelegate _next;
private readonly ILogger _logger;

private static string? GetNonEmptyEnvironmentVariableValue(string name)
=> Environment.GetEnvironmentVariable(name) is { Length: > 0 } value ? value : null;

public BrowserRefreshMiddleware(RequestDelegate next, ILogger<BrowserRefreshMiddleware> logger) =>
(_next, _logger) = (next, logger);

public async Task InvokeAsync(HttpContext context)
{
// We only need to support this for requests that could be initiated by a browser.
if (IsBrowserDocumentRequest(context))
if (IsWebAssemblyBootRequest(context))
{
AttachWebAssemblyHeaders(context);
await _next(context);
}
else if (IsBrowserDocumentRequest(context))
{
// Use a custom StreamWrapper to rewrite output on Write/WriteAsync
using var responseStreamWrapper = new ResponseStreamWrapper(context, _logger);
Expand Down Expand Up @@ -59,6 +70,86 @@ public async Task InvokeAsync(HttpContext context)
}
}

private void AttachWebAssemblyHeaders(HttpContext context)
{
context.Response.OnStarting(() =>
{
if (!context.Response.Headers.ContainsKey("DOTNET-MODIFIABLE-ASSEMBLIES"))
{
if(_dotnetModifiableAssemblies != null)
{
context.Response.Headers.Add("DOTNET-MODIFIABLE-ASSEMBLIES", _dotnetModifiableAssemblies);
}
else
{
_logger.LogDebug("DOTNET_MODIFIABLE_ASSEMBLIES environment variable is not set, likely because hot reload is not enabled. The browser refresh feature may not work as expected.");
}
}
else
{
_logger.LogDebug("DOTNET-MODIFIABLE-ASSEMBLIES header is already set.");
}

if (!context.Response.Headers.ContainsKey("ASPNETCORE-BROWSER-TOOLS"))
{
if (_aspnetcoreBrowserTools != null)
{
context.Response.Headers.Add("ASPNETCORE-BROWSER-TOOLS", _aspnetcoreBrowserTools);
}
else
{
_logger.LogDebug("__ASPNETCORE_BROWSER_TOOLS environment variable is not set. The browser refresh feature may not work as expected.");
}
}
else
{
_logger.LogDebug("ASPNETCORE-BROWSER-TOOLS header is already set.");
}

return Task.CompletedTask;
});
}

internal static bool IsWebAssemblyBootRequest(HttpContext context)
{
var request = context.Request;
if (!HttpMethods.IsGet(request.Method))
{
return false;
}

if (request.Headers.TryGetValue("Sec-Fetch-Dest", out var values) &&
!StringValues.IsNullOrEmpty(values) &&
!string.Equals(values[0], "document", StringComparison.OrdinalIgnoreCase))
{
// See https://github.com/dotnet/aspnetcore/issues/37326.
// Only inject scripts that are destined for a browser page.
return false;
}

if (!request.Path.HasValue ||
!string.Equals(Path.GetFileName(request.Path.Value), "blazor.boot.json", StringComparison.OrdinalIgnoreCase))
{
return false;
}

var typedHeaders = request.GetTypedHeaders();
if (typedHeaders.Accept is not IList<MediaTypeHeaderValue> acceptHeaders)
{
return false;
}

for (var i = 0; i < acceptHeaders.Count; i++)
{
if (acceptHeaders[i].IsSubsetOf(_applicationJsonMediaType))
{
return true;
}
}

return false;
}

internal static bool IsBrowserDocumentRequest(HttpContext context)
{
var request = context.Request;
Expand Down
Loading

0 comments on commit e001cc1

Please sign in to comment.